connmgr

package module
v3.0.0-...-cf10ea2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2023 License: ISC Imports: 15 Imported by: 2

README

connmgr

Build Status ISC License Doc

Package connmgr implements a generic Exchangecoin network connection manager.

Overview

This package handles all the general connection concerns such as maintaining a set number of outbound connections, sourcing peers, banning, limiting max connections, tor lookup, etc.

The package provides a generic connection manager which is able to accept connection requests from a source or a set of given addresses, dial them and notify the caller on connections. The main intended use is to initialize a pool of active connections and maintain them to remain connected to the P2P network.

In addition the connection manager provides the following utilities:

  • Notifications on connections or disconnections
  • Handle failures and retry new addresses from the source
  • Connect only to specified addresses
  • Permanent connections with increasing backoff retry timers
  • Disconnect or Remove an established connection

Installation and Updating

This package is part of the github.com/EXCCoin/exccd/connmgr/v3 module. Use the standard go tooling for working with modules to incorporate it.

License

Package connmgr is licensed under the copyfree ISC License.

Documentation

Overview

Package connmgr implements a generic Decred network connection manager.

Connection Manager Overview

Connection manager handles all the general connection concerns such as maintaining a set number of outbound connections, sourcing peers, banning, limiting max connections, tor lookup, etc.

Index

Constants

View Source
const (
	// Halflife defines the time (in seconds) by which the transient part
	// of the ban score decays to one half of its original value.
	Halflife = 60

	// Lifetime defines the maximum age of the transient part of the ban
	// score to be considered a non-zero score (in seconds).
	Lifetime = 1800
)
View Source
const (
	// ErrDialNil is used to indicate that Dial cannot be nil in
	// the configuration.
	ErrDialNil = ErrorKind("ErrDialNil")

	// ErrBothDialsFilled is used to indicate that Dial and DialAddr
	// cannot both be specified in the configuration.
	ErrBothDialsFilled = ErrorKind("ErrBothDialsFilled")

	// ErrTorInvalidAddressResponse indicates an invalid address was
	// returned by the Tor DNS resolver.
	ErrTorInvalidAddressResponse = ErrorKind("ErrTorInvalidAddressResponse")

	// ErrTorInvalidProxyResponse indicates the Tor proxy returned a
	// response in an unexpected format.
	ErrTorInvalidProxyResponse = ErrorKind("ErrTorInvalidProxyResponse")

	// ErrTorUnrecognizedAuthMethod indicates the authentication method
	// provided is not recognized.
	ErrTorUnrecognizedAuthMethod = ErrorKind("ErrTorUnrecognizedAuthMethod")

	// ErrTorGeneralError indicates a general tor error.
	ErrTorGeneralError = ErrorKind("ErrTorGeneralError")

	// ErrTorNotAllowed indicates tor connections are not allowed.
	ErrTorNotAllowed = ErrorKind("ErrTorNotAllowed")

	// ErrTorNetUnreachable indicates the tor network is unreachable.
	ErrTorNetUnreachable = ErrorKind("ErrTorNetUnreachable")

	// ErrTorHostUnreachable indicates the tor host is unreachable.
	ErrTorHostUnreachable = ErrorKind("ErrTorHostUnreachable")

	// ErrTorConnectionRefused indicates the tor connection was refused.
	ErrTorConnectionRefused = ErrorKind("ErrTorConnectionRefused")

	// ErrTorTTLExpired indicates the tor request Time-To-Live (TTL) expired.
	ErrTorTTLExpired = ErrorKind("ErrTorTTLExpired")

	// ErrTorCmdNotSupported indicates the tor command is not supported.
	ErrTorCmdNotSupported = ErrorKind("ErrTorCmdNotSupported")

	// ErrTorAddrNotSupported indicates the tor address type is not supported.
	ErrTorAddrNotSupported = ErrorKind("ErrTorAddrNotSupported")
)

Variables

This section is empty.

Functions

func SeedAddrs

func SeedAddrs(ctx context.Context, seeder string, dialFn DialFunc, filters ...func(f *HttpsSeederFilters)) ([]*wire.NetAddress, error)

SeedAddrs uses HTTPS seeding to return a list of addresses of p2p peers on the network.

The seeder parameter specifies the domain name of the seed. The dial function specifies the dialer to use to contact the HTTPS seeder and allows the caller to use whatever configuration it deems fit such as using a proxy, like Tor.

The variadic filters parameter allows additional query filters to be applied. The available filters can be set via the exported functions that start with the prefix SeedFilter. See the documentation for each function for more details.

