Skip to content

Commit 5ef3208

Browse files
swarm: skip dialing WebTransport addresses when we have QUIC addresses (#1756)
1 parent 131e5bd commit 5ef3208

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

p2p/net/swarm/swarm_dial.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,15 +439,15 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) []ma.Mul
439439
}
440440
}
441441

442-
return ma.FilterAddrs(addrs,
442+
return maybeRemoveWebTransportAddrs(ma.FilterAddrs(addrs,
443443
func(addr ma.Multiaddr) bool { return !ma.Contains(ourAddrs, addr) },
444444
s.canDial,
445445
// TODO: Consider allowing link-local addresses
446446
func(addr ma.Multiaddr) bool { return !manet.IsIP6LinkLocal(addr) },
447447
func(addr ma.Multiaddr) bool {
448448
return s.gater == nil || s.gater.InterceptAddrDial(p, addr)
449449
},
450-
)
450+
))
451451
}
452452

453453
// limitedDial will start a dial to the given peer when
@@ -530,3 +530,41 @@ func isRelayAddr(addr ma.Multiaddr) bool {
530530
_, err := addr.ValueForProtocol(ma.P_CIRCUIT)
531531
return err == nil
532532
}
533+
534+
func isWebTransport(addr ma.Multiaddr) bool {
535+
_, err := addr.ValueForProtocol(ma.P_WEBTRANSPORT)
536+
return err == nil
537+
}
538+
539+
func isQUIC(addr ma.Multiaddr) bool {
540+
_, err := addr.ValueForProtocol(ma.P_QUIC)
541+
return err == nil && !isWebTransport(addr)
542+
}
543+
544+
// If we have QUIC addresses, we don't want to dial WebTransport addresses.
545+
// It's better to have a native QUIC connection.
546+
// Note that this is a hack. The correct solution would be a proper
547+
// Happy-Eyeballs-style dialing.
548+
func maybeRemoveWebTransportAddrs(addrs []ma.Multiaddr) []ma.Multiaddr {
549+
var hasQuic, hasWebTransport bool
550+
for _, addr := range addrs {
551+
if isQUIC(addr) {
552+
hasQuic = true
553+
}
554+
if isWebTransport(addr) {
555+
hasWebTransport = true
556+
}
557+
}
558+
if !hasWebTransport || !hasQuic {
559+
return addrs
560+
}
561+
var c int
562+
for _, addr := range addrs {
563+
if isWebTransport(addr) {
564+
continue
565+
}
566+
addrs[c] = addr
567+
c++
568+
}
569+
return addrs[:c]
570+
}

p2p/net/swarm/swarm_dial_test.go

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import (
1515
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
1616
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
1717
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
18-
"github.com/multiformats/go-multiaddr"
18+
19+
ma "github.com/multiformats/go-multiaddr"
1920
madns "github.com/multiformats/go-multiaddr-dns"
2021
"github.com/stretchr/testify/require"
2122
)
@@ -54,7 +55,7 @@ func TestAddrsForDial(t *testing.T) {
5455

5556
otherPeer := test.RandPeerIDFatal(t)
5657

57-
ps.AddAddr(otherPeer, multiaddr.StringCast("/dns4/example.com/tcp/1234/wss"), time.Hour)
58+
ps.AddAddr(otherPeer, ma.StringCast("/dns4/example.com/tcp/1234/wss"), time.Hour)
5859

5960
ctx := context.Background()
6061
mas, err := s.addrsForDial(ctx, otherPeer)
@@ -93,11 +94,11 @@ func TestAddrResolution(t *testing.T) {
9394

9495
p1 := test.RandPeerIDFatal(t)
9596
p2 := test.RandPeerIDFatal(t)
96-
addr1 := multiaddr.StringCast("/dnsaddr/example.com")
97-
addr2 := multiaddr.StringCast("/ip4/192.0.2.1/tcp/123")
97+
addr1 := ma.StringCast("/dnsaddr/example.com")
98+
addr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123")
9899

99-
p2paddr2 := multiaddr.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
100-
p2paddr3 := multiaddr.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p2.Pretty())
100+
p2paddr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
101+
p2paddr3 := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p2.Pretty())
101102

102103
backend := &madns.MockResolver{
103104
TXT: map[string][]string{"_dnsaddr.example.com": {
@@ -136,13 +137,13 @@ func TestAddrResolutionRecursive(t *testing.T) {
136137
if err != nil {
137138
t.Error(err)
138139
}
139-
addr1 := multiaddr.StringCast("/dnsaddr/example.com")
140-
addr2 := multiaddr.StringCast("/ip4/192.0.2.1/tcp/123")
141-
p2paddr1 := multiaddr.StringCast("/dnsaddr/example.com/p2p/" + p1.Pretty())
142-
p2paddr2 := multiaddr.StringCast("/dnsaddr/example.com/p2p/" + p2.Pretty())
143-
p2paddr1i := multiaddr.StringCast("/dnsaddr/foo.example.com/p2p/" + p1.Pretty())
144-
p2paddr2i := multiaddr.StringCast("/dnsaddr/bar.example.com/p2p/" + p2.Pretty())
145-
p2paddr1f := multiaddr.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
140+
addr1 := ma.StringCast("/dnsaddr/example.com")
141+
addr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123")
142+
p2paddr1 := ma.StringCast("/dnsaddr/example.com/p2p/" + p1.Pretty())
143+
p2paddr2 := ma.StringCast("/dnsaddr/example.com/p2p/" + p2.Pretty())
144+
p2paddr1i := ma.StringCast("/dnsaddr/foo.example.com/p2p/" + p1.Pretty())
145+
p2paddr2i := ma.StringCast("/dnsaddr/bar.example.com/p2p/" + p2.Pretty())
146+
p2paddr1f := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
146147

147148
backend := &madns.MockResolver{
148149
TXT: map[string][]string{
@@ -191,3 +192,15 @@ func TestAddrResolutionRecursive(t *testing.T) {
191192
require.Len(t, addrs2, 1)
192193
require.Contains(t, addrs2, addr1)
193194
}
195+
196+
func TestRemoveWebTransportAddrs(t *testing.T) {
197+
tcpAddr := ma.StringCast("/ip4/9.5.6.4/tcp/1234")
198+
quicAddr := ma.StringCast("/ip4/1.2.3.4/udp/443/quic")
199+
webtransportAddr := ma.StringCast("/ip4/1.2.3.4/udp/443/quic/webtransport")
200+
201+
require.Equal(t, []ma.Multiaddr{tcpAddr, quicAddr}, maybeRemoveWebTransportAddrs([]ma.Multiaddr{tcpAddr, quicAddr}))
202+
require.Equal(t, []ma.Multiaddr{tcpAddr, webtransportAddr}, maybeRemoveWebTransportAddrs([]ma.Multiaddr{tcpAddr, webtransportAddr}))
203+
require.Equal(t, []ma.Multiaddr{tcpAddr, quicAddr}, maybeRemoveWebTransportAddrs([]ma.Multiaddr{tcpAddr, webtransportAddr, quicAddr}))
204+
require.Equal(t, []ma.Multiaddr{quicAddr}, maybeRemoveWebTransportAddrs([]ma.Multiaddr{quicAddr, webtransportAddr}))
205+
require.Equal(t, []ma.Multiaddr{webtransportAddr}, maybeRemoveWebTransportAddrs([]ma.Multiaddr{webtransportAddr}))
206+
}

0 commit comments

Comments
 (0)