1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
9 crand "crypto/rand" // for seeding
25 "github.com/btcsuite/btcd/chaincfg/chainhash"
26 "github.com/btcsuite/btcd/wire"
29 // AddrManager provides a concurrency safe address manager for caching potential
30 // peers on the bitcoin network.
31 type AddrManager struct {
34 lookupFunc func(string) ([]net.IP, error)
37 addrIndex map[string]*KnownAddress // address key to ka for all addrs.
38 addrNew [newBucketCount]map[string]*KnownAddress
39 addrTried [triedBucketCount]*list.List
47 localAddresses map[string]*localAddress
50 type serializedKnownAddress struct {
57 // no refcount or tried, that is available from context.
60 type serializedAddrManager struct {
63 Addresses []*serializedKnownAddress
64 NewBuckets [newBucketCount][]string // string is NetAddressKey
65 TriedBuckets [triedBucketCount][]string
68 type localAddress struct {
73 // AddressPriority type is used to describe the hierarchy of local address
75 type AddressPriority int
78 // InterfacePrio signifies the address is on a local interface
79 InterfacePrio AddressPriority = iota
81 // BoundPrio signifies the address has been explicitly bounded to.
84 // UpnpPrio signifies the address was obtained from UPnP.
87 // HTTPPrio signifies the address was obtained from an external HTTP service.
90 // ManualPrio signifies the address was provided by --externalip.
95 // needAddressThreshold is the number of addresses under which the
96 // address manager will claim to need more addresses.
97 needAddressThreshold = 1000
99 // dumpAddressInterval is the interval used to dump the address
100 // cache to disk for future use.
101 dumpAddressInterval = time.Minute * 10
103 // triedBucketSize is the maximum number of addresses in each
104 // tried address bucket.
105 triedBucketSize = 256
107 // triedBucketCount is the number of buckets we split tried
109 triedBucketCount = 64
111 // newBucketSize is the maximum number of addresses in each new address
115 // newBucketCount is the number of buckets that we spread new addresses
117 newBucketCount = 1024
119 // triedBucketsPerGroup is the number of tried buckets over which an
120 // address group will be spread.
121 triedBucketsPerGroup = 8
123 // newBucketsPerGroup is the number of new buckets over which an
124 // source address group will be spread.
125 newBucketsPerGroup = 64
127 // newBucketsPerAddress is the number of buckets a frequently seen new
128 // address may end up in.
129 newBucketsPerAddress = 8
131 // numMissingDays is the number of days before which we assume an
132 // address has vanished if we have not seen it announced in that long.
135 // numRetries is the number of tried without a single success before
136 // we assume an address is bad.
139 // maxFailures is the maximum number of failures we will accept without
140 // a success before considering an address bad.
143 // minBadDays is the number of days since the last success before we
144 // will consider evicting an address.
147 // getAddrMax is the most addresses that we will send in response
148 // to a getAddr (in practise the most addresses we will return from a
149 // call to AddressCache()).
152 // getAddrPercent is the percentage of total addresses known that we
153 // will share with a call to AddressCache.
156 // serialisationVersion is the current version of the on-disk format.
157 serialisationVersion = 1
160 // updateAddress is a helper function to either update an address already known
161 // to the address manager, or to add the address if not already known.
162 func (a *AddrManager) updateAddress(netAddr, srcAddr *wire.NetAddress) {
163 // Filter out non-routable addresses. Note that non-routable
164 // also includes invalid and local addresses.
165 if !IsRoutable(netAddr) {
169 addr := NetAddressKey(netAddr)
170 ka := a.find(netAddr)
172 // TODO: only update addresses periodically.
173 // Update the last seen time and services.
174 // note that to prevent causing excess garbage on getaddr
175 // messages the netaddresses in addrmaanger are *immutable*,
176 // if we need to change them then we replace the pointer with a
177 // new copy so that we don't have to copy every na for getaddr.
178 if netAddr.Timestamp.After(ka.na.Timestamp) ||
179 (ka.na.Services&netAddr.Services) !=
183 naCopy.Timestamp = netAddr.Timestamp
184 naCopy.AddService(netAddr.Services)
188 // If already in tried, we have nothing to do here.
193 // Already at our max?
194 if ka.refs == newBucketsPerAddress {
198 // The more entries we have, the less likely we are to add more.
200 factor := int32(2 * ka.refs)
201 if a.rand.Int31n(factor) != 0 {
205 // Make a copy of the net address to avoid races since it is
206 // updated elsewhere in the addrmanager code and would otherwise
207 // change the actual netaddress on the peer.
208 netAddrCopy := *netAddr
209 ka = &KnownAddress{na: &netAddrCopy, srcAddr: srcAddr}
210 a.addrIndex[addr] = ka
215 bucket := a.getNewBucket(netAddr, srcAddr)
218 if _, ok := a.addrNew[bucket][addr]; ok {
222 // Enforce max addresses.
223 if len(a.addrNew[bucket]) > newBucketSize {
224 log.Tracef("new bucket is full, expiring old")
228 // Add to new bucket.
230 a.addrNew[bucket][addr] = ka
232 log.Tracef("Added new address %s for a total of %d addresses", addr,
236 // expireNew makes space in the new buckets by expiring the really bad entries.
237 // If no bad entries are available we look at a few and remove the oldest.
238 func (a *AddrManager) expireNew(bucket int) {
239 // First see if there are any entries that are so bad we can just throw
240 // them away. otherwise we throw away the oldest entry in the cache.
241 // Bitcoind here chooses four random and just throws the oldest of
242 // those away, but we keep track of oldest in the initial traversal and
243 // use that information instead.
244 var oldest *KnownAddress
245 for k, v := range a.addrNew[bucket] {
247 log.Tracef("expiring bad address %v", k)
248 delete(a.addrNew[bucket], k)
252 delete(a.addrIndex, k)
258 } else if !v.na.Timestamp.After(oldest.na.Timestamp) {
264 key := NetAddressKey(oldest.na)
265 log.Tracef("expiring oldest address %v", key)
267 delete(a.addrNew[bucket], key)
269 if oldest.refs == 0 {
271 delete(a.addrIndex, key)
276 // pickTried selects an address from the tried bucket to be evicted.
277 // We just choose the eldest. Bitcoind selects 4 random entries and throws away
278 // the older of them.
279 func (a *AddrManager) pickTried(bucket int) *list.Element {
280 var oldest *KnownAddress
281 var oldestElem *list.Element
282 for e := a.addrTried[bucket].Front(); e != nil; e = e.Next() {
283 ka := e.Value.(*KnownAddress)
284 if oldest == nil || oldest.na.Timestamp.After(ka.na.Timestamp) {
293 func (a *AddrManager) getNewBucket(netAddr, srcAddr *wire.NetAddress) int {
295 // doublesha256(key + sourcegroup + int64(doublesha256(key + group + sourcegroup))%bucket_per_source_group) % num_new_buckets
298 data1 = append(data1, a.key[:]...)
299 data1 = append(data1, []byte(GroupKey(netAddr))...)
300 data1 = append(data1, []byte(GroupKey(srcAddr))...)
301 hash1 := chainhash.DoubleHashB(data1)
302 hash64 := binary.LittleEndian.Uint64(hash1)
303 hash64 %= newBucketsPerGroup
305 binary.LittleEndian.PutUint64(hashbuf[:], hash64)
307 data2 = append(data2, a.key[:]...)
308 data2 = append(data2, GroupKey(srcAddr)...)
309 data2 = append(data2, hashbuf[:]...)
311 hash2 := chainhash.DoubleHashB(data2)
312 return int(binary.LittleEndian.Uint64(hash2) % newBucketCount)
315 func (a *AddrManager) getTriedBucket(netAddr *wire.NetAddress) int {
316 // bitcoind hashes this as:
317 // doublesha256(key + group + truncate_to_64bits(doublesha256(key)) % buckets_per_group) % num_buckets
319 data1 = append(data1, a.key[:]...)
320 data1 = append(data1, []byte(NetAddressKey(netAddr))...)
321 hash1 := chainhash.DoubleHashB(data1)
322 hash64 := binary.LittleEndian.Uint64(hash1)
323 hash64 %= triedBucketsPerGroup
325 binary.LittleEndian.PutUint64(hashbuf[:], hash64)
327 data2 = append(data2, a.key[:]...)
328 data2 = append(data2, GroupKey(netAddr)...)
329 data2 = append(data2, hashbuf[:]...)
331 hash2 := chainhash.DoubleHashB(data2)
332 return int(binary.LittleEndian.Uint64(hash2) % triedBucketCount)
335 // addressHandler is the main handler for the address manager. It must be run
337 func (a *AddrManager) addressHandler() {
338 dumpAddressTicker := time.NewTicker(dumpAddressInterval)
339 defer dumpAddressTicker.Stop()
343 case <-dumpAddressTicker.C:
352 log.Trace("Address handler done")
355 // savePeers saves all the known addresses to a file so they can be read back
357 func (a *AddrManager) savePeers() {
361 // First we make a serialisable datastructure so we can encode it to
363 sam := new(serializedAddrManager)
364 sam.Version = serialisationVersion
365 copy(sam.Key[:], a.key[:])
367 sam.Addresses = make([]*serializedKnownAddress, len(a.addrIndex))
369 for k, v := range a.addrIndex {
370 ska := new(serializedKnownAddress)
372 ska.TimeStamp = v.na.Timestamp.Unix()
373 ska.Src = NetAddressKey(v.srcAddr)
374 ska.Attempts = v.attempts
375 ska.LastAttempt = v.lastattempt.Unix()
376 ska.LastSuccess = v.lastsuccess.Unix()
377 // Tried and refs are implicit in the rest of the structure
378 // and will be worked out from context on unserialisation.
379 sam.Addresses[i] = ska
382 for i := range a.addrNew {
383 sam.NewBuckets[i] = make([]string, len(a.addrNew[i]))
385 for k := range a.addrNew[i] {
386 sam.NewBuckets[i][j] = k
390 for i := range a.addrTried {
391 sam.TriedBuckets[i] = make([]string, a.addrTried[i].Len())
393 for e := a.addrTried[i].Front(); e != nil; e = e.Next() {
394 ka := e.Value.(*KnownAddress)
395 sam.TriedBuckets[i][j] = NetAddressKey(ka.na)
400 w, err := os.Create(a.peersFile)
402 log.Errorf("Error opening file %s: %v", a.peersFile, err)
405 enc := json.NewEncoder(w)
407 if err := enc.Encode(&sam); err != nil {
408 log.Errorf("Failed to encode file %s: %v", a.peersFile, err)
413 // loadPeers loads the known address from the saved file. If empty, missing, or
414 // malformed file, just don't load anything and start fresh
415 func (a *AddrManager) loadPeers() {
419 err := a.deserializePeers(a.peersFile)
421 log.Errorf("Failed to parse file %s: %v", a.peersFile, err)
422 // if it is invalid we nuke the old one unconditionally.
423 err = os.Remove(a.peersFile)
425 log.Warnf("Failed to remove corrupt peers file %s: %v",
431 log.Infof("Loaded %d addresses from file '%s'", a.numAddresses(), a.peersFile)
434 func (a *AddrManager) deserializePeers(filePath string) error {
436 _, err := os.Stat(filePath)
437 if os.IsNotExist(err) {
440 r, err := os.Open(filePath)
442 return fmt.Errorf("%s error opening file: %v", filePath, err)
446 var sam serializedAddrManager
447 dec := json.NewDecoder(r)
448 err = dec.Decode(&sam)
450 return fmt.Errorf("error reading %s: %v", filePath, err)
453 if sam.Version != serialisationVersion {
454 return fmt.Errorf("unknown version %v in serialized "+
455 "addrmanager", sam.Version)
457 copy(a.key[:], sam.Key[:])
459 for _, v := range sam.Addresses {
460 ka := new(KnownAddress)
461 ka.na, err = a.DeserializeNetAddress(v.Addr)
463 return fmt.Errorf("failed to deserialize netaddress "+
464 "%s: %v", v.Addr, err)
466 ka.srcAddr, err = a.DeserializeNetAddress(v.Src)
468 return fmt.Errorf("failed to deserialize netaddress "+
469 "%s: %v", v.Src, err)
471 ka.attempts = v.Attempts
472 ka.lastattempt = time.Unix(v.LastAttempt, 0)
473 ka.lastsuccess = time.Unix(v.LastSuccess, 0)
474 a.addrIndex[NetAddressKey(ka.na)] = ka
477 for i := range sam.NewBuckets {
478 for _, val := range sam.NewBuckets[i] {
479 ka, ok := a.addrIndex[val]
481 return fmt.Errorf("newbucket contains %s but "+
482 "none in address list", val)
489 a.addrNew[i][val] = ka
492 for i := range sam.TriedBuckets {
493 for _, val := range sam.TriedBuckets[i] {
494 ka, ok := a.addrIndex[val]
496 return fmt.Errorf("Newbucket contains %s but "+
497 "none in address list", val)
502 a.addrTried[i].PushBack(ka)
507 for k, v := range a.addrIndex {
508 if v.refs == 0 && !v.tried {
509 return fmt.Errorf("address %s after serialisation "+
510 "with no references", k)
513 if v.refs > 0 && v.tried {
514 return fmt.Errorf("address %s after serialisation "+
515 "which is both new and tried!", k)
522 // DeserializeNetAddress converts a given address string to a *wire.NetAddress
523 func (a *AddrManager) DeserializeNetAddress(addr string) (*wire.NetAddress, error) {
524 host, portStr, err := net.SplitHostPort(addr)
528 port, err := strconv.ParseUint(portStr, 10, 16)
533 return a.HostToNetAddress(host, uint16(port), wire.SFNodeNetwork)
536 // Start begins the core address handler which manages a pool of known
537 // addresses, timeouts, and interval based writes.
538 func (a *AddrManager) Start() {
540 if atomic.AddInt32(&a.started, 1) != 1 {
544 log.Trace("Starting address manager")
546 // Load peers we already know about from file.
549 // Start the address ticker to save addresses periodically.
551 go a.addressHandler()
554 // Stop gracefully shuts down the address manager by stopping the main handler.
555 func (a *AddrManager) Stop() error {
556 if atomic.AddInt32(&a.shutdown, 1) != 1 {
557 log.Warnf("Address manager is already in the process of " +
562 log.Infof("Address manager shutting down")
568 // AddAddresses adds new addresses to the address manager. It enforces a max
569 // number of addresses and silently ignores duplicate addresses. It is
570 // safe for concurrent access.
571 func (a *AddrManager) AddAddresses(addrs []*wire.NetAddress, srcAddr *wire.NetAddress) {
575 for _, na := range addrs {
576 a.updateAddress(na, srcAddr)
580 // AddAddress adds a new address to the address manager. It enforces a max
581 // number of addresses and silently ignores duplicate addresses. It is
582 // safe for concurrent access.
583 func (a *AddrManager) AddAddress(addr, srcAddr *wire.NetAddress) {
587 a.updateAddress(addr, srcAddr)
590 // AddAddressByIP adds an address where we are given an ip:port and not a
592 func (a *AddrManager) AddAddressByIP(addrIP string) error {
594 addr, portStr, err := net.SplitHostPort(addrIP)
598 // Put it in wire.Netaddress
599 ip := net.ParseIP(addr)
601 return fmt.Errorf("invalid ip address %s", addr)
603 port, err := strconv.ParseUint(portStr, 10, 0)
605 return fmt.Errorf("invalid port %s: %v", portStr, err)
607 na := wire.NewNetAddressIPPort(ip, uint16(port), 0)
608 a.AddAddress(na, na) // XXX use correct src address
612 // NumAddresses returns the number of addresses known to the address manager.
613 func (a *AddrManager) numAddresses() int {
614 return a.nTried + a.nNew
617 // NumAddresses returns the number of addresses known to the address manager.
618 func (a *AddrManager) NumAddresses() int {
622 return a.numAddresses()
625 // NeedMoreAddresses returns whether or not the address manager needs more
627 func (a *AddrManager) NeedMoreAddresses() bool {
631 return a.numAddresses() < needAddressThreshold
634 // AddressCache returns the current address cache. It must be treated as
635 // read-only (but since it is a copy now, this is not as dangerous).
636 func (a *AddrManager) AddressCache() []*wire.NetAddress {
640 addrIndexLen := len(a.addrIndex)
641 if addrIndexLen == 0 {
645 allAddr := make([]*wire.NetAddress, 0, addrIndexLen)
646 // Iteration order is undefined here, but we randomise it anyway.
647 for _, v := range a.addrIndex {
648 allAddr = append(allAddr, v.na)
651 numAddresses := addrIndexLen * getAddrPercent / 100
652 if numAddresses > getAddrMax {
653 numAddresses = getAddrMax
656 // Fisher-Yates shuffle the array. We only need to do the first
657 // `numAddresses' since we are throwing the rest.
658 for i := 0; i < numAddresses; i++ {
659 // pick a number between current index and the end
660 j := rand.Intn(addrIndexLen-i) + i
661 allAddr[i], allAddr[j] = allAddr[j], allAddr[i]
664 // slice off the limit we are willing to share.
665 return allAddr[0:numAddresses]
668 // reset resets the address manager by reinitialising the random source
669 // and allocating fresh empty bucket storage.
670 func (a *AddrManager) reset() {
672 a.addrIndex = make(map[string]*KnownAddress)
674 // fill key with bytes from a good random source.
675 io.ReadFull(crand.Reader, a.key[:])
676 for i := range a.addrNew {
677 a.addrNew[i] = make(map[string]*KnownAddress)
679 for i := range a.addrTried {
680 a.addrTried[i] = list.New()
684 // HostToNetAddress returns a netaddress given a host address. If the address
685 // is a Tor .onion address this will be taken care of. Else if the host is
686 // not an IP address it will be resolved (via Tor if required).
687 func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.ServiceFlag) (*wire.NetAddress, error) {
688 // Tor address is 16 char base32 + ".onion"
690 if len(host) == 22 && host[16:] == ".onion" {
691 // go base32 encoding uses capitals (as does the rfc
692 // but Tor and bitcoind tend to user lowercase, so we switch
694 data, err := base32.StdEncoding.DecodeString(
695 strings.ToUpper(host[:16]))
699 prefix := []byte{0xfd, 0x87, 0xd8, 0x7e, 0xeb, 0x43}
700 ip = net.IP(append(prefix, data...))
701 } else if ip = net.ParseIP(host); ip == nil {
702 ips, err := a.lookupFunc(host)
707 return nil, fmt.Errorf("no addresses found for %s", host)
712 return wire.NewNetAddressIPPort(ip, port, services), nil
715 // ipString returns a string for the ip from the provided NetAddress. If the
716 // ip is in the range used for Tor addresses then it will be transformed into
717 // the relevant .onion address.
718 func ipString(na *wire.NetAddress) string {
719 if IsOnionCatTor(na) {
720 // We know now that na.IP is long enough.
721 base32 := base32.StdEncoding.EncodeToString(na.IP[6:])
722 return strings.ToLower(base32) + ".onion"
725 return na.IP.String()
728 // NetAddressKey returns a string key in the form of ip:port for IPv4 addresses
729 // or [ip]:port for IPv6 addresses.
730 func NetAddressKey(na *wire.NetAddress) string {
731 port := strconv.FormatUint(uint64(na.Port), 10)
733 return net.JoinHostPort(ipString(na), port)
736 // GetAddress returns a single address that should be routable. It picks a
737 // random one from the possible addresses with preference given to ones that
738 // have not been used recently and should not pick 'close' addresses
740 func (a *AddrManager) GetAddress() *KnownAddress {
741 // Protect concurrent access.
745 if a.numAddresses() == 0 {
749 // Use a 50% chance for choosing between tried and new table entries.
750 if a.nTried > 0 && (a.nNew == 0 || a.rand.Intn(2) == 0) {
755 // pick a random bucket.
756 bucket := a.rand.Intn(len(a.addrTried))
757 if a.addrTried[bucket].Len() == 0 {
761 // Pick a random entry in the list
762 e := a.addrTried[bucket].Front()
764 a.rand.Int63n(int64(a.addrTried[bucket].Len())); i > 0; i-- {
767 ka := e.Value.(*KnownAddress)
768 randval := a.rand.Intn(large)
769 if float64(randval) < (factor * ka.chance() * float64(large)) {
770 log.Tracef("Selected %v from tried bucket",
771 NetAddressKey(ka.na))
778 // XXX use a closure/function to avoid repeating this.
782 // Pick a random bucket.
783 bucket := a.rand.Intn(len(a.addrNew))
784 if len(a.addrNew[bucket]) == 0 {
787 // Then, a random entry in it.
789 nth := a.rand.Intn(len(a.addrNew[bucket]))
790 for _, value := range a.addrNew[bucket] {
796 randval := a.rand.Intn(large)
797 if float64(randval) < (factor * ka.chance() * float64(large)) {
798 log.Tracef("Selected %v from new bucket",
799 NetAddressKey(ka.na))
807 func (a *AddrManager) find(addr *wire.NetAddress) *KnownAddress {
808 return a.addrIndex[NetAddressKey(addr)]
811 // Attempt increases the given address' attempt counter and updates
812 // the last attempt time.
813 func (a *AddrManager) Attempt(addr *wire.NetAddress) {
818 // Surely address will be in tried by now?
823 // set last tried time to now
825 ka.lastattempt = time.Now()
828 // Connected Marks the given address as currently connected and working at the
829 // current time. The address must already be known to AddrManager else it will
831 func (a *AddrManager) Connected(addr *wire.NetAddress) {
840 // Update the time as long as it has been 20 minutes since last we did
843 if now.After(ka.na.Timestamp.Add(time.Minute * 20)) {
844 // ka.na is immutable, so replace it.
846 naCopy.Timestamp = time.Now()
851 // Good marks the given address as good. To be called after a successful
852 // connection and version exchange. If the address is unknown to the address
853 // manager it will be ignored.
854 func (a *AddrManager) Good(addr *wire.NetAddress) {
863 // ka.Timestamp is not updated here to avoid leaking information
864 // about currently connected peers.
870 // move to tried set, optionally evicting other addresses if neeed.
875 // ok, need to move it to tried.
877 // remove from all new buckets.
878 // record one of the buckets in question and call it the `first'
879 addrKey := NetAddressKey(addr)
881 for i := range a.addrNew {
882 // we check for existence so we can record the first one
883 if _, ok := a.addrNew[i][addrKey]; ok {
884 delete(a.addrNew[i], addrKey)
894 // What? wasn't in a bucket after all.... Panic?
898 bucket := a.getTriedBucket(ka.na)
900 // Room in this tried bucket?
901 if a.addrTried[bucket].Len() < triedBucketSize {
903 a.addrTried[bucket].PushBack(ka)
908 // No room, we have to evict something else.
909 entry := a.pickTried(bucket)
910 rmka := entry.Value.(*KnownAddress)
912 // First bucket it would have been put in.
913 newBucket := a.getNewBucket(rmka.na, rmka.srcAddr)
915 // If no room in the original bucket, we put it in a bucket we just
916 // freed up a space in.
917 if len(a.addrNew[newBucket]) >= newBucketSize {
918 newBucket = oldBucket
921 // replace with ka in list.
928 // We don't touch a.nTried here since the number of tried stays the same
929 // but we decemented new above, raise it again since we're putting
933 rmkey := NetAddressKey(rmka.na)
934 log.Tracef("Replacing %s with %s in tried", rmkey, addrKey)
936 // We made sure there is space here just above.
937 a.addrNew[newBucket][rmkey] = rmka
940 // AddLocalAddress adds na to the list of known local addresses to advertise
941 // with the given priority.
942 func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error {
944 return fmt.Errorf("address %s is not routable", na.IP)
948 defer a.lamtx.Unlock()
950 key := NetAddressKey(na)
951 la, ok := a.localAddresses[key]
952 if !ok || la.score < priority {
954 la.score = priority + 1
956 a.localAddresses[key] = &localAddress{
965 // getReachabilityFrom returns the relative reachability of the provided local
966 // address to the provided remote address.
967 func getReachabilityFrom(localAddr, remoteAddr *wire.NetAddress) int {
978 if !IsRoutable(remoteAddr) {
982 if IsOnionCatTor(remoteAddr) {
983 if IsOnionCatTor(localAddr) {
987 if IsRoutable(localAddr) && IsIPv4(localAddr) {
994 if IsRFC4380(remoteAddr) {
995 if !IsRoutable(localAddr) {
999 if IsRFC4380(localAddr) {
1003 if IsIPv4(localAddr) {
1010 if IsIPv4(remoteAddr) {
1011 if IsRoutable(localAddr) && IsIPv4(localAddr) {
1019 // Is our v6 is tunnelled?
1020 if IsRFC3964(localAddr) || IsRFC6052(localAddr) || IsRFC6145(localAddr) {
1024 if !IsRoutable(localAddr) {
1028 if IsRFC4380(localAddr) {
1032 if IsIPv4(localAddr) {
1037 // only prioritise ipv6 if we aren't tunnelling it.
1044 // GetBestLocalAddress returns the most appropriate local address to use
1045 // for the given remote address.
1046 func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.NetAddress {
1048 defer a.lamtx.Unlock()
1051 var bestscore AddressPriority
1052 var bestAddress *wire.NetAddress
1053 for _, la := range a.localAddresses {
1054 reach := getReachabilityFrom(la.na, remoteAddr)
1055 if reach > bestreach ||
1056 (reach == bestreach && la.score > bestscore) {
1058 bestscore = la.score
1062 if bestAddress != nil {
1063 log.Debugf("Suggesting address %s:%d for %s:%d", bestAddress.IP,
1064 bestAddress.Port, remoteAddr.IP, remoteAddr.Port)
1066 log.Debugf("No worthy address for %s:%d", remoteAddr.IP,
1069 // Send something unroutable if nothing suitable.
1071 if !IsIPv4(remoteAddr) && !IsOnionCatTor(remoteAddr) {
1076 services := wire.SFNodeNetwork | wire.SFNodeWitness | wire.SFNodeBloom
1077 bestAddress = wire.NewNetAddressIPPort(ip, 0, services)
1083 // New returns a new bitcoin address manager.
1084 // Use Start to begin processing asynchronous address updates.
1085 func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager {
1087 peersFile: filepath.Join(dataDir, "peers.json"),
1088 lookupFunc: lookupFunc,
1089 rand: rand.New(rand.NewSource(time.Now().UnixNano())),
1090 quit: make(chan struct{}),
1091 localAddresses: make(map[string]*localAddress),