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

import (
	"context"
5
	"fmt"
6

Hector Sanjuan's avatar
Hector Sanjuan committed
7 8
	ma "gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr"
	net "gx/ipfs/QmY3ArotKMKaL7YGfbQfyDrib6RVraLqZYWXZvVgZktBxp/go-libp2p-net"
9
	protocol "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"
Hector Sanjuan's avatar
Hector Sanjuan committed
10
	manet "gx/ipfs/Qmc85NSvmSG4Frn9Vb2cBc1rMyULH6D3TNVEfCzSKoUpip/go-multiaddr-net"
11 12
)

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

Łukasz Magiera's avatar
Łukasz Magiera committed
15 16
// remoteListener accepts libp2p streams and proxies them to a manet host
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 51 52 53
func (l *remoteListener) handleStream(remote net.Stream) {
	local, err := manet.Dial(l.addr)
	if err != nil {
		remote.Reset()
		return
	}
54

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

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

64 65 66 67 68
	peerMa, err := ma.NewMultiaddr(maPrefix + peer.Pretty())
	if err != nil {
		remote.Reset()
		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)
}