Skip to content

Commit

Permalink
Limit queue sizes in address resolution
Browse files Browse the repository at this point in the history
Limits the queue of addresses we are trying to resolve and addresses we
are returning
  • Loading branch information
MarcoPolo committed Oct 1, 2024
1 parent 987b5f7 commit 99d2253
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
23 changes: 21 additions & 2 deletions p2p/net/swarm/swarm_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions p2p/net/swarm/swarm_dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,18 @@ func TestBlackHoledAddrBlocked(t *testing.T) {
}
require.ErrorIs(t, err, ErrDialRefusedBlackHole)
}

func TestSkipDialingManyDNS(t *testing.T) {
resolver, err := madns.NewResolver()
if err != nil {
t.Fatal(err)
}
s := newTestSwarmWithResolver(t, resolver)
defer s.Close()
id := test.RandPeerIDFatal(t)
addr := ma.StringCast("/dns/example.com/udp/1234/p2p-circuit/dns/example.com/p2p-circuit/dns/example.com")

resolved, err := s.resolveAddrs(context.Background(), peer.AddrInfo{ID: id, Addrs: []ma.Multiaddr{addr}})
require.NoError(t, err)
require.Less(t, len(resolved), maximumResolvedAddresses)
}

0 comments on commit 99d2253

Please sign in to comment.