Commit 0b06a5fe authored by Lars Gierth's avatar Lars Gierth

Refactor and relax filtering of known undialable addresses

This commit moves filtering of dial candidates into its own little function.
Things that are being filtered: addresses configured to be blocked,
IPv6 link-local addresses, addresses without a dial-capable transport,
and addresses that we know to be our own. It's is an optimization to
avoid wasting time on dials that we know are going to fail.

This also relaxes the filtering of addresses that we consider our own.
Previously, any address would get filtered that's registered in peerstore
for or own PeerID. For e.g. /ip4/1.2.3.4/tcp/4001 that's fine, but for
ephemeral ports it can already cause problems.

In addition, now that go-libp2p-circuit is being fixed to handle its
multiaddrs slightly differently, /p2p-circuit addresses won't contain
the PeerID anymore. That means they stand for themselves, and would get
filtered too. (/p2p-circuit is the address we want to dial, but it's
also on of "our own addresses").

In the future we'd want to use the mafmt package here, and also consider
/quic, /ws, etc. addresses as our own.
parent 67f7e372
......@@ -281,42 +281,24 @@ func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) {
log.Debug("Dial not given PrivateKey, so WILL NOT SECURE conn.")
}
ila, _ := s.InterfaceListenAddresses()
subtractFilter := addrutil.SubtractFilter(append(ila, s.peers.Addrs(s.local)...)...)
// get live channel of addresses for peer, filtered by the given filters
/*
remoteAddrChan := s.peers.AddrsChan(ctx, p,
addrutil.AddrUsableFilter,
subtractFilter,
s.Filters.AddrBlocked)
*/
//////
/*
This code is temporary, the peerstore can currently provide
This slice-to-chan code is temporary, the peerstore can currently provide
a channel as an interface for receiving addresses, but more thought
needs to be put into the execution. For now, this allows us to use
the improved rate limiter, while maintaining the outward behaviour
that we previously had (halting a dial when we run out of addrs)
*/
paddrs := s.peers.Addrs(p)
goodAddrs := addrutil.FilterAddrs(paddrs,
subtractFilter,
s.canDial,
// TODO: Consider allowing this?
addrutil.AddrOverNonLocalIP,
addrutil.FilterNeg(s.Filters.AddrBlocked),
)
remoteAddrChan := make(chan ma.Multiaddr, len(goodAddrs))
goodAddrs := s.filterKnownUndialables(s.peers.Addrs(p))
goodAddrsChan := make(chan ma.Multiaddr, len(goodAddrs))
for _, a := range goodAddrs {
remoteAddrChan <- a
goodAddrsChan <- a
}
close(remoteAddrChan)
close(goodAddrsChan)
/////////
// try to get a connection to any addr
connC, err := s.dialAddrs(ctx, p, remoteAddrChan)
connC, err := s.dialAddrs(ctx, p, goodAddrsChan)
if err != nil {
logdial["error"] = err.Error()
return nil, err
......@@ -336,6 +318,31 @@ func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) {
return swarmC, nil
}
// filterKnownUndialables takes a list of multiaddrs, and removes those
// that we definitely don't want to dial: addresses configured to be blocked,
// IPv6 link-local addresses, addresses without a dial-capable transport,
// and addresses that we know to be our own.
// This is an optimization to avoid wasting time on dials that we know are going to fail.
func (s *Swarm) filterKnownUndialables(addrs []ma.Multiaddr) []ma.Multiaddr {
lisAddrs, _ := s.InterfaceListenAddresses()
var ourAddrs []ma.Multiaddr
for _, addr := range lisAddrs {
protos := addr.Protocols()
// we're only sure about filtering out /ip4 and /ip6 addresses, so far
if len(protos) == 2 && (protos[0].Code == ma.P_IP4 || protos[0].Code == ma.P_IP6) {
ourAddrs = append(ourAddrs, addr)
}
}
return addrutil.FilterAddrs(addrs,
addrutil.SubtractFilter(ourAddrs...),
s.canDial,
// TODO: Consider allowing link-local addresses
addrutil.AddrOverNonLocalIP,
addrutil.FilterNeg(s.Filters.AddrBlocked),
)
}
func (s *Swarm) dialAddrs(ctx context.Context, p peer.ID, remoteAddrs <-chan ma.Multiaddr) (transport.Conn, error) {
log.Debugf("%s swarm dialing %s", s.local, p)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment