remote.go 2.05 KB
Newer Older
1 2 3 4
package p2p

import (
	"context"
5
	"fmt"
6

tavit ohanian's avatar
tavit ohanian committed
7 8 9 10
	ma "gitlab.dms3.io/mf/go-multiaddr"
	manet "gitlab.dms3.io/mf/go-multiaddr/net"
	net "gitlab.dms3.io/p2p/go-p2p-core/network"
	protocol "gitlab.dms3.io/p2p/go-p2p-core/protocol"
11 12
)

tavit ohanian's avatar
tavit ohanian committed
13
var maPrefix = "/" + ma.ProtocolWithCode(ma.P_DMS3).Name + "/"
Łukasz Magiera's avatar
Łukasz Magiera committed
14

tavit ohanian's avatar
tavit ohanian committed
15
// remoteListener accepts p2p streams and proxies them to a manet host
Łukasz Magiera's avatar
Łukasz Magiera committed
16
type remoteListener struct {
17 18 19
	p2p *P2P

	// Application proto identifier.
Łukasz Magiera's avatar
Łukasz Magiera committed
20
	proto protocol.ID
21

22
	// Address to proxy the incoming connections to
23
	addr ma.Multiaddr
24 25 26 27

	// reportRemote if set to true makes the handler send '<base58 remote peerid>\n'
	// to target before any data is forwarded
	reportRemote bool
28 29
}

Łukasz Magiera's avatar
Łukasz Magiera committed
30
// ForwardRemote creates new p2p listener
31
func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Multiaddr, reportRemote bool) (Listener, error) {
32
	listener := &remoteListener{
33 34
		p2p: p2p,

Łukasz Magiera's avatar
Łukasz Magiera committed
35
		proto: proto,
36
		addr:  addr,
37 38

		reportRemote: reportRemote,
39 40
	}

Łukasz Magiera's avatar
Łukasz Magiera committed
41
	if err := p2p.ListenersP2P.Register(listener); err != nil {
42 43
		return nil, err
	}
Łukasz Magiera's avatar
Łukasz Magiera committed
44

Łukasz Magiera's avatar
Łukasz Magiera committed
45 46 47
	return listener, nil
}

48 49 50
func (l *remoteListener) handleStream(remote net.Stream) {
	local, err := manet.Dial(l.addr)
	if err != nil {
51
		_ = remote.Reset()
52 53
		return
	}
54

55
	peer := remote.Conn().RemotePeer()
56

57 58
	if l.reportRemote {
		if _, err := fmt.Fprintf(local, "%s\n", peer.Pretty()); err != nil {
59
			_ = remote.Reset()
60 61 62 63
			return
		}
	}

64 65
	peerMa, err := ma.NewMultiaddr(maPrefix + peer.Pretty())
	if err != nil {
66
		_ = remote.Reset()
67 68
		return
	}
69

70 71
	stream := &Stream{
		Protocol: l.proto,
72

73 74
		OriginAddr: peerMa,
		TargetAddr: l.addr,
Łukasz Magiera's avatar
Łukasz Magiera committed
75
		peer:       peer,
76

77 78
		Local:  local,
		Remote: remote,
79

80 81
		Registry: l.p2p.Streams,
	}
82

83
	l.p2p.Streams.Register(stream)
84 85
}

Łukasz Magiera's avatar
Łukasz Magiera committed
86 87
func (l *remoteListener) Protocol() protocol.ID {
	return l.proto
88 89
}

Łukasz Magiera's avatar
Łukasz Magiera committed
90 91 92 93 94 95
func (l *remoteListener) ListenAddress() ma.Multiaddr {
	addr, err := ma.NewMultiaddr(maPrefix + l.p2p.identity.Pretty())
	if err != nil {
		panic(err)
	}
	return addr
Łukasz Magiera's avatar
Łukasz Magiera committed
96 97
}

Łukasz Magiera's avatar
Łukasz Magiera committed
98 99
func (l *remoteListener) TargetAddress() ma.Multiaddr {
	return l.addr
100 101
}

Łukasz Magiera's avatar
Łukasz Magiera committed
102
func (l *remoteListener) close() {}
103 104 105 106

func (l *remoteListener) key() string {
	return string(l.proto)
}