Unverified Commit ccc587ca authored by Lars Gierth's avatar Lars Gierth Committed by GitHub

Merge pull request #87 from libp2p/fix/known-undialables

Refactor and relax filtering of known undialable addresses
parents 67f7e372 0b06a5fe
......@@ -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