@cryptotaxi247 / kubo / commits / 00d7b498e

routing/dht: adjust routing table on peer conn/disc

Juan Batiz-Benet committed Jan 24, 2015 at 08:52 UTC 00d7b498efc2e3f4929354f3379c158b289b305f
4 files changed +69 -1
routing/dht/dht.go
+9 -1
@@ -65,9 +65,17 @@ func NewDHT(ctx context.Context, h host.Host, dstore ds.ThreadSafeDatastore) *Ip
65 dht.datastore = dstore
66 dht.self = h.ID()
67 dht.peerstore = h.Peerstore()
68 - dht.ContextGroup = ctxgroup.WithContext(ctx)
68 dht.host = h
69
70 + // register for network notifs.
71 + dht.host.Network().Notify((*netNotifiee)(dht))
72 +
73 + dht.ContextGroup = ctxgroup.WithContextAndTeardown(ctx, func() error {
74 + // remove ourselves from network notifs.
75 + dht.host.Network().StopNotify((*netNotifiee)(dht))
76 + return nil
77 + })
78 +
79 // sanity check. this should **never** happen
80 if len(dht.peerstore.Addresses(dht.self)) < 1 {
81 panic("attempt to initialize dht without addresses for self")
routing/dht/notif.go new
+33
@@ -0,0 +1,33 @@
1 +package dht
2 +
3 +import (
4 + inet "github.com/jbenet/go-ipfs/p2p/net"
5 +)
6 +
7 +// netNotifiee defines methods to be used with the IpfsDHT
8 +type netNotifiee IpfsDHT
9 +
10 +func (nn *netNotifiee) DHT() *IpfsDHT {
11 + return (*IpfsDHT)(nn)
12 +}
13 +
14 +func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
15 + dht := nn.DHT()
16 + select {
17 + case <-dht.Closing():
18 + return
19 + }
20 + dht.Update(dht.Context(), v.RemotePeer())
21 +}
22 +
23 +func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
24 + dht := nn.DHT()
25 + select {
26 + case <-dht.Closing():
27 + return
28 + }
29 + dht.routingTable.Remove(v.RemotePeer())
30 +}
31 +
32 +func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
33 +func (nn *netNotifiee) ClosedStream(n inet.Network, v inet.Stream) {}
routing/kbucket/bucket.go
+10
@@ -30,6 +30,16 @@ func (b *Bucket) find(id peer.ID) *list.Element {
30 return nil
31 }
32
33 +func (b *Bucket) remove(id peer.ID) {
34 + b.lk.RLock()
35 + defer b.lk.RUnlock()
36 + for e := b.list.Front(); e != nil; e = e.Next() {
37 + if e.Value.(peer.ID) == id {
38 + b.list.Remove(e)
39 + }
40 + }
41 +}
42 +
43 func (b *Bucket) moveToFront(e *list.Element) {
44 b.lk.Lock()
45 b.list.MoveToFront(e)
routing/kbucket/table.go
+17
@@ -87,6 +87,23 @@ func (rt *RoutingTable) Update(p peer.ID) peer.ID {
87 return ""
88 }
89
90 +// Remove deletes a peer from the routing table. This is to be used
91 +// when we are sure a node has disconnected completely.
92 +func (rt *RoutingTable) Remove(p peer.ID) {
93 + rt.tabLock.Lock()
94 + defer rt.tabLock.Unlock()
95 + peerID := ConvertPeerID(p)
96 + cpl := commonPrefixLen(peerID, rt.local)
97 +
98 + bucketID := cpl
99 + if bucketID >= len(rt.Buckets) {
100 + bucketID = len(rt.Buckets) - 1
101 + }
102 +
103 + bucket := rt.Buckets[bucketID]
104 + bucket.remove(p)
105 +}
106 +
107 func (rt *RoutingTable) nextBucket() peer.ID {
108 bucket := rt.Buckets[len(rt.Buckets)-1]
109 newBucket := bucket.Split(len(rt.Buckets)-1, rt.local)