func pickLocalAddr(laddrs []ma.Multiaddr, raddr ma.Multiaddr) (laddr ma.Multiaddr) { if len(laddrs) < 1 { return nil } // make sure that we ONLY use local addrs that match the remote addr. laddrs = manet.AddrMatch(raddr, laddrs) if len(laddrs) < 1 { return nil } // make sure that we ONLY use local addrs that CAN dial the remote addr. // filter out all the local addrs that aren't capable raddrIPLayer := ma.Split(raddr)[0] raddrIsLoopback := manet.IsIPLoopback(raddrIPLayer) raddrIsLinkLocal := manet.IsIP6LinkLocal(raddrIPLayer) laddrs = addrutil.FilterAddrs(laddrs, func(a ma.Multiaddr) bool { laddrIPLayer := ma.Split(a)[0] laddrIsLoopback := manet.IsIPLoopback(laddrIPLayer) laddrIsLinkLocal := manet.IsIP6LinkLocal(laddrIPLayer) if laddrIsLoopback { // our loopback addrs can only dial loopbacks. return raddrIsLoopback } if laddrIsLinkLocal { return raddrIsLinkLocal // out linklocal addrs can only dial link locals. } return true }) // TODO pick with a good heuristic // we use a random one for now to prevent bad addresses from making nodes unreachable // with a random selection, multiple tries may work. return laddrs[rand.Intn(len(laddrs))] }
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link func AddrOverNonLocalIP(a ma.Multiaddr) bool { split := ma.Split(a) if len(split) < 1 { return false } if manet.IsIP6LinkLocal(split[0]) { return false } return true }
// AddrIsShareableOnWAN returns whether the given address should be shareable on the // wide area network (wide internet). func AddrIsShareableOnWAN(addr ma.Multiaddr) bool { s := ma.Split(addr) if len(s) < 1 { return false } a := s[0] if manet.IsIPLoopback(a) || manet.IsIP6LinkLocal(a) || manet.IsIPUnspecified(a) { return false } return manet.IsThinWaist(a) }