Skip to content

Commit 9fec5bf

Browse files
committed
swarm_test: support more transports for GenSwarm
This adds support for `/webtransport` andn `/webrtc-direct` to GenSwarm. Ideally, we should rewrite this to have the same semantics, opt into transports not opt out, as `libp2p.New`. But I need webtransport and webrtc support to write address inference tests for #3075 Depending on how disruptive this is to users, we can decide on whether to merge or drop this.
1 parent f88beca commit 9fec5bf

File tree

4 files changed

+121
-16
lines changed

4 files changed

+121
-16
lines changed

p2p/net/swarm/swarm_notif_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
. "github.com/libp2p/go-libp2p/p2p/net/swarm"
1111

1212
ma "github.com/multiformats/go-multiaddr"
13+
manet "github.com/multiformats/go-multiaddr/net"
1314

1415
"github.com/stretchr/testify/require"
1516
)
@@ -93,11 +94,29 @@ func TestNotifications(t *testing.T) {
9394
}
9495
}
9596

97+
normalizeAddrs := func(a ma.Multiaddr, isLocal bool) ma.Multiaddr {
98+
// remove certhashes
99+
x, _ := ma.SplitFunc(a, func(c ma.Component) bool {
100+
return c.Protocol().Code == ma.P_CERTHASH
101+
})
102+
// on local addrs, replace 0.0.0.0 with 127.0.0.1
103+
if isLocal {
104+
if manet.IsIPUnspecified(x) {
105+
ip, rest := ma.SplitFirst(x)
106+
if ip.Protocol().Code == ma.P_IP4 {
107+
return ma.StringCast("/ip4/127.0.0.1").Encapsulate(rest)
108+
} else {
109+
return ma.StringCast("/ip6/::1").Encapsulate(rest)
110+
}
111+
}
112+
}
113+
return x
114+
}
96115
complement := func(c network.Conn) (*Swarm, *netNotifiee, *Conn) {
97116
for i, s := range swarms {
98117
for _, c2 := range s.Conns() {
99-
if c.LocalMultiaddr().Equal(c2.RemoteMultiaddr()) &&
100-
c2.LocalMultiaddr().Equal(c.RemoteMultiaddr()) {
118+
if normalizeAddrs(c.LocalMultiaddr(), true).Equal(normalizeAddrs(c2.RemoteMultiaddr(), false)) &&
119+
normalizeAddrs(c2.LocalMultiaddr(), true).Equal(normalizeAddrs(c.RemoteMultiaddr(), false)) {
101120
return s, notifiees[i], c2.(*Conn)
102121
}
103122
}

p2p/net/swarm/swarm_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ func makeSwarms(t *testing.T, num int, opts ...Option) []*swarm.Swarm {
7979

8080
func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
8181
var wg sync.WaitGroup
82-
connect := func(s *swarm.Swarm, dst peer.ID, addr ma.Multiaddr) {
83-
// TODO: make a DialAddr func.
84-
s.Peerstore().AddAddr(dst, addr, peerstore.PermanentAddrTTL)
82+
connect := func(s *swarm.Swarm, dst peer.ID, addrs []ma.Multiaddr) {
83+
s.Peerstore().AddAddrs(dst, addrs, peerstore.TempAddrTTL)
8584
if _, err := s.DialPeer(ctx, dst); err != nil {
8685
t.Fatal("error swarm dialing to peer", err)
8786
}
@@ -92,7 +91,7 @@ func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
9291
for i, s1 := range swarms {
9392
for _, s2 := range swarms[i+1:] {
9493
wg.Add(1)
95-
connect(s1, s2.LocalPeer(), s2.ListenAddresses()[0]) // try the first.
94+
connect(s1, s2.LocalPeer(), s2.ListenAddresses())
9695
}
9796
}
9897
wg.Wait()

p2p/net/swarm/testing/testing.go

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package testing
22

33
import (
44
"crypto/rand"
5+
"net"
56
"testing"
67
"time"
78

@@ -24,21 +25,26 @@ import (
2425
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
2526
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
2627
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
28+
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
29+
libp2pwebtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
2730

2831
ma "github.com/multiformats/go-multiaddr"
32+
manet "github.com/multiformats/go-multiaddr/net"
2933
"github.com/quic-go/quic-go"
3034
"github.com/stretchr/testify/require"
3135
)
3236

3337
type config struct {
34-
disableReuseport bool
35-
dialOnly bool
36-
disableTCP bool
37-
disableQUIC bool
38-
connectionGater connmgr.ConnectionGater
39-
sk crypto.PrivKey
40-
swarmOpts []swarm.Option
41-
eventBus event.Bus
38+
disableReuseport bool
39+
dialOnly bool
40+
disableTCP bool
41+
disableQUIC bool
42+
disableWebTransport bool
43+
disableWebRTC bool
44+
connectionGater connmgr.ConnectionGater
45+
sk crypto.PrivKey
46+
swarmOpts []swarm.Option
47+
eventBus event.Bus
4248
clock
4349
}
4450

@@ -88,6 +94,16 @@ var OptDisableQUIC Option = func(_ testing.TB, c *config) {
8894
c.disableQUIC = true
8995
}
9096

97+
// OptDisableWebTransport disables WebTransport.
98+
var OptDisableWebTransport Option = func(_ testing.TB, c *config) {
99+
c.disableWebTransport = true
100+
}
101+
102+
// OptDisableWebRTC disables WebRTC.
103+
var OptDisableWebRTC Option = func(_ testing.TB, c *config) {
104+
c.disableWebRTC = true
105+
}
106+
91107
// OptConnGater configures the given connection gater on the test
92108
func OptConnGater(cg connmgr.ConnectionGater) Option {
93109
return func(_ testing.TB, c *config) {
@@ -175,8 +191,10 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
175191
}
176192
}
177193
}
194+
var quicListenAddr ma.Multiaddr
195+
var reuse *quicreuse.ConnManager
178196
if !cfg.disableQUIC {
179-
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
197+
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
180198
if err != nil {
181199
t.Fatal(err)
182200
}
@@ -191,6 +209,75 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
191209
if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1")); err != nil {
192210
t.Fatal(err)
193211
}
212+
for _, a := range s.ListenAddresses() {
213+
if _, err := a.ValueForProtocol(ma.P_QUIC_V1); err == nil {
214+
quicListenAddr = a
215+
break
216+
}
217+
}
218+
}
219+
}
220+
if !cfg.disableWebTransport {
221+
if reuse == nil {
222+
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
223+
if err != nil {
224+
t.Fatal(err)
225+
}
226+
}
227+
wtTransport, err := libp2pwebtransport.New(priv, nil, reuse, cfg.connectionGater, nil)
228+
if err != nil {
229+
t.Fatal(err)
230+
}
231+
if err := s.AddTransport(wtTransport); err != nil {
232+
t.Fatal(err)
233+
}
234+
if !cfg.dialOnly {
235+
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1/webtransport")
236+
if quicListenAddr != nil {
237+
listenAddr = quicListenAddr.Encapsulate(ma.StringCast("/webtransport"))
238+
}
239+
if err := s.Listen(listenAddr); err != nil {
240+
t.Fatal(err)
241+
}
242+
}
243+
}
244+
245+
if !cfg.disableWebRTC {
246+
listenUDPFn := func(network string, laddr *net.UDPAddr) (net.PacketConn, error) {
247+
hasQuicAddrPortFor := func(network string, laddr *net.UDPAddr) bool {
248+
quicAddrPorts := map[string]struct{}{}
249+
for _, addr := range s.ListenAddresses() {
250+
if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
251+
netw, addr, err := manet.DialArgs(addr)
252+
if err != nil {
253+
return false
254+
}
255+
quicAddrPorts[netw+"_"+addr] = struct{}{}
256+
}
257+
}
258+
_, ok := quicAddrPorts[network+"_"+laddr.String()]
259+
return ok
260+
}
261+
if hasQuicAddrPortFor(network, laddr) {
262+
return reuse.SharedNonQUICPacketConn(network, laddr)
263+
}
264+
return net.ListenUDP(network, laddr)
265+
}
266+
wrtcTransport, err := libp2pwebrtc.New(priv, nil, cfg.connectionGater, nil, listenUDPFn)
267+
if err != nil {
268+
t.Fatal(err)
269+
}
270+
if err := s.AddTransport(wrtcTransport); err != nil {
271+
t.Fatal(err)
272+
}
273+
if !cfg.dialOnly {
274+
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/webrtc-direct")
275+
if quicListenAddr != nil {
276+
listenAddr = quicListenAddr.Decapsulate(ma.StringCast("/quic-v1")).Encapsulate(ma.StringCast("/webrtc-direct"))
277+
}
278+
if err := s.Listen(listenAddr); err != nil {
279+
t.Fatal(err)
280+
}
194281
}
195282
}
196283
if !cfg.dialOnly {

p2p/protocol/autonatv2/autonat_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func newAutoNAT(t testing.TB, dialer host.Host, opts ...AutoNATOption) *AutoNAT
2828
t.Helper()
2929
b := eventbus.NewBus()
3030
h := bhost.NewBlankHost(
31-
swarmt.GenSwarm(t, swarmt.EventBus(b)), bhost.WithEventBus(b))
31+
swarmt.GenSwarm(t, swarmt.EventBus(b), swarmt.OptDisableWebTransport, swarmt.OptDisableWebRTC), bhost.WithEventBus(b))
3232
if dialer == nil {
3333
dialer = bhost.NewBlankHost(
3434
swarmt.GenSwarm(t,

0 commit comments

Comments
 (0)