Documentation

Overview

Package addrmgr implements concurrency safe Bitcoin Cash address manager.

Address Manager Overview

In order maintain the peer-to-peer Bitcoin Cash network, there needs to be a source of addresses to connect to as nodes come and go. The Bitcoin Cash protocol provides the getaddr and addr messages to allow peers to communicate known addresses with each other. However, there needs to a mechanism to store those results and select peers from them. It is also important to note that remote peers can't be trusted to send valid peers nor attempt to provide you with only peers they control with malicious intent.

With that in mind, this package provides a concurrency safe address manager for caching and selecting peers in a non-deterministic manner. The general idea is the caller adds addresses to the address manager and notifies it when addresses are connected, known good, and attempted. The caller also requests addresses as it needs them.

The address manager internally segregates the addresses into groups and non-deterministically selects groups in a cryptographically random manner. This reduce the chances multiple addresses from the same nets are selected which generally helps provide greater peer diversity, and perhaps more importantly, drastically reduces the chances an attacker is able to coerce your peer into only connecting to nodes they control.

The address manager also understands routability and Tor addresses and tries hard to only return routable addresses. In addition, it uses the information provided by the caller about connected, known good, and attempted addresses to periodically purge peers which no longer appear to be good peers as well as bias the selection toward known good peers. The general idea is to make a best effort at only providing usable addresses.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DisableLog

