diff --git a/p2p/host/routed/routed.go b/p2p/host/routed/routed.go index 99926f2b240144ba30a8819cfe938e38cd92d74c..6522c3e88c479b773c76322fb896a6ef3bd240c9 100644 --- a/p2p/host/routed/routed.go +++ b/p2p/host/routed/routed.go @@ -8,6 +8,7 @@ import ( host "github.com/libp2p/go-libp2p-host" logging "github.com/ipfs/go-log" + circuit "github.com/libp2p/go-libp2p-circuit" ifconnmgr "github.com/libp2p/go-libp2p-interface-connmgr" lgbl "github.com/libp2p/go-libp2p-loggables" inet "github.com/libp2p/go-libp2p-net" @@ -67,6 +68,42 @@ func (rh *RoutedHost) Connect(ctx context.Context, pi pstore.PeerInfo) error { } } + // Issue 448: if our address set includes specific relay addrs, we need + // to make sure the relay's addr itself is in the peerstore or else + // we wont be able to dial it. + for _, addr := range addrs { + _, err := addr.ValueForProtocol(circuit.P_CIRCUIT) + if err != nil { + // not a relay address + continue + } + + relay, err := addr.ValueForProtocol(ma.P_P2P) + if err != nil { + // not a specific relay address + continue + } + + relayID, err := peer.IDFromString(relay) + if err != nil { + log.Debugf("failed to parse relay ID in address %s: %s", relay, err) + continue + } + + if len(rh.Peerstore().Addrs(relayID)) > 0 { + // we already have addrs for this relay + continue + } + + relayAddrs, err := rh.findPeerAddrs(ctx, relayID) + if err != nil { + log.Debugf("failed to find relay %s: %s", relay, err) + continue + } + + rh.Peerstore().AddAddrs(relayID, relayAddrs, pstore.AddressTTL) + } + // if we're here, we got some addrs. let's use our wrapped host to connect. pi.Addrs = addrs return rh.host.Connect(ctx, pi)