diff --git a/p2p/protocol/identify/obsaddr.go b/p2p/protocol/identify/obsaddr.go index 3422a286ff..0412541f5d 100644 --- a/p2p/protocol/identify/obsaddr.go +++ b/p2p/protocol/identify/obsaddr.go @@ -375,6 +375,11 @@ func shouldRecordObservation(host addrsProvider, network listenAddrsProvider, co return false } + // Provided by NAT64 peers, these addresses are specific to the peer and not publicly routable + if manet.IsNAT64IPv4ConvertedIPv6Addr(observed) { + return false + } + // we should only use ObservedAddr when our connection's LocalAddr is one // of our ListenAddrs. If we Dial out using an ephemeral addr, knowing that // address's external mapping is not very useful because the port will not be diff --git a/p2p/protocol/identify/obsaddr_glass_test.go b/p2p/protocol/identify/obsaddr_glass_test.go index 497b08e0bd..f96d3a3576 100644 --- a/p2p/protocol/identify/obsaddr_glass_test.go +++ b/p2p/protocol/identify/obsaddr_glass_test.go @@ -4,6 +4,7 @@ package identify // can access internal types. import ( + "fmt" "testing" ma "github.com/multiformats/go-multiaddr" @@ -103,3 +104,50 @@ func TestShouldRecordObservationWithWebTransport(t *testing.T) { require.True(t, shouldRecordObservation(h, h, c, observedAddr)) } + +func TestShouldRecordObservationWithNAT64Addr(t *testing.T) { + listenAddr1 := ma.StringCast("/ip4/0.0.0.0/tcp/1234") + ifaceAddr1 := ma.StringCast("/ip4/10.0.0.2/tcp/4321") + listenAddr2 := ma.StringCast("/ip6/::/tcp/1234") + ifaceAddr2 := ma.StringCast("/ip6/1::1/tcp/4321") + + h := &mockHost{ + listenAddrs: []ma.Multiaddr{listenAddr1, listenAddr2}, + ifaceListenAddrs: []ma.Multiaddr{ifaceAddr1, ifaceAddr2}, + addrs: []ma.Multiaddr{listenAddr1, listenAddr2}, + } + c := &mockConn{ + local: listenAddr1, + remote: ma.StringCast("/ip4/1.2.3.6/tcp/4321"), + } + + cases := []struct { + addr ma.Multiaddr + want bool + failureReason string + }{ + { + addr: ma.StringCast("/ip4/1.2.3.4/tcp/1234"), + want: true, + failureReason: "IPv4 should be observed", + }, + { + addr: ma.StringCast("/ip6/1::4/tcp/1234"), + want: true, + failureReason: "public IPv6 address should be observed", + }, + { + addr: ma.StringCast("/ip6/64:ff9b::192.0.1.2/tcp/1234"), + want: false, + failureReason: "NAT64 IPv6 address shouldn't be observed", + }, + } + for i, tc := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + + if shouldRecordObservation(h, h, c, tc.addr) != tc.want { + t.Fatalf("%s %s", tc.addr, tc.failureReason) + } + }) + } +}