diff --git a/p2p/net/swarm/dial_worker.go b/p2p/net/swarm/dial_worker.go index 9d097f3c26..5bb9559e52 100644 --- a/p2p/net/swarm/dial_worker.go +++ b/p2p/net/swarm/dial_worker.go @@ -2,6 +2,7 @@ package swarm import ( "context" + "fmt" "math" "sync" "time" @@ -295,6 +296,9 @@ loop: } ad.dialed = true ad.dialRankingDelay = now.Sub(ad.createdAt) + if _, err := ad.addr.ValueForProtocol(ma.P_WEBRTC_DIRECT); err == nil { + fmt.Println("dial ranking delay", ad.addr, ad.dialRankingDelay) + } err := w.s.dialNextAddr(ad.ctx, w.peer, ad.addr, w.resch) if err != nil { // Errored without attempting a dial. This happens in case of diff --git a/p2p/test/basichost/basic_host_test.go b/p2p/test/basichost/basic_host_test.go index aa6ee688d0..78be7101ef 100644 --- a/p2p/test/basichost/basic_host_test.go +++ b/p2p/test/basichost/basic_host_test.go @@ -204,7 +204,7 @@ func TestAddrFactorCertHashAppend(t *testing.T) { }, 5*time.Second, 100*time.Millisecond) } -func TestWebRTCDirectDialDelay(t *testing.T) { +func TestOnlyWebRTCDirectDialNoDelay(t *testing.T) { // This tests that only webrtc-direct dials are dialled immediately // and not delayed by dial ranker. h1, err := libp2p.New( @@ -229,46 +229,49 @@ func TestWebRTCDirectDialDelay(t *testing.T) { func TestWebRTCWithQUICManyConnections(t *testing.T) { // Correctly fixes: https://github.com/libp2p/js-libp2p/issues/2805 + // The server has both /quic-v1 and /webrtc-direct listen addresses h, err := libp2p.New( libp2p.Transport(libp2pquic.NewTransport), libp2p.Transport(libp2pwebrtc.New), libp2p.ListenAddrStrings("/ip4/0.0.0.0/udp/0/quic-v1"), libp2p.ListenAddrStrings("/ip4/0.0.0.0/udp/0/webrtc-direct"), + libp2p.ResourceManager(&network.NullResourceManager{}), ) require.NoError(t, err) defer h.Close() - const N = 50 + const N = 200 + // These N dialers have both /quic-v1 and /webrtc-direct transports var dialers [N]host.Host for i := 0; i < N; i++ { dialers[i], err = libp2p.New(libp2p.NoListenAddrs) require.NoError(t, err) defer dialers[i].Close() } - // only webrtc dialer for dialing the peer later + // This dialer has only /webrtc-direct transport d, err := libp2p.New(libp2p.Transport(libp2pwebrtc.New), libp2p.NoListenAddrs) require.NoError(t, err) defer d.Close() - startDial := make(chan struct{}) var wg sync.WaitGroup wg.Add(N) for i := 0; i < N; i++ { go func() { defer wg.Done() - <-startDial ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - // it is fine if the dial fails, we just want to take up all the webrtc - // listen queue + // With happy eyeballs these dialers will connect over only /quic-v1 + // and not stall the /webrtc-direct handshake goroutines. + // it is fine if the dial fails, we just want to ensure that there's space + // in the /webrtc-direct listen queue _ = dialers[i].Connect(ctx, peer.AddrInfo{ID: h.ID(), Addrs: h.Addrs()}) }() } - close(startDial) wg.Wait() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() + // The webrtc only dialer should be able to connect to the peer err = d.Connect(ctx, peer.AddrInfo{ID: h.ID(), Addrs: h.Addrs()}) require.NoError(t, err) } diff --git a/p2p/transport/webrtc/listener.go b/p2p/transport/webrtc/listener.go index c3e2f29799..d105dc0305 100644 --- a/p2p/transport/webrtc/listener.go +++ b/p2p/transport/webrtc/listener.go @@ -126,7 +126,7 @@ func (l *listener) listen() { } return } - + fmt.Println("listener queue size: ", len(inFlightSemaphore), candidate.Addr, candidate.Ufrag) go func() { defer func() { <-inFlightSemaphore }() @@ -135,6 +135,7 @@ func (l *listener) listen() { conn, err := l.handleCandidate(ctx, candidate) if err != nil { + fmt.Println("dropping conn: ", len(inFlightSemaphore), candidate.Addr, candidate.Ufrag, err) l.mux.RemoveConnByUfrag(candidate.Ufrag) log.Debugf("could not accept connection: %s: %v", candidate.Ufrag, err) return