autonatv2: fix normalization for websocket addrs (#3403)

This commit is contained in:
sukun
2025-10-07 13:49:45 +05:30
committed by GitHub
parent b12a0b43a6
commit bd2fc6bc3a
2 changed files with 59 additions and 12 deletions

View File

@@ -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) {

View File

@@ -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"
)
@@ -327,23 +325,54 @@ func (ac *client) handleDialBack(s network.Stream) {
}
}
var tlsWSAddr = ma.StringCast("/tls/ws")
// normalizeMultiaddr returns a multiaddr suitable for equality checks.
// If the multiaddr is a webtransport component, it removes the 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 {
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)
// /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 out
}
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[:i+1]
}
}
return nil
}
func (ac *client) areAddrsConsistent(connLocalAddr, dialedAddr ma.Multiaddr) bool {
if len(connLocalAddr) == 0 || len(dialedAddr) == 0 {
return false