7
7
"time"
8
8
9
9
"github.com/libp2p/go-libp2p/core/peer"
10
- pstore "github.com/libp2p/go-libp2p/p2p/host /peerstore"
10
+ "github.com/libp2p/go-libp2p/core /peerstore"
11
11
12
12
ds "github.com/ipfs/go-datastore"
13
13
"github.com/libp2p/go-libp2p-kad-dht/internal"
@@ -66,12 +66,11 @@ func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Mess
66
66
resp .Record = rec
67
67
68
68
// Find closest peer on given cluster to desired key and reply with that info
69
- closer := dht .betterPeersToQuery (pmes , p , dht .bucketSize )
70
- if len (closer ) > 0 {
71
- // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos).
72
- closerinfos := pstore .PeerInfos (dht .peerstore , closer )
73
- for _ , pi := range closerinfos {
74
- logger .Debugf ("handleGetValue returning closer peer: '%s'" , pi .ID )
69
+ closestPeers := dht .closestPeersToQuery (pmes , p , dht .bucketSize )
70
+ if len (closestPeers ) > 0 {
71
+ closestInfos := peerstore .AddrInfos (dht .peerstore , closestPeers )
72
+ for _ , pi := range closestInfos {
73
+ logger .Debugf ("handleGetValue returning closest peer: '%s'" , pi .ID )
75
74
if len (pi .Addrs ) < 1 {
76
75
logger .Warnw ("no addresses on peer being sent" ,
77
76
"local" , dht .self ,
@@ -81,7 +80,7 @@ func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Mess
81
80
}
82
81
}
83
82
84
- resp .CloserPeers = pb .PeerInfosToPBPeers (dht .host .Network (), closerinfos )
83
+ resp .CloserPeers = pb .PeerInfosToPBPeers (dht .host .Network (), closestInfos )
85
84
}
86
85
87
86
return resp , nil
@@ -252,42 +251,26 @@ func (dht *IpfsDHT) handlePing(_ context.Context, p peer.ID, pmes *pb.Message) (
252
251
253
252
func (dht * IpfsDHT ) handleFindPeer (ctx context.Context , from peer.ID , pmes * pb.Message ) (_ * pb.Message , _err error ) {
254
253
resp := pb .NewMessage (pmes .GetType (), nil , pmes .GetClusterLevel ())
255
- var closest []peer.ID
256
254
257
255
if len (pmes .GetKey ()) == 0 {
258
256
return nil , errors .New ("handleFindPeer with empty key" )
259
257
}
260
258
261
- // if looking for self... special case where we send it on CloserPeers.
262
259
targetPid := peer .ID (pmes .GetKey ())
263
- closest = dht .betterPeersToQuery (pmes , from , dht .bucketSize )
264
-
265
- // Never tell a peer about itself.
266
- if targetPid != from {
267
- // Add the target peer to the set of closest peers if
268
- // not already present in our routing table.
269
- //
270
- // Later, when we lookup known addresses for all peers
271
- // in this set, we'll prune this peer if we don't
272
- // _actually_ know where it is.
273
- found := false
274
- for _ , p := range closest {
275
- if targetPid == p {
276
- found = true
277
- break
278
- }
279
- }
280
- if ! found {
281
- closest = append (closest , targetPid )
282
- }
283
- }
260
+ closest := dht .closestPeersToQuery (pmes , from , dht .bucketSize )
284
261
285
- if closest == nil {
286
- return resp , nil
262
+ // Prepend targetPid to the front of the list if not already present.
263
+ // targetPid is always the closest key to itself.
264
+ //
265
+ // Per IPFS Kademlia DHT spec: FIND_PEER has a special exception where the
266
+ // target peer MUST be included in the response (if present in peerstore),
267
+ // even if it is self, the requester, or not a DHT server. This allows peers
268
+ // to discover multiaddresses for any peer, not just DHT servers.
269
+ if len (closest ) == 0 || closest [0 ] != targetPid {
270
+ closest = append ([]peer.ID {targetPid }, closest ... )
287
271
}
288
272
289
- // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos).
290
- closestinfos := pstore .PeerInfos (dht .peerstore , closest )
273
+ closestinfos := peerstore .AddrInfos (dht .peerstore , closest )
291
274
// possibly an over-allocation but this array is temporary anyways.
292
275
withAddresses := make ([]peer.AddrInfo , 0 , len (closestinfos ))
293
276
for _ , pi := range closestinfos {
@@ -326,11 +309,10 @@ func (dht *IpfsDHT) handleGetProviders(ctx context.Context, p peer.ID, pmes *pb.
326
309
327
310
resp .ProviderPeers = pb .PeerInfosToPBPeers (dht .host .Network (), filtered )
328
311
329
- // Also send closer peers.
330
- closer := dht .betterPeersToQuery (pmes , p , dht .bucketSize )
331
- if closer != nil {
332
- // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos).
333
- infos := pstore .PeerInfos (dht .peerstore , closer )
312
+ // Also send closest dht servers we know about.
313
+ closestPeers := dht .closestPeersToQuery (pmes , p , dht .bucketSize )
314
+ if closestPeers != nil {
315
+ infos := peerstore .AddrInfos (dht .peerstore , closestPeers )
334
316
resp .CloserPeers = pb .PeerInfosToPBPeers (dht .host .Network (), infos )
335
317
}
336
318
0 commit comments