From e13d89fbee047f97dffc6fed15232ef1349e3fef Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 1 Oct 2024 16:19:40 -0700 Subject: [PATCH] Limit queue sizes in address resolution Limits the queue of addresses we are trying to resolve and addresses we are returning --- p2p/net/swarm/swarm_dial.go | 23 +++++++++++++++++++++-- p2p/net/swarm/swarm_dial_test.go | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/p2p/net/swarm/swarm_dial.go b/p2p/net/swarm/swarm_dial.go index 446ece4504..7456b7f42d 100644 --- a/p2p/net/swarm/swarm_dial.go +++ b/p2p/net/swarm/swarm_dial.go @@ -22,9 +22,17 @@ import ( ) // The maximum number of address resolution steps we'll perform for a single -// peer (for all addresses). +// peer (for all addresses). In other words, the maximum number of times we'll +// call `.Resolve` for all of a peer's addresses const maxAddressResolution = 32 +// The maximum number of addresses we'll return when resolving all of a peer's +// address +const maximumResolvedAddresses = 100 + +// The maximum queue size of addresses left to resolve. +const maximumToResolveAddresses = 100 + // Diagram of dial sync: // // many callers of Dial() synched w. dials many addrs results to callers @@ -337,7 +345,7 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multia // * Otherwise, resolve it and add the results to the "to resolve" list. toResolve := append([]ma.Multiaddr{}, pi.Addrs...) resolved := make([]ma.Multiaddr, 0, len(pi.Addrs)) - for len(toResolve) > 0 { + for len(toResolve) > 0 && len(resolved) < maximumResolvedAddresses { // pop the last addr off. addr := toResolve[len(toResolve)-1] toResolve = toResolve[:len(toResolve)-1] @@ -372,6 +380,9 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multia } var added bool for _, a := range resolvedAddrs { + if len(toResolve) >= maximumToResolveAddresses { + break + } if !addr.Equal(a) { toResolve = append(toResolve, a) added = true @@ -382,6 +393,11 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multia } } + if len(toResolve) >= maximumToResolveAddresses { + // No point in resolving any more addresses, we don't have space. + continue + } + // otherwise, resolve it reqaddr := addr.Encapsulate(p2paddr) resaddrs, err := s.maResolver.Resolve(ctx, reqaddr) @@ -391,6 +407,9 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multia // add the results to the toResolve list. for _, res := range resaddrs { + if len(toResolve) >= maximumToResolveAddresses { + break + } pi, err := peer.AddrInfoFromP2pAddr(res) if err != nil { log.Infof("error parsing %s: %s", res, err) diff --git a/p2p/net/swarm/swarm_dial_test.go b/p2p/net/swarm/swarm_dial_test.go index bf7e7f4411..09989b6ee9 100644 --- a/p2p/net/swarm/swarm_dial_test.go +++ b/p2p/net/swarm/swarm_dial_test.go @@ -411,5 +411,5 @@ func TestSkipDialingManyDNS(t *testing.T) { resolved, err := s.resolveAddrs(context.Background(), peer.AddrInfo{ID: id, Addrs: []ma.Multiaddr{addr}}) require.NoError(t, err) - require.Zero(t, len(resolved)) + require.Less(t, len(resolved), maximumResolvedAddresses) }