Skip to content

Commit

Permalink
swarm: move back off handling outside worker loop
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt committed Jul 9, 2023
1 parent 87c2561 commit 6bcdc83
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 52 deletions.
33 changes: 6 additions & 27 deletions p2p/net/swarm/dial_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,16 +293,9 @@ loop:
}
ad.dialed = true
ad.dialRankingDelay = now.Sub(ad.createdAt)
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
// backoff or black hole.
w.dispatchError(ad, err)
} else {
// the dial was successful. update inflight dials
dialsInFlight++
totalDials++
}
w.s.limitedDial(ad.ctx, w.peer, ad.addr, w.resch)
dialsInFlight++
totalDials++
}
timerRunning = false
// schedule more dials
Expand Down Expand Up @@ -357,18 +350,12 @@ loop:
continue loop
}

// it must be an error -- add backoff if applicable and dispatch
// ErrDialRefusedBlackHole shouldn't end up here, just a safety check
if res.Err != ErrDialRefusedBlackHole && res.Err != context.Canceled && !w.connected {
// we only add backoff if there has not been a successful connection
// for consistency with the old dialer behavior.
// it must be an error -- add backoff if applicable
if res.Err != context.Canceled {
w.s.backf.AddBackoff(w.peer, res.Addr)
} else if res.Err == ErrDialRefusedBlackHole {
log.Errorf("SWARM BUG: unexpected ErrDialRefusedBlackHole while dialing peer %s to addr %s",
w.peer, res.Addr)
}

w.dispatchError(ad, res.Err)

// Only schedule next dial on error.
// If we scheduleNextDial on success, we will end up making one dial more than
// required because the final successful dial will spawn one more dial
Expand Down Expand Up @@ -406,14 +393,6 @@ func (w *dialWorker) dispatchError(ad *addrDial, err error) {
}

ad.requests = nil

// if it was a backoff, clear the address dial so that it doesn't inhibit new dial requests.
// this is necessary to support active listen scenarios, where a new dial comes in while
// another dial is in progress, and needs to do a direct connection without inhibitions from
// dial backoff.
if err == ErrDialBackoff {
delete(w.trackedDials, string(ad.addr.Bytes()))
}
}

// rankAddrs ranks addresses for dialing. if it's a simConnect request we
Expand Down
29 changes: 4 additions & 25 deletions p2p/net/swarm/swarm_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ const maxAddressResolution = 32
// retry dialAttempt x

var (
// ErrDialBackoff is returned by the backoff code when a given peer has
// been dialed too frequently
ErrDialBackoff = errors.New("dial backoff")

// ErrDialRefusedBlackHole is returned when we are in a black holed environment
ErrDialRefusedBlackHole = errors.New("dial refused because of black hole")

// ErrDialToSelf is returned if we attempt to dial our own peer
ErrDialToSelf = errors.New("dial to self attempted")

Expand Down Expand Up @@ -311,7 +304,7 @@ func (s *Swarm) addrsForDial(ctx context.Context, p peer.ID) ([]ma.Multiaddr, er
return nil, err
}

goodAddrs := s.filterKnownUndialables(p, resolved)
goodAddrs := s.filterKnownUndialables(ctx, p, resolved)
if forceDirect, _ := network.GetForceDirectDial(ctx); forceDirect {
goodAddrs = ma.FilterAddrs(goodAddrs, s.nonProxyAddr)
}
Expand Down Expand Up @@ -388,20 +381,6 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multia
return resolved, nil
}

func (s *Swarm) dialNextAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr, resch chan dialResult) error {
// check the dial backoff
if forceDirect, _ := network.GetForceDirectDial(ctx); !forceDirect {
if s.backf.Backoff(p, addr) {
return ErrDialBackoff
}
}

// start the dial
s.limitedDial(ctx, p, addr, resch)

return nil
}

func (s *Swarm) canDial(addr ma.Multiaddr) bool {
t := s.TransportForDialing(addr)
return t != nil && t.CanDial(addr)
Expand All @@ -418,7 +397,7 @@ func (s *Swarm) nonProxyAddr(addr ma.Multiaddr) bool {
// addresses that we know to be our own, and addresses with a better tranport
// available. This is an optimization to avoid wasting time on dials that we
// know are going to fail or for which we have a better alternative.
func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) []ma.Multiaddr {
func (s *Swarm) filterKnownUndialables(ctx context.Context, p peer.ID, addrs []ma.Multiaddr) []ma.Multiaddr {
lisAddrs, _ := s.InterfaceListenAddresses()
var ourAddrs []ma.Multiaddr
for _, addr := range lisAddrs {
Expand All @@ -430,21 +409,21 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) []ma.Mul
return false
})
}
forceDirect, _ := network.GetForceDirectDial(ctx)

// The order of these two filters is important. If we can only dial /webtransport,
// we don't want to filter /webtransport addresses out because the peer had a /quic-v1
// address

// filter addresses we cannot dial
addrs = ma.FilterAddrs(addrs, s.canDial)

// filter low priority addresses among the addresses we can dial
addrs = filterLowPriorityAddresses(addrs)

// remove black holed addrs
addrs = s.bhd.FilterAddrs(addrs)

return ma.FilterAddrs(addrs,
func(addr ma.Multiaddr) bool { return forceDirect || !s.backf.Backoff(p, addr) },
func(addr ma.Multiaddr) bool { return !ma.Contains(ourAddrs, addr) },
// TODO: Consider allowing link-local addresses
func(addr ma.Multiaddr) bool { return !manet.IsIP6LinkLocal(addr) },
Expand Down

0 comments on commit 6bcdc83

Please sign in to comment.