diff --git a/p2p/net/swarm/swarm_dial.go b/p2p/net/swarm/swarm_dial.go index aa6e077f4b..fe38d01305 100644 --- a/p2p/net/swarm/swarm_dial.go +++ b/p2p/net/swarm/swarm_dial.go @@ -475,6 +475,14 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) (goodAdd } return ma.FilterAddrs(addrs, + // Linux and BSD treat an unspecified address when dialing as a localhost address. + // Windows doesn't support this. We filter all such addresses out because peers + // listening on unspecified addresses will advertise more specific addresses. + // https://unix.stackexchange.com/a/419881 + // https://superuser.com/a/1755455 + func(addr ma.Multiaddr) bool { + return !manet.IsIPUnspecified(addr) + }, func(addr ma.Multiaddr) bool { if ma.Contains(ourAddrs, addr) { addrErrs = append(addrErrs, TransportError{Address: addr, Cause: ErrDialToSelf}) diff --git a/p2p/net/swarm/swarm_dial_test.go b/p2p/net/swarm/swarm_dial_test.go index 47310978fe..13f56fb930 100644 --- a/p2p/net/swarm/swarm_dial_test.go +++ b/p2p/net/swarm/swarm_dial_test.go @@ -277,6 +277,9 @@ func TestAddrsForDialFiltering(t *testing.T) { t1 := ma.StringCast("/ip4/1.2.3.4/tcp/1") ws1 := ma.StringCast("/ip4/1.2.3.4/tcp/1/ws") + unSpecQ := ma.StringCast("/ip4/0.0.0.0/udp/2/quic-v1") + unSpecT := ma.StringCast("/ip6/::/tcp/2/") + resolver, err := madns.NewResolver(madns.WithDefaultResolver(&madns.MockResolver{})) require.NoError(t, err) s := newTestSwarmWithResolver(t, resolver) @@ -307,6 +310,11 @@ func TestAddrsForDialFiltering(t *testing.T) { input: append([]ma.Multiaddr{q1}, ourAddrs...), output: []ma.Multiaddr{q1}, }, + { + name: "unspecified-filtered", + input: []ma.Multiaddr{q1v1, t1, unSpecQ, unSpecT}, + output: []ma.Multiaddr{q1v1, t1}, + }, } ctx := context.Background()