mirror of
https://github.com/libp2p/go-libp2p.git
synced 2025-12-24 13:29:35 +08:00
autonatv2: fix normalization for websocket addrs (#3403)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user