func DisableLog()

    DisableLog disables all library log output. Logging output is disabled by default until either UseLogger or SetLogWriter are called.

    func GroupKey

    func GroupKey(na *wire.NetAddress) string

      GroupKey returns a string representing the network group an address is part of. This is the /16 for IPv4, the /32 (/36 for he.net) for IPv6, the string "local" for a local address, the string "tor:key" where key is the /4 of the onion address for Tor address, and the string "unroutable" for an unroutable address.

      func IsIPv4

      func IsIPv4(na *wire.NetAddress) bool

        IsIPv4 returns whether or not the given address is an IPv4 address.

        func IsLocal

        func IsLocal(na *wire.NetAddress) bool

          IsLocal returns whether or not the given address is a local address.

          func IsOnionCatTor

          func IsOnionCatTor(na *wire.NetAddress) bool

            IsOnionCatTor returns whether or not the passed address is in the IPv6 range used by bitcoin to support Tor (fd87:d87e:eb43::/48). Note that this range is the same range used by OnionCat, which is part of the RFC4193 unique local IPv6 range.

            func IsRFC1918

            func IsRFC1918(na *wire.NetAddress) bool

              IsRFC1918 returns whether or not the passed address is part of the IPv4 private network address space as defined by RFC1918 (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16).

              func IsRFC2544

              func IsRFC2544(na *wire.NetAddress) bool

                IsRFC2544 returns whether or not the passed address is part of the IPv4 address space as defined by RFC2544 (198.18.0.0/15)

                func IsRFC3849

                func IsRFC3849(na *wire.NetAddress) bool

                  IsRFC3849 returns whether or not the passed address is part of the IPv6 documentation range as defined by RFC3849 (2001:DB8::/32).

                  func IsRFC3927

                  func IsRFC3927(na *wire.NetAddress) bool

                    IsRFC3927 returns whether or not the passed address is part of the IPv4 autoconfiguration range as defined by RFC3927 (169.254.0.0/16).

                    func IsRFC3964

                    func IsRFC3964(na *wire.NetAddress) bool

                      IsRFC3964 returns whether or not the passed address is part of the IPv6 to IPv4 encapsulation range as defined by RFC3964 (2002::/16).

                      func IsRFC4193

                      func IsRFC4193(na *wire.NetAddress) bool

                        IsRFC4193 returns whether or not the passed address is part of the IPv6 unique local range as defined by RFC4193 (FC00::/7).

                        func IsRFC4380

                        func IsRFC4380(na *wire.NetAddress) bool

                          IsRFC4380 returns whether or not the passed address is part of the IPv6 teredo tunneling over UDP range as defined by RFC4380 (2001::/32).

                          func IsRFC4843

                          func IsRFC4843(na *wire.NetAddress) bool

                            IsRFC4843 returns whether or not the passed address is part of the IPv6 ORCHID range as defined by RFC4843 (2001:10::/28).

                            func IsRFC4862

                            func IsRFC4862(na *wire.NetAddress) bool

                              IsRFC4862 returns whether or not the passed address is part of the IPv6 stateless address autoconfiguration range as defined by RFC4862 (FE80::/64).

                              func IsRFC5737

                              func IsRFC5737(na *wire.NetAddress) bool

                                IsRFC5737 returns whether or not the passed address is part of the IPv4 documentation address space as defined by RFC5737 (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)

                                func IsRFC6052

                                func IsRFC6052(na *wire.NetAddress) bool

                                  IsRFC6052 returns whether or not the passed address is part of the IPv6 well-known prefix range as defined by RFC6052 (64:FF9B::/96).

                                  func IsRFC6145

                                  func IsRFC6145(na *wire.NetAddress) bool

                                    IsRFC6145 returns whether or not the passed address is part of the IPv6 to IPv4 translated address range as defined by RFC6145 (::FFFF:0:0:0/96).

                                    func IsRFC6598

                                    func IsRFC6598(na *wire.NetAddress) bool

                                      IsRFC6598 returns whether or not the passed address is part of the IPv4 shared address space specified by RFC6598 (100.64.0.0/10)

                                      func IsRoutable

                                      func IsRoutable(na *wire.NetAddress) bool

                                        IsRoutable returns whether or not the passed address is routable over the public internet. This is true as long as the address is valid and is not in any reserved ranges.

                                        func IsValid

                                        func IsValid(na *wire.NetAddress) bool

                                          IsValid returns whether or not the passed address is valid. The address is considered invalid under the following circumstances: IPv4: It is either a zero or all bits set address. IPv6: It is either a zero or RFC3849 documentation address.

                                          func NetAddressKey

                                          func NetAddressKey(na *wire.NetAddress) string

                                            NetAddressKey returns a string key in the form of ip:port for IPv4 addresses or [ip]:port for IPv6 addresses.

                                            func UseLogger

                                            func UseLogger(logger bchlog.Logger)

                                              UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using bchlog.

                                              Types

                                              type AddrManager

                                              type AddrManager struct {
                                              	// contains filtered or unexported fields
                                              }

                                                AddrManager provides a concurrency safe address manager for caching potential peers on the bitcoin network.

                                                func New

                                                func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager

                                                  New returns a new bitcoin address manager. Use Start to begin processing asynchronous address updates.

                                                  func (*AddrManager) AddAddress

                                                  func (a *AddrManager) AddAddress(addr, srcAddr *wire.NetAddress)

                                                    AddAddress adds a new address to the address manager. It enforces a max number of addresses and silently ignores duplicate addresses. It is safe for concurrent access.

                                                    func (*AddrManager) AddAddressByIP

                                                    func (a *AddrManager) AddAddressByIP(addrIP string) error

                                                      AddAddressByIP adds an address where we are given an ip:port and not a wire.NetAddress.

                                                      func (*AddrManager) AddAddresses

                                                      func (a *AddrManager) AddAddresses(addrs []*wire.NetAddress, srcAddr *wire.NetAddress)

                                                        AddAddresses adds new addresses to the address manager. It enforces a max number of addresses and silently ignores duplicate addresses. It is safe for concurrent access.

                                                        func (*AddrManager) AddLocalAddress

                                                        func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error

                                                          AddLocalAddress adds na to the list of known local addresses to advertise with the given priority.

                                                          func (*AddrManager) AddressCache

                                                          func (a *AddrManager) AddressCache() []*wire.NetAddress

                                                            AddressCache returns the current address cache. It must be treated as read-only (but since it is a copy now, this is not as dangerous).

                                                            func (*AddrManager) Attempt

                                                            func (a *AddrManager) Attempt(addr *wire.NetAddress)

                                                              Attempt increases the given address' attempt counter and updates the last attempt time.

                                                              func (*AddrManager) Connected

                                                              func (a *AddrManager) Connected(addr *wire.NetAddress)

                                                                Connected Marks the given address as currently connected and working at the current time. The address must already be known to AddrManager else it will be ignored.

                                                                func (*AddrManager) DeserializeNetAddress

                                                                func (a *AddrManager) DeserializeNetAddress(addr string,
                                                                	services wire.ServiceFlag) (*wire.NetAddress, error)

                                                                  DeserializeNetAddress converts a given address string to a *wire.NetAddress.

                                                                  func (*AddrManager) GetAddress

                                                                  func (a *AddrManager) GetAddress() *KnownAddress

                                                                    GetAddress returns a single address that should be routable. It picks a random one from the possible addresses with preference given to ones that have not been used recently and should not pick 'close' addresses consecutively.

                                                                    func (*AddrManager) GetBestLocalAddress

                                                                    func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.NetAddress

                                                                      GetBestLocalAddress returns the most appropriate local address to use for the given remote address.

                                                                      func (*AddrManager) Good

                                                                      func (a *AddrManager) Good(addr *wire.NetAddress)

                                                                        Good marks the given address as good. To be called after a successful connection and version exchange. If the address is unknown to the address manager it will be ignored.

                                                                        func (*AddrManager) HostToNetAddress

                                                                        func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.ServiceFlag) (*wire.NetAddress, error)

                                                                          HostToNetAddress returns a netaddress given a host address. If the address is a Tor .onion address this will be taken care of. Else if the host is not an IP address it will be resolved (via Tor if required).

                                                                          func (*AddrManager) LocalAddresses

                                                                          func (a *AddrManager) LocalAddresses() []*LocalAddress

                                                                            LocalAddresses returns the list of local addresses for our node.

                                                                            func (*AddrManager) NeedMoreAddresses

                                                                            func (a *AddrManager) NeedMoreAddresses() bool

                                                                              NeedMoreAddresses returns whether or not the address manager needs more addresses.

                                                                              func (*AddrManager) NumAddresses

                                                                              func (a *AddrManager) NumAddresses() int

                                                                                NumAddresses returns the number of addresses known to the address manager.

                                                                                func (*AddrManager) SetServices

                                                                                func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFlag)

                                                                                  SetServices sets the services for the given address to the provided value.

                                                                                  func (*AddrManager) Start

                                                                                  func (a *AddrManager) Start()

                                                                                    Start begins the core address handler which manages a pool of known addresses, timeouts, and interval based writes.

                                                                                    func (*AddrManager) Stop

                                                                                    func (a *AddrManager) Stop() error

                                                                                      Stop gracefully shuts down the address manager by stopping the main handler.

                                                                                      type AddressPriority

                                                                                      type AddressPriority int

                                                                                        AddressPriority type is used to describe the hierarchy of local address discovery methods.

                                                                                        const (
                                                                                        	// InterfacePrio signifies the address is on a local interface
                                                                                        	InterfacePrio AddressPriority = iota
                                                                                        
                                                                                        	// BoundPrio signifies the address has been explicitly bounded to.
                                                                                        	BoundPrio
                                                                                        
                                                                                        	// UpnpPrio signifies the address was obtained from UPnP.
                                                                                        	UpnpPrio
                                                                                        
                                                                                        	// HTTPPrio signifies the address was obtained from an external HTTP service.
                                                                                        	HTTPPrio
                                                                                        
                                                                                        	// ManualPrio signifies the address was provided by --externalip.
                                                                                        	ManualPrio
                                                                                        )

                                                                                        type KnownAddress

                                                                                        type KnownAddress struct {
                                                                                        	// contains filtered or unexported fields
                                                                                        }

                                                                                          KnownAddress tracks information about a known network address that is used to determine how viable an address is.

                                                                                          func (*KnownAddress) LastAttempt

                                                                                          func (ka *KnownAddress) LastAttempt() time.Time

                                                                                            LastAttempt returns the last time the known address was attempted.

                                                                                            func (*KnownAddress) NetAddress

                                                                                            func (ka *KnownAddress) NetAddress() *wire.NetAddress

                                                                                              NetAddress returns the underlying wire.NetAddress associated with the known address.

                                                                                              func (*KnownAddress) Services

                                                                                              func (ka *KnownAddress) Services() wire.ServiceFlag

                                                                                                Services returns the services supported by the peer with the known address.

                                                                                                type LocalAddress

                                                                                                type LocalAddress struct {
                                                                                                	NA    *wire.NetAddress
                                                                                                	Score AddressPriority
                                                                                                }

                                                                                                  LocalAddress holds a NetAddress with the addresses's priority.