// AddAddressByIP adds an address where we are given an ip:port and not a // wire.NetAddress. func (a *AddrManager) AddAddressByIP(addrIP string) error { // Split IP and port addr, portStr, err := net.SplitHostPort(addrIP) if err != nil { return err } // Put it in wire.Netaddress var na wire.NetAddress na.Timestamp = time.Now() na.IP = net.ParseIP(addr) if na.IP == nil { return fmt.Errorf("invalid ip address %s", addr) } port, err := strconv.ParseUint(portStr, 10, 0) if err != nil { return fmt.Errorf("invalid port %s: %v", portStr, err) } na.Port = uint16(port) a.AddAddress(&na, &na) // XXX use correct src address return nil }
// GetBestLocalAddress returns the most appropriate local address to use // for the given remote address. func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.NetAddress { a.lamtx.Lock() defer a.lamtx.Unlock() bestreach := 0 var bestscore AddressPriority var bestAddress *wire.NetAddress for _, la := range a.localAddresses { reach := getReachabilityFrom(la.na, remoteAddr) if reach > bestreach || (reach == bestreach && la.score > bestscore) { bestreach = reach bestscore = la.score bestAddress = la.na } } if bestAddress != nil { log.Debugf("Suggesting address %s:%d for %s:%d", bestAddress.IP, bestAddress.Port, remoteAddr.IP, remoteAddr.Port) } else { log.Debugf("No worthy address for %s:%d", remoteAddr.IP, remoteAddr.Port) // Send something unroutable if nothing suitable. bestAddress = &wire.NetAddress{ Timestamp: time.Now(), Services: wire.SFNodeNetwork, Port: 0, } if !IsIPv4(remoteAddr) && !IsOnionCatTor(remoteAddr) { bestAddress.IP = net.IPv6zero } else { bestAddress.IP = net.IPv4zero } } return bestAddress }