From 858e75df15bf443604c2c39afb4d9b6b2a69766d Mon Sep 17 00:00:00 2001 From: sukun Date: Fri, 3 Oct 2025 15:50:37 +0530 Subject: [PATCH 1/2] autonatv2: remove dependency on webrtc and webtransport --- p2p/protocol/autonatv2/client.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/p2p/protocol/autonatv2/client.go b/p2p/protocol/autonatv2/client.go index 5cbe698dd5..203f822d6b 100644 --- a/p2p/protocol/autonatv2/client.go +++ b/p2p/protocol/autonatv2/client.go @@ -14,8 +14,6 @@ import ( "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/protocol/autonatv2/pb" - libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc" - libp2pwebtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport" "github.com/libp2p/go-msgio/pbio" ma "github.com/multiformats/go-multiaddr" ) @@ -328,20 +326,20 @@ func (ac *client) handleDialBack(s network.Stream) { } // normalizeMultiaddr returns a multiaddr suitable for equality checks. -// If the multiaddr is a webtransport component, it removes the certhashes. +// it removes trailing certhashes. func normalizeMultiaddr(addr ma.Multiaddr) ma.Multiaddr { - ok, n := libp2pwebtransport.IsWebtransportMultiaddr(addr) - if !ok { - ok, n = libp2pwebrtc.IsWebRTCDirectMultiaddr(addr) - } - if ok && n > 0 { - out := addr - for i := 0; i < n; i++ { - out, _ = ma.SplitLast(out) + addr = removeTrailing(addr, ma.P_P2P) + addr = removeTrailing(addr, ma.P_CERTHASH) + return addr +} + +func removeTrailing(addr ma.Multiaddr, protocolCode int) ma.Multiaddr { + for i := len(addr) - 1; i >= 0; i-- { + if addr[i].Code() != protocolCode { + return addr[0 : i+1] } - return out } - return addr + return nil } func (ac *client) areAddrsConsistent(connLocalAddr, dialedAddr ma.Multiaddr) bool { From 6ed6f8551051489e238a07fe40f485337ee3dbbd Mon Sep 17 00:00:00 2001 From: sukun Date: Fri, 3 Oct 2025 16:08:25 +0530 Subject: [PATCH 2/2] autonatv2: fix normalization for websocket addrs 1. Convert /wss to /tls/ws 2. Ignore the sni for comparison because there's no sni information on `conn.LocalAddr()` --- p2p/protocol/autonatv2/autonat_test.go | 18 +++++++++++++ p2p/protocol/autonatv2/client.go | 35 ++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/p2p/protocol/autonatv2/autonat_test.go b/p2p/protocol/autonatv2/autonat_test.go index 7ef2fa223a..82b5014d39 100644 --- a/p2p/protocol/autonatv2/autonat_test.go +++ b/p2p/protocol/autonatv2/autonat_test.go @@ -636,6 +636,24 @@ func TestAreAddrsConsistency(t *testing.T) { dialAddr: ma.StringCast("/ip4/1.2.3.4/udp/123/quic-v1/"), success: false, }, + { + name: "wss", + dialAddr: ma.StringCast("/dns/lib.p2p/tcp/1/wss"), + localAddr: ma.StringCast("/ip4/1.2.3.4/tcp/1/tls/ws"), + success: true, + }, + { + name: "tls-sni", + localAddr: ma.StringCast("/ip4/1.2.3.4/tcp/1/wss"), + dialAddr: ma.StringCast("/ip4/1.2.3.4/tcp/1/tls/sni/abc.xyz/ws"), + success: true, + }, + { + name: "only p2p", + localAddr: ma.StringCast("/p2p/QmYo41GybvrXk8y8Xnm1P7pfA4YEXCpfnLyzgRPnNbG35e"), + dialAddr: ma.StringCast("/p2p/QmYo41GybvrXk8y8Xnm1P7pfA4YEXCpfnLyzgRPnNbG35e"), + success: true, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { diff --git a/p2p/protocol/autonatv2/client.go b/p2p/protocol/autonatv2/client.go index 203f822d6b..0e272718b9 100644 --- a/p2p/protocol/autonatv2/client.go +++ b/p2p/protocol/autonatv2/client.go @@ -325,18 +325,49 @@ func (ac *client) handleDialBack(s network.Stream) { } } +var tlsWSAddr = ma.StringCast("/tls/ws") + // normalizeMultiaddr returns a multiaddr suitable for equality checks. -// it removes trailing certhashes. +// it removes trailing certhashes and p2p components, removes sni components, +// and translates /wss to /tls/ws. +// Remove sni components because there's no way for us to verify whether the +// correct sni was dialled by the remote host as the LocalAddr on the websocket conn +// doesn't have sni information. +// Note: This is used for comparing two addresses where both the addresses are +// controlled by the host not by a remote node. func normalizeMultiaddr(addr ma.Multiaddr) ma.Multiaddr { addr = removeTrailing(addr, ma.P_P2P) addr = removeTrailing(addr, ma.P_CERTHASH) + + // /wss => /tls/ws + for i, c := range addr { + if c.Code() == ma.P_WSS { + na := make(ma.Multiaddr, 0, len(addr)+1) + na = append(na, addr[:i]...) + na = append(na, tlsWSAddr...) + na = append(na, addr[i+1:]...) + addr = na + break // only do this once; there shouldn't be two /wss components anyway + } + } + + // remove the sni component + for i, c := range addr { + if c.Code() == ma.P_SNI { + na := make(ma.Multiaddr, 0, len(addr)-1) + na = append(na, addr[:i]...) + na = append(na, addr[i+1:]...) + addr = na + break // only do this once; there shouldn't be two /sni components anyway + } + } return addr } func removeTrailing(addr ma.Multiaddr, protocolCode int) ma.Multiaddr { for i := len(addr) - 1; i >= 0; i-- { if addr[i].Code() != protocolCode { - return addr[0 : i+1] + return addr[:i+1] } } return nil