func SeedFilterIPVersion

func SeedFilterIPVersion(ipVersion uint16) func(f *HttpsSeederFilters)

SeedFilterIPVersion configures a request to an HTTPS seeder to filter all results that are not the provided ip version, which is expected to be either 4 or 6, to indicate IPv4 or IPv6 addresses, respectively. The HTTPS seeder may choose to ignore other IP versions.

func SeedFilterProtocolVersion

func SeedFilterProtocolVersion(pver uint32) func(f *HttpsSeederFilters)

SeedFilterProtocolVersion configures a request to an HTTPS seeder to filter all results that are not the provided peer-to-peer protocol version. This can be useful to discover peers that support specific peer versions.

func SeedFilterServices

func SeedFilterServices(services wire.ServiceFlag) func(f *HttpsSeederFilters)

SeedFilterServices configures a request to an HTTPS seeder to filter all results that do not support the provided service flags. This can be useful to discover peers that support specific services such as fully-validating nodes.

func TorLookupIP

func TorLookupIP(ctx context.Context, host, proxy string) ([]net.IP, error)

TorLookupIP uses Tor to resolve DNS via the passed SOCKS proxy.

func UseLogger

func UseLogger(logger slog.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 slog.

Types

type Config

type Config struct {
	// Listeners defines a slice of listeners for which the connection
	// manager will take ownership of and accept connections.  When a
	// connection is accepted, the OnAccept handler will be invoked with the
	// connection.  Since the connection manager takes ownership of these
	// listeners, they will be closed when the connection manager is
	// stopped.
	//
	// This field will not have any effect if the OnAccept field is not
	// also specified.  It may be nil if the caller does not wish to listen
	// for incoming connections.
	Listeners []net.Listener

	// OnAccept is a callback that is fired when an inbound connection is
	// accepted.  It is the caller's responsibility to close the connection.
	// Failure to close the connection will result in the connection manager
	// believing the connection is still active and thus have undesirable
	// side effects such as still counting toward maximum connection limits.
	//
	// This field will not have any effect if the Listeners field is not
	// also specified since there couldn't possibly be any accepted
	// connections in that case.
	OnAccept func(net.Conn)

	// TargetOutbound is the number of outbound network connections to
	// maintain. Defaults to 8.
	TargetOutbound uint32

	// RetryDuration is the duration to wait before retrying connection
	// requests. Defaults to 5s.
	RetryDuration time.Duration

	// OnConnection is a callback that is fired when a new outbound
	// connection is established.
	OnConnection func(*ConnReq, net.Conn)

	// OnDisconnection is a callback that is fired when an outbound
	// connection is disconnected.
	OnDisconnection func(*ConnReq)

	// GetNewAddress is a way to get an address to make a network connection
	// to.  If nil, no new connections will be made automatically.
	GetNewAddress func() (net.Addr, error)

	// Dial connects to the address on the named network. Either Dial or
	// DialAddr need to be specified (but not both).
	Dial func(ctx context.Context, network, addr string) (net.Conn, error)

	// DialAddr is an alternative to Dial which receives a full net.Addr instead
	// of just the protocol family and address. Either DialAddr or Dial need
	// to be specified (but not both).
	DialAddr func(context.Context, net.Addr) (net.Conn, error)

	// Timeout specifies the amount of time to wait for a connection
	// to complete before giving up.
	Timeout time.Duration
}

Config holds the configuration options related to the connection manager.

type ConnManager

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

ConnManager provides a manager to handle network connections.

func New

func New(cfg *Config) (*ConnManager, error)

New returns a new connection manager with the provided configuration.

Use Run to start listening and/or connecting to the network.

func (*ConnManager) CancelPending

func (cm *ConnManager) CancelPending(addr net.Addr) error

CancelPending removes the connection corresponding to the given address from the list of pending failed connections.

Returns an error if the connection manager is stopped or there is no pending connection for the given address.

func (*ConnManager) Connect

func (cm *ConnManager) Connect(ctx context.Context, c *ConnReq)

Connect assigns an id and dials a connection to the address of the connection request using the provided context and the dial function configured when initially creating the connection manager.

The connection attempt will be ignored if the connection manager has been shutdown by canceling the lifecycle context the Run method was invoked with or the provided connection request is already in the failed state.

Note that the context parameter to this function and the lifecycle context may be independent.

func (*ConnManager) Disconnect

func (cm *ConnManager) Disconnect(id uint64)

Disconnect disconnects the connection corresponding to the given connection id. If permanent, the connection will be retried with an increasing backoff duration.

func (*ConnManager) ForEachConnReq

func (cm *ConnManager) ForEachConnReq(f func(c *ConnReq) error) error

ForEachConnReq calls the provided function with each connection request known to the connection manager, including pending requests. Returning an error from the provided function will stop the iteration early and return said error from this function.

This function is safe for concurrent access.

NOTE: This must not call any other connection manager methods during iteration or it will result in a deadlock.

func (*ConnManager) Remove

func (cm *ConnManager) Remove(id uint64)

Remove removes the connection corresponding to the given connection id from known connections.

NOTE: This method can also be used to cancel a lingering connection attempt that hasn't yet succeeded.

func (*ConnManager) Run

func (cm *ConnManager) Run(ctx context.Context)

Run starts the connection manager along with its configured listeners and begins connecting to the network. It blocks until the provided context is cancelled.

type ConnReq

type ConnReq struct {

	// Addr is the address to connect to.
	Addr net.Addr

	// Permanent specifies whether or not the connection request represents what
	// should be treated as a permanent connection, meaning the connection
	// manager will try to always maintain the connection including retries with
	// increasing backoff timeouts.
	Permanent bool
	// contains filtered or unexported fields
}

ConnReq is the connection request to a network address. If permanent, the connection will be retried on disconnection.

func (*ConnReq) ID

func (c *ConnReq) ID() uint64

ID returns a unique identifier for the connection request.

func (*ConnReq) State

func (c *ConnReq) State() ConnState

State is the connection state of the requested connection.

func (*ConnReq) String

func (c *ConnReq) String() string

String returns a human-readable string for the connection request.

type ConnState

type ConnState uint32

ConnState represents the state of the requested connection.

const (
	ConnPending ConnState = iota
	ConnEstablished
	ConnDisconnected
	ConnFailed
	ConnCanceled
)

ConnState can be either pending, established, disconnected or failed. When a new connection is requested, it is attempted and categorized as established or failed depending on the connection result. An established connection which was disconnected is categorized as disconnected.

type DialFunc

type DialFunc func(context.Context, string, string) (net.Conn, error)

DialFunc is the signature of the Dialer function.

type DynamicBanScore

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

DynamicBanScore provides dynamic ban scores consisting of a persistent and a decaying component. The persistent score could be utilized to create simple additive banning policies similar to those found in other bitcoin node implementations.

The decaying score enables the creation of evasive logic which handles misbehaving peers (especially application layer DoS attacks) gracefully by disconnecting and banning peers attempting various kinds of flooding. DynamicBanScore allows these two approaches to be used in tandem.

Zero value: Values of type DynamicBanScore are immediately ready for use upon declaration.

func (*DynamicBanScore) Increase

func (s *DynamicBanScore) Increase(persistent, transient uint32) uint32

Increase increases both the persistent and decaying scores by the values passed as parameters. The resulting score is returned.

This function is safe for concurrent access.

func (*DynamicBanScore) Int

func (s *DynamicBanScore) Int() uint32

Int returns the current ban score, the sum of the persistent and decaying scores.

This function is safe for concurrent access.

func (*DynamicBanScore) Reset

func (s *DynamicBanScore) Reset()

Reset set both persistent and decaying scores to zero.

This function is safe for concurrent access.

func (*DynamicBanScore) String

func (s *DynamicBanScore) String() string

String returns the ban score as a human-readable string.

type Error

type Error struct {
	Description string
	Err         error
}

Error identifies an error related to the connection manager error. It has full support for errors.Is and errors.As, so the caller can ascertain the specific reason for the error by checking the underlying error.

func MakeError

func MakeError(kind ErrorKind, desc string) Error

MakeError creates an Error given a set of arguments.

func (Error) Error

func (e Error) Error() string

Error satisfies the error interface and prints human-readable errors.

func (Error) Unwrap

func (e Error) Unwrap() error

Unwrap returns the underlying wrapped error.

type ErrorKind

type ErrorKind string

ErrorKind identifies a kind of error. It has full support for errors.Is and errors.As, so the caller can directly check against an error kind when determining the reason for an error.

func (ErrorKind) Error

func (e ErrorKind) Error() string

Error satisfies the error interface and prints human-readable errors.

type HttpsSeederFilters

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

HttpsSeederFilters houses filter parameters for use when making a request to an HTTPS seeder. It can be configured via the various exported functions that start with the prefix SeedFilter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL