diff --git a/dht_bootstrap.go b/dht_bootstrap.go index 2ff90b6..e7442ae 100644 --- a/dht_bootstrap.go +++ b/dht_bootstrap.go @@ -8,7 +8,6 @@ import ( multierror "github.com/hashicorp/go-multierror" process "github.com/jbenet/goprocess" processctx "github.com/jbenet/goprocess/context" - "github.com/libp2p/go-libp2p-core/routing" kbucket "github.com/libp2p/go-libp2p-kbucket" "github.com/multiformats/go-multiaddr" _ "github.com/multiformats/go-multiaddr-dns" @@ -58,8 +57,8 @@ func (dht *IpfsDHT) startSelfLookup() error { // Do a self walk queryCtx, cancel := context.WithTimeout(ctx, dht.rtRefreshQueryTimeout) - _, err := dht.FindPeer(queryCtx, dht.self) - if err == routing.ErrNotFound || err == kbucket.ErrLookupFailure { + _, err := dht.GetClosestPeers(queryCtx, string(dht.self)) + if err == kbucket.ErrLookupFailure { err = nil } else if err != nil { err = fmt.Errorf("failed to query self during routing table refresh: %s", err) @@ -207,10 +206,7 @@ func (dht *IpfsDHT) refreshCpls(ctx context.Context) error { // walk to the generated peer walkFnc := func(c context.Context) error { - _, err := dht.FindPeer(c, randPeer) - if err == routing.ErrNotFound { - return nil - } + _, err := dht.GetClosestPeers(c, string(randPeer)) return err } diff --git a/routing.go b/routing.go index 6695c96..eb2b4ed 100644 --- a/routing.go +++ b/routing.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-kad-dht/qpeerset" "sync" "time" @@ -688,22 +689,21 @@ func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (_ peer.AddrInfo, return peer.AddrInfo{}, err } - // refresh the cpl for this key if we discovered the peer because of the query - if ctx.Err() == nil { - discoveredPeerDuringQuery := false - for _, p := range lookupRes.peers { - if p == id { - discoveredPeerDuringQuery = true - break - } - } - if discoveredPeerDuringQuery || lookupRes.completed { - dht.routingTable.ResetCplRefreshedAtForID(kb.ConvertPeerID(id), time.Now()) + dialedPeerDuringQuery := false + for i, p := range lookupRes.peers { + if p == id { + // Note: we consider PeerUnreachable to be a valid state because the peer may not support the DHT protocol + // and therefore the peer would fail the query. The fact that a peer that is returned can be a non-DHT + // server peer and is not identified as such is a bug. + dialedPeerDuringQuery = lookupRes.state[i] != qpeerset.PeerHeard + break } } - // TODO: Consider unlucky disconnect timing and potentially utilizing network.CanConnect or something similar - if dht.host.Network().Connectedness(id) == network.Connected { + // Return peer information if we tried to dial the peer during the query or we are (or recently were) connected + // to the peer. + connectedness := dht.host.Network().Connectedness(id) + if dialedPeerDuringQuery || connectedness == network.Connected || connectedness == network.CanConnect { return dht.peerstore.PeerInfo(id), nil }