diff --git a/core/transport/transport.go b/core/transport/transport.go index ad2ee664..2a753773 100644 --- a/core/transport/transport.go +++ b/core/transport/transport.go @@ -91,7 +91,7 @@ type Listener interface { Accept() (CapableConn, error) Close() error Addr() net.Addr - Multiaddr() ma.Multiaddr + Multiaddrs() []ma.Multiaddr } // TransportNetwork is an inet.Network with methods for managing transports. diff --git a/p2p/host/autonat/dialpolicy_test.go b/p2p/host/autonat/dialpolicy_test.go index 75731ae9..e56a862b 100644 --- a/p2p/host/autonat/dialpolicy_test.go +++ b/p2p/host/autonat/dialpolicy_test.go @@ -47,9 +47,9 @@ func (l *mockL) Accept() (transport.CapableConn, error) { <-l.ctx.Done() return nil, errors.New("expected in mocked test") } -func (l *mockL) Close() error { return nil } -func (l *mockL) Addr() net.Addr { return nil } -func (l *mockL) Multiaddr() multiaddr.Multiaddr { return l.addr } +func (l *mockL) Close() error { return nil } +func (l *mockL) Addr() net.Addr { return nil } +func (l *mockL) Multiaddrs() []multiaddr.Multiaddr { return []multiaddr.Multiaddr{l.addr} } func TestSkipDial(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/p2p/net/swarm/swarm_addr.go b/p2p/net/swarm/swarm_addr.go index 8d088e76..aa8b8080 100644 --- a/p2p/net/swarm/swarm_addr.go +++ b/p2p/net/swarm/swarm_addr.go @@ -18,7 +18,7 @@ func (s *Swarm) ListenAddresses() []ma.Multiaddr { func (s *Swarm) listenAddressesNoLock() []ma.Multiaddr { addrs := make([]ma.Multiaddr, 0, len(s.listeners.m)) for l := range s.listeners.m { - addrs = append(addrs, l.Multiaddr()) + addrs = append(addrs, l.Multiaddrs()...) } return addrs } diff --git a/p2p/net/swarm/swarm_listen.go b/p2p/net/swarm/swarm_listen.go index 044da2e8..59407162 100644 --- a/p2p/net/swarm/swarm_listen.go +++ b/p2p/net/swarm/swarm_listen.go @@ -43,7 +43,7 @@ func (s *Swarm) ListenClose(addrs ...ma.Multiaddr) { s.listeners.Lock() for l := range s.listeners.m { - if !containsMultiaddr(addrs, l.Multiaddr()) { + if !containsSomeMultiaddr(addrs, l.Multiaddrs()) { continue } @@ -92,11 +92,13 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { s.listeners.cacheEOL = time.Time{} s.listeners.Unlock() - maddr := list.Multiaddr() + maddrs := list.Multiaddrs() // signal to our notifiees on listen. s.notifyAll(func(n network.Notifiee) { - n.Listen(s, maddr) + for _, maddr := range maddrs { + n.Listen(s, maddr) + } }) go func() { @@ -116,7 +118,9 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { // signal to our notifiees on listen close. s.notifyAll(func(n network.Notifiee) { - n.ListenClose(s, maddr) + for _, maddr := range maddrs { + n.ListenClose(s, maddr) + } }) s.refs.Done() }() @@ -147,11 +151,16 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { return nil } -func containsMultiaddr(addrs []ma.Multiaddr, addr ma.Multiaddr) bool { - for _, a := range addrs { - if addr == a { +func containsSomeMultiaddr(hayStack []ma.Multiaddr, needles []ma.Multiaddr) bool { + seenSet := make(map[string]struct{}, len(needles)) + for _, a := range needles { + seenSet[string(a.Bytes())] = struct{}{} + } + for _, a := range hayStack { + if _, found := seenSet[string(a.Bytes())]; found { return true } } return false + } diff --git a/p2p/net/upgrader/listener.go b/p2p/net/upgrader/listener.go index c07299c1..0a3ab557 100644 --- a/p2p/net/upgrader/listener.go +++ b/p2p/net/upgrader/listener.go @@ -10,6 +10,7 @@ import ( logging "github.com/ipfs/go-log/v2" tec "github.com/jbenet/go-temp-err-catcher" + "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -175,4 +176,8 @@ func (l *listener) String() string { return fmt.Sprintf("", l.Multiaddr()) } +func (l *listener) Multiaddrs() []multiaddr.Multiaddr { + return []multiaddr.Multiaddr{l.Multiaddr()} +} + var _ transport.Listener = (*listener)(nil) diff --git a/p2p/net/upgrader/listener_test.go b/p2p/net/upgrader/listener_test.go index 5b541075..0d872d1d 100644 --- a/p2p/net/upgrader/listener_test.go +++ b/p2p/net/upgrader/listener_test.go @@ -56,7 +56,7 @@ func TestAcceptSingleConn(t *testing.T) { ln := createListener(t, u) defer ln.Close() - cconn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + cconn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) sconn, err := ln.Accept() @@ -80,7 +80,7 @@ func TestAcceptMultipleConns(t *testing.T) { }() for i := 0; i < 10; i++ { - cconn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + cconn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) toClose = append(toClose, cconn) @@ -104,7 +104,7 @@ func TestConnectionsClosedIfNotAccepted(t *testing.T) { ln := createListener(t, u) defer ln.Close() - conn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) errCh := make(chan error) @@ -143,7 +143,7 @@ func TestFailedUpgradeOnListen(t *testing.T) { errCh <- err }() - _, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + _, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.Error(err) // close the listener. @@ -177,7 +177,7 @@ func TestListenerClose(t *testing.T) { require.Contains(err.Error(), "use of closed network connection") // doesn't accept new connections when it is closed - _, err = dial(t, u, ln.Multiaddr(), peer.ID("1"), &network.NullScope{}) + _, err = dial(t, u, ln.Multiaddrs()[0], peer.ID("1"), &network.NullScope{}) require.Error(err) } @@ -189,7 +189,7 @@ func TestListenerCloseClosesQueued(t *testing.T) { var conns []transport.CapableConn for i := 0; i < 10; i++ { - conn, err := dial(t, upgrader, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, upgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) conns = append(conns, conn) } @@ -249,7 +249,7 @@ func TestConcurrentAccept(t *testing.T) { go func() { defer wg.Done() - conn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) if err != nil { errCh <- err return @@ -279,7 +279,7 @@ func TestAcceptQueueBacklogged(t *testing.T) { // setup AcceptQueueLength connections, but don't accept any of them var counter int32 // to be used atomically doDial := func() { - conn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) atomic.AddInt32(&counter, 1) t.Cleanup(func() { conn.Close() }) @@ -315,7 +315,7 @@ func TestListenerConnectionGater(t *testing.T) { defer ln.Close() // no gating. - conn, err := dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) require.False(conn.IsClosed()) _ = conn.Close() @@ -323,28 +323,28 @@ func TestListenerConnectionGater(t *testing.T) { // rejecting after handshake. testGater.BlockSecured(true) testGater.BlockAccept(false) - conn, err = dial(t, u, ln.Multiaddr(), "invalid", &network.NullScope{}) + conn, err = dial(t, u, ln.Multiaddrs()[0], "invalid", &network.NullScope{}) require.Error(err) require.Nil(conn) // rejecting on accept will trigger firupgrader. testGater.BlockSecured(true) testGater.BlockAccept(true) - conn, err = dial(t, u, ln.Multiaddr(), "invalid", &network.NullScope{}) + conn, err = dial(t, u, ln.Multiaddrs()[0], "invalid", &network.NullScope{}) require.Error(err) require.Nil(conn) // rejecting only on acceptance. testGater.BlockSecured(false) testGater.BlockAccept(true) - conn, err = dial(t, u, ln.Multiaddr(), "invalid", &network.NullScope{}) + conn, err = dial(t, u, ln.Multiaddrs()[0], "invalid", &network.NullScope{}) require.Error(err) require.Nil(conn) // back to normal testGater.BlockSecured(false) testGater.BlockAccept(false) - conn, err = dial(t, u, ln.Multiaddr(), id, &network.NullScope{}) + conn, err = dial(t, u, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) require.False(conn.IsClosed()) _ = conn.Close() @@ -360,13 +360,13 @@ func TestListenerResourceManagement(t *testing.T) { connScope := mocknetwork.NewMockConnManagementScope(ctrl) gomock.InOrder( - rcmgr.EXPECT().OpenConnection(network.DirInbound, true, gomock.Not(ln.Multiaddr())).Return(connScope, nil), + rcmgr.EXPECT().OpenConnection(network.DirInbound, true, gomock.Not(ln.Multiaddrs()[0])).Return(connScope, nil), connScope.EXPECT().PeerScope(), connScope.EXPECT().SetPeer(id), connScope.EXPECT().PeerScope(), ) - cconn, err := dial(t, upgrader, ln.Multiaddr(), id, &network.NullScope{}) + cconn, err := dial(t, upgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(t, err) defer cconn.Close() @@ -383,8 +383,8 @@ func TestListenerResourceManagementDenied(t *testing.T) { id, upgrader := createUpgraderWithResourceManager(t, rcmgr) ln := createListener(t, upgrader) - rcmgr.EXPECT().OpenConnection(network.DirInbound, true, gomock.Not(ln.Multiaddr())).Return(nil, errors.New("nope")) - _, err := dial(t, upgrader, ln.Multiaddr(), id, &network.NullScope{}) + rcmgr.EXPECT().OpenConnection(network.DirInbound, true, gomock.Not(ln.Multiaddrs()[0])).Return(nil, errors.New("nope")) + _, err := dial(t, upgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.Error(t, err) done := make(chan struct{}) diff --git a/p2p/net/upgrader/upgrader_test.go b/p2p/net/upgrader/upgrader_test.go index 106752ab..ccbd6ffa 100644 --- a/p2p/net/upgrader/upgrader_test.go +++ b/p2p/net/upgrader/upgrader_test.go @@ -134,21 +134,21 @@ func TestOutboundConnectionGating(t *testing.T) { testGater := &testGater{} _, dialUpgrader := createUpgraderWithConnGater(t, testGater) - conn, err := dial(t, dialUpgrader, ln.Multiaddr(), id, &network.NullScope{}) + conn, err := dial(t, dialUpgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) require.NotNil(conn) _ = conn.Close() // blocking accepts doesn't affect the dialling side, only the listener. testGater.BlockAccept(true) - conn, err = dial(t, dialUpgrader, ln.Multiaddr(), id, &network.NullScope{}) + conn, err = dial(t, dialUpgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.NoError(err) require.NotNil(conn) _ = conn.Close() // now let's block all connections after being secured. testGater.BlockSecured(true) - conn, err = dial(t, dialUpgrader, ln.Multiaddr(), id, &network.NullScope{}) + conn, err = dial(t, dialUpgrader, ln.Multiaddrs()[0], id, &network.NullScope{}) require.Error(err) require.Contains(err.Error(), "gater rejected connection") require.Nil(conn) @@ -169,7 +169,7 @@ func TestOutboundResourceManagement(t *testing.T) { connScope.EXPECT().PeerScope().Return(&network.NullScope{}), ) _, dialUpgrader := createUpgrader(t) - conn, err := dial(t, dialUpgrader, ln.Multiaddr(), id, connScope) + conn, err := dial(t, dialUpgrader, ln.Multiaddrs()[0], id, connScope) require.NoError(t, err) require.NotNil(t, conn) connScope.EXPECT().Done() @@ -191,7 +191,7 @@ func TestOutboundResourceManagement(t *testing.T) { connScope.EXPECT().Done(), ) _, dialUpgrader := createUpgrader(t) - _, err := dial(t, dialUpgrader, ln.Multiaddr(), id, connScope) + _, err := dial(t, dialUpgrader, ln.Multiaddrs()[0], id, connScope) require.Error(t, err) }) diff --git a/p2p/transport/quic/cmd/server/main.go b/p2p/transport/quic/cmd/server/main.go index e6585137..7122de60 100644 --- a/p2p/transport/quic/cmd/server/main.go +++ b/p2p/transport/quic/cmd/server/main.go @@ -48,7 +48,7 @@ func run(port string) error { if err != nil { return err } - fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddr(), peerID) + fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddrs()[0], peerID) for { conn, err := ln.Accept() if err != nil { diff --git a/p2p/transport/quic/conn_test.go b/p2p/transport/quic/conn_test.go index 047c3034..6bca67da 100644 --- a/p2p/transport/quic/conn_test.go +++ b/p2p/transport/quic/conn_test.go @@ -84,7 +84,7 @@ func testHandshake(t *testing.T, tc *connTestCase) { clientTransport, err := NewTransport(clientKey, nil, nil, nil, tc.Options...) require.NoError(t, err) defer clientTransport.(io.Closer).Close() - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() serverConn, err := ln.Accept() @@ -146,7 +146,7 @@ func testResourceManagerSuccess(t *testing.T, tc *connTestCase) { connChan := make(chan tpt.CapableConn) serverConnScope := mocknetwork.NewMockConnManagementScope(ctrl) go func() { - serverRcmgr.EXPECT().OpenConnection(network.DirInbound, false, gomock.Not(ln.Multiaddr())).Return(serverConnScope, nil) + serverRcmgr.EXPECT().OpenConnection(network.DirInbound, false, gomock.Not(ln.Multiaddrs()[0])).Return(serverConnScope, nil) serverConnScope.EXPECT().SetPeer(clientID) serverConn, err := ln.Accept() require.NoError(t, err) @@ -154,9 +154,9 @@ func testResourceManagerSuccess(t *testing.T, tc *connTestCase) { }() connScope := mocknetwork.NewMockConnManagementScope(ctrl) - clientRcmgr.EXPECT().OpenConnection(network.DirOutbound, false, ln.Multiaddr()).Return(connScope, nil) + clientRcmgr.EXPECT().OpenConnection(network.DirOutbound, false, ln.Multiaddrs()[0]).Return(connScope, nil) connScope.EXPECT().SetPeer(serverID) - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) serverConn := <-connChan t.Log("received conn") @@ -238,12 +238,12 @@ func testResourceManagerAcceptDenied(t *testing.T, tc *connTestCase) { }() clientConnScope := mocknetwork.NewMockConnManagementScope(ctrl) - clientRcmgr.EXPECT().OpenConnection(network.DirOutbound, false, ln.Multiaddr()).Return(clientConnScope, nil) + clientRcmgr.EXPECT().OpenConnection(network.DirOutbound, false, ln.Multiaddrs()[0]).Return(clientConnScope, nil) clientConnScope.EXPECT().SetPeer(serverID) // In rare instances, the connection gating error will already occur on Dial. // In that case, Done is called on the connection scope. clientConnScope.EXPECT().Done().MaxTimes(1) - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) // In rare instances, the connection gating error will already occur on Dial. if err == nil { _, err = conn.AcceptStream() @@ -277,7 +277,7 @@ func testStreams(t *testing.T, tc *connTestCase) { clientTransport, err := NewTransport(clientKey, nil, nil, nil, tc.Options...) require.NoError(t, err) defer clientTransport.(io.Closer).Close() - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() serverConn, err := ln.Accept() @@ -317,7 +317,7 @@ func testHandshakeFailPeerIDMismatch(t *testing.T, tc *connTestCase) { clientTransport, err := NewTransport(clientKey, nil, nil, nil, tc.Options...) require.NoError(t, err) // dial, but expect the wrong peer ID - _, err = clientTransport.Dial(context.Background(), ln.Multiaddr(), thirdPartyID) + _, err = clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], thirdPartyID) require.Error(t, err) require.Contains(t, err.Error(), "CRYPTO_ERROR") defer clientTransport.(io.Closer).Close() @@ -374,7 +374,7 @@ func testConnectionGating(t *testing.T, tc *connTestCase) { require.NoError(t, err) defer clientTransport.(io.Closer).Close() // make sure that connection attempts fails - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) // In rare instances, the connection gating error will already occur on Dial. // In most cases, it will be returned by AcceptStream. if err == nil { @@ -386,7 +386,7 @@ func testConnectionGating(t *testing.T, tc *connTestCase) { cg.EXPECT().InterceptAccept(gomock.Any()).Return(true) cg.EXPECT().InterceptSecured(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) clientTransport.(*transport).clientConfig.HandshakeIdleTimeout = 2 * time.Second - conn, err = clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err = clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() require.Eventually(t, func() bool { @@ -414,14 +414,14 @@ func testConnectionGating(t *testing.T, tc *connTestCase) { defer clientTransport.(io.Closer).Close() // make sure that connection attempts fails - _, err = clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + _, err = clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.Error(t, err) require.Contains(t, err.Error(), "connection gated") // now allow the peerId and make sure the connection goes through cg.EXPECT().InterceptSecured(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) clientTransport.(*transport).clientConfig.HandshakeIdleTimeout = 2 * time.Second - conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := clientTransport.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) conn.Close() }) @@ -474,10 +474,10 @@ func testDialTwo(t *testing.T, tc *connTestCase) { clientTransport, err := NewTransport(clientKey, nil, nil, nil, tc.Options...) require.NoError(t, err) defer clientTransport.(io.Closer).Close() - c1, err := clientTransport.Dial(context.Background(), ln1.Multiaddr(), serverID) + c1, err := clientTransport.Dial(context.Background(), ln1.Multiaddrs()[0], serverID) require.NoError(t, err) defer c1.Close() - c2, err := clientTransport.Dial(context.Background(), ln2.Multiaddr(), serverID2) + c2, err := clientTransport.Dial(context.Background(), ln2.Multiaddrs()[0], serverID2) require.NoError(t, err) defer c2.Close() @@ -632,7 +632,7 @@ func TestHolePunching(t *testing.T) { go func() { conn, err := t2.Dial( network.WithSimultaneousConnect(context.Background(), false, ""), - ln1.Multiaddr(), + ln1.Multiaddrs()[0], serverID, ) require.NoError(t, err) @@ -650,7 +650,7 @@ func TestHolePunching(t *testing.T) { conn1, err := t1.Dial( network.WithSimultaneousConnect(context.Background(), true, ""), - ln2.Multiaddr(), + ln2.Multiaddrs()[0], clientID, ) require.NoError(t, err) diff --git a/p2p/transport/quic/listener.go b/p2p/transport/quic/listener.go index 949a3e7d..6cad6fa5 100644 --- a/p2p/transport/quic/listener.go +++ b/p2p/transport/quic/listener.go @@ -164,6 +164,6 @@ func (l *listener) Addr() net.Addr { } // Multiaddr returns the multiaddress of this listener. -func (l *listener) Multiaddr() ma.Multiaddr { - return l.localMultiaddr +func (l *listener) Multiaddrs() []ma.Multiaddr { + return []ma.Multiaddr{l.localMultiaddr} } diff --git a/p2p/transport/quic/listener_test.go b/p2p/transport/quic/listener_test.go index 7c8494ae..7f5fe845 100644 --- a/p2p/transport/quic/listener_test.go +++ b/p2p/transport/quic/listener_test.go @@ -66,7 +66,7 @@ func TestListenAddr(t *testing.T) { defer ln.Close() port := ln.Addr().(*net.UDPAddr).Port require.NotZero(t, port) - require.Equal(t, ln.Multiaddr().String(), fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic", port)) + require.Equal(t, ln.Multiaddrs()[0].String(), fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic", port)) }) t.Run("for IPv6", func(t *testing.T) { @@ -76,7 +76,7 @@ func TestListenAddr(t *testing.T) { defer ln.Close() port := ln.Addr().(*net.UDPAddr).Port require.NotZero(t, port) - require.Equal(t, ln.Multiaddr().String(), fmt.Sprintf("/ip6/::/udp/%d/quic", port)) + require.Equal(t, ln.Multiaddrs()[0].String(), fmt.Sprintf("/ip6/::/udp/%d/quic", port)) }) } diff --git a/p2p/transport/tcp/tcp_test.go b/p2p/transport/tcp/tcp_test.go index 92040463..b320c5a4 100644 --- a/p2p/transport/tcp/tcp_test.go +++ b/p2p/transport/tcp/tcp_test.go @@ -86,10 +86,10 @@ func TestResourceManager(t *testing.T) { t.Run("success", func(t *testing.T) { scope := mocknetwork.NewMockConnManagementScope(ctrl) - rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddr()).Return(scope, nil) + rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddrs()[0]).Return(scope, nil) scope.EXPECT().SetPeer(peerA) scope.EXPECT().PeerScope().Return(&network.NullScope{}).AnyTimes() // called by the upgrader - conn, err := tb.Dial(context.Background(), ln.Multiaddr(), peerA) + conn, err := tb.Dial(context.Background(), ln.Multiaddrs()[0], peerA) require.NoError(t, err) scope.EXPECT().Done() defer conn.Close() @@ -97,18 +97,18 @@ func TestResourceManager(t *testing.T) { t.Run("connection denied", func(t *testing.T) { rerr := errors.New("nope") - rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddr()).Return(nil, rerr) - _, err = tb.Dial(context.Background(), ln.Multiaddr(), peerA) + rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddrs()[0]).Return(nil, rerr) + _, err = tb.Dial(context.Background(), ln.Multiaddrs()[0], peerA) require.ErrorIs(t, err, rerr) }) t.Run("peer denied", func(t *testing.T) { scope := mocknetwork.NewMockConnManagementScope(ctrl) - rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddr()).Return(scope, nil) + rcmgr.EXPECT().OpenConnection(network.DirOutbound, true, ln.Multiaddrs()[0]).Return(scope, nil) rerr := errors.New("nope") scope.EXPECT().SetPeer(peerA).Return(rerr) scope.EXPECT().Done() - _, err = tb.Dial(context.Background(), ln.Multiaddr(), peerA) + _, err = tb.Dial(context.Background(), ln.Multiaddrs()[0], peerA) require.ErrorIs(t, err, rerr) }) } diff --git a/p2p/transport/testsuite/stream_suite.go b/p2p/transport/testsuite/stream_suite.go index b139976b..3170b72c 100644 --- a/p2p/transport/testsuite/stream_suite.go +++ b/p2p/transport/testsuite/stream_suite.go @@ -197,7 +197,7 @@ func SubtestStress(t *testing.T, ta, tb transport.Transport, maddr ma.Multiaddr, serve(t, l) }() - c, err := tb.Dial(context.Background(), l.Multiaddr(), peerA) + c, err := tb.Dial(context.Background(), l.Multiaddrs()[0], peerA) if err != nil { t.Error(err) return @@ -259,7 +259,7 @@ func SubtestStreamOpenStress(t *testing.T, ta, tb transport.Transport, maddr ma. connA, err = l.Accept() accepted <- err }() - connB, err = tb.Dial(context.Background(), l.Multiaddr(), peerA) + connB, err = tb.Dial(context.Background(), l.Multiaddrs()[0], peerA) if err != nil { t.Fatal(err) } @@ -373,7 +373,7 @@ func SubtestStreamReset(t *testing.T, ta, tb transport.Transport, maddr ma.Multi }() - muxb, err := tb.Dial(context.Background(), l.Multiaddr(), peerA) + muxb, err := tb.Dial(context.Background(), l.Multiaddrs()[0], peerA) if err != nil { t.Fatal(err) } diff --git a/p2p/transport/testsuite/transport_suite.go b/p2p/transport/testsuite/transport_suite.go index bd8892e8..f8d0ff11 100644 --- a/p2p/transport/testsuite/transport_suite.go +++ b/p2p/transport/testsuite/transport_suite.go @@ -111,11 +111,11 @@ func SubtestBasic(t *testing.T, ta, tb transport.Transport, maddr ma.Multiaddr, } }() - if !tb.CanDial(list.Multiaddr()) { + if !tb.CanDial(list.Multiaddrs()[0]) { t.Error("CanDial should have returned true") } - connA, err = tb.Dial(ctx, list.Multiaddr(), peerA) + connA, err = tb.Dial(ctx, list.Multiaddrs()[0], peerA) if err != nil { t.Fatal(err) } @@ -232,11 +232,11 @@ func SubtestPingPong(t *testing.T, ta, tb transport.Transport, maddr ma.Multiadd sWg.Wait() }() - if !tb.CanDial(list.Multiaddr()) { + if !tb.CanDial(list.Multiaddrs()[0]) { t.Error("CanDial should have returned true") } - connB, err = tb.Dial(ctx, list.Multiaddr(), peerA) + connB, err = tb.Dial(ctx, list.Multiaddrs()[0], peerA) if err != nil { t.Fatal(err) } @@ -297,7 +297,7 @@ func SubtestCancel(t *testing.T, ta, tb transport.Transport, maddr ma.Multiaddr, ctx, cancel := context.WithCancel(context.Background()) cancel() - c, err := tb.Dial(ctx, list.Multiaddr(), peerA) + c, err := tb.Dial(ctx, list.Multiaddrs()[0], peerA) if err == nil { c.Close() t.Fatal("dial should have failed") diff --git a/p2p/transport/websocket/listener.go b/p2p/transport/websocket/listener.go index 128fdf5e..ee681080 100644 --- a/p2p/transport/websocket/listener.go +++ b/p2p/transport/websocket/listener.go @@ -136,3 +136,7 @@ func (l *listener) Close() error { func (l *listener) Multiaddr() ma.Multiaddr { return l.laddr } + +func (l *listener) Multiaddrs() []ma.Multiaddr { + return []ma.Multiaddr{l.laddr} +} diff --git a/p2p/transport/websocket/websocket_test.go b/p2p/transport/websocket/websocket_test.go index 016dbe59..051c8064 100644 --- a/p2p/transport/websocket/websocket_test.go +++ b/p2p/transport/websocket/websocket_test.go @@ -190,7 +190,7 @@ func testWSSServer(t *testing.T, listenAddr ma.Multiaddr) (ma.Multiaddr, peer.ID close(errChan) }() - return l.Multiaddr(), id, errChan + return l.Multiaddrs()[0], id, errChan } func getTLSConf(t *testing.T, ip net.IP, start, end time.Time) *tls.Config { @@ -330,9 +330,9 @@ func connectAndExchangeData(t *testing.T, laddr ma.Multiaddr, secure bool) { l, err := tpt.Listen(laddr) require.NoError(t, err) if secure { - require.Contains(t, l.Multiaddr().String(), "tls") + require.Contains(t, l.Multiaddrs()[0].String(), "tls") } else { - require.Equal(t, lastComponent(t, l.Multiaddr()), wsComponent) + require.Equal(t, lastComponent(t, l.Multiaddrs()[0]), wsComponent) } defer l.Close() @@ -346,7 +346,7 @@ func connectAndExchangeData(t *testing.T, laddr ma.Multiaddr, secure bool) { _, u := newUpgrader(t) tpt, err := New(u, &network.NullResourceManager{}, opts...) require.NoError(t, err) - c, err := tpt.Dial(context.Background(), l.Multiaddr(), server) + c, err := tpt.Dial(context.Background(), l.Multiaddrs()[0], server) require.NoError(t, err) str, err := c.OpenStream(context.Background()) require.NoError(t, err) @@ -401,14 +401,14 @@ func TestWebsocketListenSecureAndInsecure(t *testing.T) { require.NoError(t, err) // dialing the insecure address should succeed - conn, err := client.Dial(context.Background(), lnInsecure.Multiaddr(), serverID) + conn, err := client.Dial(context.Background(), lnInsecure.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() require.Equal(t, lastComponent(t, conn.RemoteMultiaddr()).String(), wsComponent.String()) require.Equal(t, lastComponent(t, conn.LocalMultiaddr()).String(), wsComponent.String()) // dialing the secure address should fail - _, err = client.Dial(context.Background(), lnSecure.Multiaddr(), serverID) + _, err = client.Dial(context.Background(), lnSecure.Multiaddrs()[0], serverID) require.NoError(t, err) }) @@ -418,14 +418,14 @@ func TestWebsocketListenSecureAndInsecure(t *testing.T) { require.NoError(t, err) // dialing the insecure address should succeed - conn, err := client.Dial(context.Background(), lnSecure.Multiaddr(), serverID) + conn, err := client.Dial(context.Background(), lnSecure.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() require.Equal(t, lastComponent(t, conn.RemoteMultiaddr()), wssComponent) require.Equal(t, lastComponent(t, conn.LocalMultiaddr()), wssComponent) // dialing the insecure address should fail - _, err = client.Dial(context.Background(), lnInsecure.Multiaddr(), serverID) + _, err = client.Dial(context.Background(), lnInsecure.Multiaddrs()[0], serverID) require.NoError(t, err) }) } diff --git a/p2p/transport/webtransport/listener.go b/p2p/transport/webtransport/listener.go index a5fae40d..9a93d014 100644 --- a/p2p/transport/webtransport/listener.go +++ b/p2p/transport/webtransport/listener.go @@ -218,11 +218,11 @@ func (l *listener) Addr() net.Addr { return l.addr } -func (l *listener) Multiaddr() ma.Multiaddr { +func (l *listener) Multiaddrs() []ma.Multiaddr { if l.transport.certManager == nil { - return l.multiaddr + return []ma.Multiaddr{l.multiaddr} } - return l.multiaddr.Encapsulate(l.transport.certManager.AddrComponent()) + return []ma.Multiaddr{l.multiaddr.Encapsulate(l.transport.certManager.AddrComponent())} } func (l *listener) Close() error { diff --git a/p2p/transport/webtransport/transport_test.go b/p2p/transport/webtransport/transport_test.go index 70d4ec4b..3e856b25 100644 --- a/p2p/transport/webtransport/transport_test.go +++ b/p2p/transport/webtransport/transport_test.go @@ -114,7 +114,7 @@ func TestTransport(t *testing.T) { require.NoError(t, err) defer tr2.(io.Closer).Close() - conn, err := tr2.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := tr2.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) str, err := conn.OpenStream(context.Background()) require.NoError(t, err) @@ -123,7 +123,7 @@ func TestTransport(t *testing.T) { require.NoError(t, str.Close()) // check RemoteMultiaddr - _, addr, err := manet.DialArgs(ln.Multiaddr()) + _, addr, err := manet.DialArgs(ln.Multiaddrs()[0]) require.NoError(t, err) _, port, err := net.SplitHostPort(addr) require.NoError(t, err) @@ -167,14 +167,14 @@ func TestHashVerification(t *testing.T) { t.Run("fails using only a wrong hash", func(t *testing.T) { // replace the certificate hash in the multiaddr with a fake hash - addr := stripCertHashes(ln.Multiaddr()).Encapsulate(foobarHash) + addr := stripCertHashes(ln.Multiaddrs()[0]).Encapsulate(foobarHash) _, err := tr2.Dial(context.Background(), addr, serverID) require.Error(t, err) require.Contains(t, err.Error(), "CRYPTO_ERROR (0x12a): cert hash not found") }) t.Run("fails when adding a wrong hash", func(t *testing.T) { - _, err := tr2.Dial(context.Background(), ln.Multiaddr().Encapsulate(foobarHash), serverID) + _, err := tr2.Dial(context.Background(), ln.Multiaddrs()[0].Encapsulate(foobarHash), serverID) require.Error(t, err) }) @@ -248,9 +248,9 @@ func TestListenerAddrs(t *testing.T) { require.NoError(t, err) ln2, err := tr.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic/webtransport")) require.NoError(t, err) - hashes1 := extractCertHashes(ln1.Multiaddr()) + hashes1 := extractCertHashes(ln1.Multiaddrs()[0]) require.Len(t, hashes1, 2) - hashes2 := extractCertHashes(ln2.Multiaddr()) + hashes2 := extractCertHashes(ln2.Multiaddrs()[0]) require.Equal(t, hashes1, hashes2) } @@ -304,7 +304,7 @@ func TestResourceManagerListening(t *testing.T) { return nil, errors.New("denied") }) - _, err = cl.Dial(context.Background(), ln.Multiaddr(), serverID) + _, err = cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.EqualError(t, err, "received status 503") }) @@ -326,7 +326,7 @@ func TestResourceManagerListening(t *testing.T) { scope.EXPECT().Done().Do(func() { close(serverDone) }) // The handshake will complete, but the server will immediately close the connection. - conn, err := cl.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() clientDone := make(chan struct{}) @@ -365,13 +365,13 @@ func TestConnectionGaterDialing(t *testing.T) { defer ln.Close() connGater.EXPECT().InterceptSecured(network.DirOutbound, serverID, gomock.Any()).Do(func(_ network.Direction, _ peer.ID, addrs network.ConnMultiaddrs) { - require.Equal(t, stripCertHashes(ln.Multiaddr()), addrs.RemoteMultiaddr()) + require.Equal(t, stripCertHashes(ln.Multiaddrs()[0]), addrs.RemoteMultiaddr()) }) _, key := newIdentity(t) cl, err := libp2pwebtransport.New(key, connGater, &network.NullResourceManager{}) require.NoError(t, err) defer cl.(io.Closer).Close() - _, err = cl.Dial(context.Background(), ln.Multiaddr(), serverID) + _, err = cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.EqualError(t, err, "secured connection gated") } @@ -389,15 +389,15 @@ func TestConnectionGaterInterceptAccept(t *testing.T) { defer ln.Close() connGater.EXPECT().InterceptAccept(gomock.Any()).Do(func(addrs network.ConnMultiaddrs) { - require.Equal(t, stripCertHashes(ln.Multiaddr()), addrs.LocalMultiaddr()) - require.NotEqual(t, stripCertHashes(ln.Multiaddr()), addrs.RemoteMultiaddr()) + require.Equal(t, stripCertHashes(ln.Multiaddrs()[0]), addrs.LocalMultiaddr()) + require.NotEqual(t, stripCertHashes(ln.Multiaddrs()[0]), addrs.RemoteMultiaddr()) }) _, key := newIdentity(t) cl, err := libp2pwebtransport.New(key, nil, &network.NullResourceManager{}) require.NoError(t, err) defer cl.(io.Closer).Close() - _, err = cl.Dial(context.Background(), ln.Multiaddr(), serverID) + _, err = cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.EqualError(t, err, "received status 403") } @@ -421,11 +421,11 @@ func TestConnectionGaterInterceptSecured(t *testing.T) { connGater.EXPECT().InterceptAccept(gomock.Any()).Return(true) connGater.EXPECT().InterceptSecured(network.DirInbound, clientID, gomock.Any()).Do(func(_ network.Direction, _ peer.ID, addrs network.ConnMultiaddrs) { - require.Equal(t, stripCertHashes(ln.Multiaddr()), addrs.LocalMultiaddr()) - require.NotEqual(t, stripCertHashes(ln.Multiaddr()), addrs.RemoteMultiaddr()) + require.Equal(t, stripCertHashes(ln.Multiaddrs()[0]), addrs.LocalMultiaddr()) + require.NotEqual(t, stripCertHashes(ln.Multiaddrs()[0]), addrs.RemoteMultiaddr()) }) // The handshake will complete, but the server will immediately close the connection. - conn, err := cl.Dial(context.Background(), ln.Multiaddr(), serverID) + conn, err := cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() done := make(chan struct{}) @@ -479,7 +479,7 @@ func TestStaticTLSConf(t *testing.T) { ln, err := tr.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic/webtransport")) require.NoError(t, err) defer ln.Close() - require.Empty(t, extractCertHashes(ln.Multiaddr()), "listener address shouldn't contain any certhash") + require.Empty(t, extractCertHashes(ln.Multiaddrs()[0]), "listener address shouldn't contain any certhash") t.Run("fails when the certificate is invalid", func(t *testing.T) { _, key := newIdentity(t) @@ -487,7 +487,7 @@ func TestStaticTLSConf(t *testing.T) { require.NoError(t, err) defer cl.(io.Closer).Close() - _, err = cl.Dial(context.Background(), ln.Multiaddr(), serverID) + _, err = cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.Error(t, err) if !strings.Contains(err.Error(), "certificate is not trusted") && !strings.Contains(err.Error(), "certificate signed by unknown authority") { @@ -501,7 +501,7 @@ func TestStaticTLSConf(t *testing.T) { require.NoError(t, err) defer cl.(io.Closer).Close() - addr := ln.Multiaddr().Encapsulate(getCerthashComponent(t, []byte("foo"))) + addr := ln.Multiaddrs()[0].Encapsulate(getCerthashComponent(t, []byte("foo"))) _, err = cl.Dial(context.Background(), addr, serverID) require.Error(t, err) require.Contains(t, err.Error(), "cert hash not found") @@ -516,8 +516,8 @@ func TestStaticTLSConf(t *testing.T) { require.NoError(t, err) defer cl.(io.Closer).Close() - require.True(t, cl.CanDial(ln.Multiaddr())) - conn, err := cl.Dial(context.Background(), ln.Multiaddr(), serverID) + require.True(t, cl.CanDial(ln.Multiaddrs()[0])) + conn, err := cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) require.NoError(t, err) defer conn.Close() }) @@ -538,7 +538,7 @@ func TestAcceptQueueFilledUp(t *testing.T) { cl, err := libp2pwebtransport.New(key, nil, &network.NullResourceManager{}) require.NoError(t, err) defer cl.(io.Closer).Close() - return cl.Dial(context.Background(), ln.Multiaddr(), serverID) + return cl.Dial(context.Background(), ln.Multiaddrs()[0], serverID) } for i := 0; i < 16; i++ { @@ -577,7 +577,7 @@ func TestSNIIsSent(t *testing.T) { require.NoError(t, err) defer tr.(io.Closer).Close() - beforeQuicMa, withQuicMa := ma.SplitFunc(ln1.Multiaddr(), func(c ma.Component) bool { + beforeQuicMa, withQuicMa := ma.SplitFunc(ln1.Multiaddrs()[0], func(c ma.Component) bool { return c.Protocol().Code == ma.P_QUIC }) @@ -663,7 +663,7 @@ func TestFlowControlWindowIncrease(t *testing.T) { defer tr2.(io.Closer).Close() var addr ma.Multiaddr - for _, comp := range ma.Split(ln.Multiaddr()) { + for _, comp := range ma.Split(ln.Multiaddrs()[0]) { if _, err := comp.ValueForProtocol(ma.P_UDP); err == nil { addr = addr.Encapsulate(ma.StringCast(fmt.Sprintf("/udp/%d", proxy.LocalPort()))) continue