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))] }
// 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) }
func (al AddrList) Less(i, j int) bool { a := al[i] b := al[j] // dial localhost addresses next, they should fail immediately lba := manet.IsIPLoopback(a) lbb := manet.IsIPLoopback(b) if lba { if !lbb { return true } } // dial utp and similar 'non-fd-consuming' addresses first fda := isFDCostlyTransport(a) fdb := isFDCostlyTransport(b) if !fda { if fdb { return true } // if neither consume fd's, assume equal ordering return false } // if 'b' doesnt take a file descriptor if !fdb { return false } // if 'b' is loopback and both take file descriptors if lbb { return false } // for the rest, just sort by bytes return bytes.Compare(a.Bytes(), b.Bytes()) > 0 }
func localAddresses() []ma.Multiaddr { maddrs, err := manet.InterfaceMultiaddrs() if err != nil { die(err) } if !hideLoopback { return maddrs } var maddrs2 []ma.Multiaddr for _, a := range maddrs { if !manet.IsIPLoopback(a) { maddrs2 = append(maddrs2, a) } } return maddrs2 }