@cryptotaxi247 / kubo / commits / dd48b8237

p2p: separate listener types

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Sep 5, 2018 at 23:06 UTC dd48b8237a402c765e8afb7360336ef194b06893
6 files changed +162 -40
core/commands/p2p.go
+26 -8
@@ -230,15 +230,25 @@ var p2pLsCmd = &cmds.Command{
230
231 output := &P2PLsOutput{}
232
233 - n.P2P.Listeners.Lock()
234 - for _, listener := range n.P2P.Listeners.Listeners {
233 + n.P2P.ListenersLocal.Lock()
234 + for _, listener := range n.P2P.ListenersLocal.Listeners {
235 output.Listeners = append(output.Listeners, P2PListenerInfoOutput{
236 Protocol: string(listener.Protocol()),
237 ListenAddress: listener.ListenAddress().String(),
238 TargetAddress: listener.TargetAddress().String(),
239 })
240 }
241 - n.P2P.Listeners.Unlock()
241 + n.P2P.ListenersLocal.Unlock()
242 +
243 + n.P2P.ListenersP2P.Lock()
244 + for _, listener := range n.P2P.ListenersP2P.Listeners {
245 + output.Listeners = append(output.Listeners, P2PListenerInfoOutput{
246 + Protocol: string(listener.Protocol()),
247 + ListenAddress: listener.ListenAddress().String(),
248 + TargetAddress: listener.TargetAddress().String(),
249 + })
250 + }
251 + n.P2P.ListenersP2P.Unlock()
252
253 res.SetOutput(output)
254 },
@@ -314,7 +324,7 @@ var p2pCloseCmd = &cmds.Command{
324 return
325 }
326
317 - match := func(listener p2p.Listener) bool {
327 + match := func(listener p2p.ListenerLocal) bool {
328 if closeAll {
329 return true
330 }
@@ -330,15 +340,23 @@ var p2pCloseCmd = &cmds.Command{
340 return true
341 }
342
333 - todo := make([]p2p.Listener, 0)
334 - n.P2P.Listeners.Lock()
335 - for _, l := range n.P2P.Listeners.Listeners {
343 + todo := make([]p2p.ListenerLocal, 0)
344 + n.P2P.ListenersLocal.Lock()
345 + for _, l := range n.P2P.ListenersLocal.Listeners {
346 + if !match(l) {
347 + continue
348 + }
349 + todo = append(todo, l)
350 + }
351 + n.P2P.ListenersLocal.Unlock()
352 + n.P2P.ListenersP2P.Lock()
353 + for _, l := range n.P2P.ListenersP2P.Listeners {
354 if !match(l) {
355 continue
356 }
357 todo = append(todo, l)
358 }
341 - n.P2P.Listeners.Unlock()
359 + n.P2P.ListenersP2P.Unlock()
360
361 var errs []string
362 for _, l := range todo {
p2p/local.go
+3 -3
@@ -27,7 +27,7 @@ type localListener struct {
27 }
28
29 // ForwardLocal creates new P2P stream to a remote listener
30 -func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.ID, bindAddr ma.Multiaddr) (Listener, error) {
30 +func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.ID, bindAddr ma.Multiaddr) (ListenerLocal, error) {
31 listener := &localListener{
32 ctx: ctx,
33
@@ -39,7 +39,7 @@ func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.I
39 peer: peer,
40 }
41
42 - if err := p2p.Listeners.Register(listener); err != nil {
42 + if err := p2p.ListenersLocal.Register(listener); err != nil {
43 return nil, err
44 }
45
@@ -111,7 +111,7 @@ func (l *localListener) start() error {
111 }
112
113 func (l *localListener) Close() error {
114 - ok, err := l.p2p.Listeners.Deregister(getListenerKey(l))
114 + ok, err := l.p2p.ListenersLocal.Deregister(l.laddr.String())
115 if err != nil {
116 return err
117 }
p2p/local_listener.go new
+113
@@ -0,0 +1,113 @@
1 +package p2p
2 +
3 +import (
4 + "errors"
5 + "sync"
6 +
7 + net "gx/ipfs/QmQSbtGXCyNrj34LWL8EgXyNNYDZ8r3SwQcpW5pPxVhLnM/go-libp2p-net"
8 + peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer"
9 + ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr"
10 + "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"
11 + p2phost "gx/ipfs/QmfH9FKYv3Jp1xiyL8sPchGBUBg6JA6XviwajAo3qgnT3B/go-libp2p-host"
12 +)
13 +
14 +// ListenerLocal listens for connections and proxies them to a target
15 +type ListenerLocal interface {
16 + Protocol() protocol.ID
17 + ListenAddress() ma.Multiaddr
18 + TargetAddress() ma.Multiaddr
19 +
20 + start() error
21 +
22 + // Close closes the listener. Does not affect child streams
23 + Close() error
24 +}
25 +
26 +// ListenersLocal is a collection of local application proto listeners.
27 +type ListenersLocal struct {
28 + sync.RWMutex
29 +
30 + Listeners map[string]ListenerLocal
31 + starting map[string]struct{}
32 +}
33 +
34 +func newListenerRegistry(id peer.ID, host p2phost.Host) *ListenersLocal {
35 + reg := &ListenersLocal{
36 + Listeners: map[string]ListenerLocal{},
37 + starting: map[string]struct{}{},
38 + }
39 +
40 + addr, err := ma.NewMultiaddr(maPrefix + id.Pretty())
41 + if err != nil {
42 + panic(err)
43 + }
44 +
45 + host.SetStreamHandlerMatch("/x/", func(p string) bool {
46 + reg.RLock()
47 + defer reg.RUnlock()
48 +
49 + for _, l := range reg.Listeners {
50 + if l.ListenAddress().Equal(addr) && string(l.Protocol()) == p {
51 + return true
52 + }
53 + }
54 +
55 + return false
56 + }, func(stream net.Stream) {
57 + reg.RLock()
58 + defer reg.RUnlock()
59 +
60 + for _, l := range reg.Listeners {
61 + if l.ListenAddress().Equal(addr) && l.Protocol() == stream.Protocol() {
62 + go l.(*remoteListener).handleStream(stream)
63 + return
64 + }
65 + }
66 + })
67 +
68 + return reg
69 +}
70 +
71 +// Register registers listenerInfo into this registry and starts it
72 +func (r *ListenersLocal) Register(l ListenerLocal) error {
73 + r.Lock()
74 + k := l.ListenAddress().String()
75 +
76 + if _, ok := r.Listeners[k]; ok {
77 + r.Unlock()
78 + return errors.New("listener already registered")
79 + }
80 +
81 + r.Listeners[k] = l
82 + r.starting[k] = struct{}{}
83 +
84 + r.Unlock()
85 +
86 + err := l.start()
87 +
88 + r.Lock()
89 + defer r.Unlock()
90 +
91 + delete(r.starting, k)
92 +
93 + if err != nil {
94 + delete(r.Listeners, k)
95 + return err
96 + }
97 +
98 + return nil
99 +}
100 +
101 +// Deregister removes p2p listener from this registry
102 +func (r *ListenersLocal) Deregister(k string) (bool, error) {
103 + r.Lock()
104 + defer r.Unlock()
105 +
106 + if _, ok := r.starting[k]; ok {
107 + return false, errors.New("listener didn't start yet")
108 + }
109 +
110 + _, ok := r.Listeners[k]
111 + delete(r.Listeners, k)
112 + return ok, nil
113 +}
p2p/p2p.go
+6 -3
@@ -11,8 +11,9 @@ var log = logging.Logger("p2p-mount")
11
12 // P2P structure holds information on currently running streams/listeners
13 type P2P struct {
14 - Listeners *ListenerRegistry
15 - Streams *StreamRegistry
14 + ListenersLocal *ListenersLocal
15 + ListenersP2P *ListenersP2P
16 + Streams *StreamRegistry
17
18 identity peer.ID
19 peerHost p2phost.Host
@@ -26,7 +27,9 @@ func NewP2P(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore)
27 peerHost: peerHost,
28 peerstore: peerstore,
29
29 - Listeners: newListenerRegistry(identity, peerHost),
30 + ListenersLocal: newListenerRegistry(identity, peerHost),
31 + ListenersP2P: newListenerP2PRegistry(identity, peerHost),
32 +
33 Streams: &StreamRegistry{
34 Streams: map[uint64]*Stream{},
35 },
p2p/p2p_listener.go renamed
+11 -23
@@ -12,7 +12,7 @@ import (
12 )
13
14 // Listener listens for connections and proxies them to a target
15 -type Listener interface {
15 +type P2PListener interface {
16 Protocol() protocol.ID
17 ListenAddress() ma.Multiaddr
18 TargetAddress() ma.Multiaddr
@@ -23,23 +23,18 @@ type Listener interface {
23 Close() error
24 }
25
26 -type listenerKey struct {
27 - proto string
28 - listen string
29 -}
30 -
26 // ListenerRegistry is a collection of local application proto listeners.
32 -type ListenerRegistry struct {
27 +type ListenersP2P struct {
28 sync.RWMutex
29
35 - Listeners map[listenerKey]Listener
36 - starting map[listenerKey]struct{}
30 + Listeners map[protocol.ID]ListenerLocal
31 + starting map[protocol.ID]struct{}
32 }
33
39 -func newListenerRegistry(id peer.ID, host p2phost.Host) *ListenerRegistry {
40 - reg := &ListenerRegistry{
41 - Listeners: map[listenerKey]Listener{},
42 - starting: map[listenerKey]struct{}{},
34 +func newListenerP2PRegistry(id peer.ID, host p2phost.Host) *ListenersP2P {
35 + reg := &ListenersP2P{
36 + Listeners: map[protocol.ID]ListenerLocal{},
37 + starting: map[protocol.ID]struct{}{},
38 }
39
40 addr, err := ma.NewMultiaddr(maPrefix + id.Pretty())
@@ -74,10 +69,10 @@ func newListenerRegistry(id peer.ID, host p2phost.Host) *ListenerRegistry {
69 }
70
71 // Register registers listenerInfo into this registry and starts it
77 -func (r *ListenerRegistry) Register(l Listener) error {
72 +func (r *ListenersP2P) Register(l ListenerLocal) error {
73 r.Lock()
79 - k := getListenerKey(l)
74
75 + k := l.Protocol()
76 if _, ok := r.Listeners[k]; ok {
77 r.Unlock()
78 return errors.New("listener already registered")
@@ -104,7 +99,7 @@ func (r *ListenerRegistry) Register(l Listener) error {
99 }
100
101 // Deregister removes p2p listener from this registry
107 -func (r *ListenerRegistry) Deregister(k listenerKey) (bool, error) {
102 +func (r *ListenersP2P) Deregister(k protocol.ID) (bool, error) {
103 r.Lock()
104 defer r.Unlock()
105
@@ -116,10 +111,3 @@ func (r *ListenerRegistry) Deregister(k listenerKey) (bool, error) {
111 delete(r.Listeners, k)
112 return ok, nil
113 }
119 -
120 -func getListenerKey(l Listener) listenerKey {
121 - return listenerKey{
122 - proto: string(l.Protocol()),
123 - listen: l.ListenAddress().String(),
124 - }
125 -}
p2p/remote.go
+3 -3
@@ -23,7 +23,7 @@ type remoteListener struct {
23 }
24
25 // ForwardRemote creates new p2p listener
26 -func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Multiaddr) (Listener, error) {
26 +func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Multiaddr) (P2PListener, error) {
27 listener := &remoteListener{
28 p2p: p2p,
29
@@ -31,7 +31,7 @@ func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Mu
31 addr: addr,
32 }
33
34 - if err := p2p.Listeners.Register(listener); err != nil {
34 + if err := p2p.ListenersP2P.Register(listener); err != nil {
35 return nil, err
36 }
37
@@ -97,7 +97,7 @@ func (l *remoteListener) TargetAddress() ma.Multiaddr {
97 }
98
99 func (l *remoteListener) Close() error {
100 - ok, err := l.p2p.Listeners.Deregister(getListenerKey(l))
100 + ok, err := l.p2p.ListenersP2P.Deregister(l.proto)
101 if err != nil {
102 return err
103 }