BlackHoleSuccessCounter provides black hole filtering for dials. This filter should be used in concert
with a UDP or IPv6 address filter to detect UDP or IPv6 black hole. In a black holed environment,
dial requests are refused Requests are blocked if the number of successes in the last N dials is
less than MinSuccesses.
If a request succeeds in Blocked state, the filter state is reset and N subsequent requests are
allowed before reevaluating black hole state. Dials cancelled when some other concurrent dial
succeeded are counted as failures. A sufficiently large N prevents false negatives in such cases. MinSuccesses is the minimum number of Success required in the last n dials
to consider we are not blocked. N is
1. The minimum number of completed dials required before evaluating black hole state
2. the minimum number of requests after which we probe the state of the black hole in
blocked state Name for the detector. HandleRequest returns the result of applying the black hole filter for the request. RecordResult records the outcome of a dial. A successful dial in Blocked state will change the
state of the filter to Probing. A failed dial only blocks subsequent requests if the success
fraction over the last n outcomes is less than the minSuccessFraction of the filter.(*BlackHoleSuccessCounter) State() BlackHoleState
func WithIPv6BlackHoleSuccessCounter(f *BlackHoleSuccessCounter) Option
func WithUDPBlackHoleSuccessCounter(f *BlackHoleSuccessCounter) Option
func github.com/libp2p/go-libp2p.IPv6BlackHoleSuccessCounter(f *BlackHoleSuccessCounter) libp2p.Option
func github.com/libp2p/go-libp2p.UDPBlackHoleSuccessCounter(f *BlackHoleSuccessCounter) libp2p.Option
Clock is a clock that can create timers that trigger at some
instant rather than some duration( Clock) InstantTimer(when time.Time) InstantTimer( Clock) Now() time.Time( Clock) Since(t time.Time) time.DurationRealClock
Clock : github.com/hibiken/asynq/internal/timeutil.Clock
Clock : github.com/pion/stun.Clock
Clock : github.com/pion/stun/v3.Clock
Clock : github.com/quic-go/quic-go/internal/congestion.Clock
Clock : go.uber.org/dig/internal/digclock.Clock
Conn is the connection type used by swarm. In general, you won't use this
type directly. Close closes this connection.
Note: This method won't wait for the close notifications to finish as that
would create a deadlock when called from an open notification (because all
open notifications must finish before we can fire off the close
notifications).(*Conn) CloseWithError(errCode network.ConnErrorCode) error ConnState is the security connection state. including early data result.
Empty if not supported. GetStreams returns the streams associated with this connection.(*Conn) ID() string(*Conn) IsClosed() bool LocalMultiaddr is the Multiaddr on this side LocalPeer is the Peer on our side of the connection NewStream returns a new Stream from this connection RemoteMultiaddr is the Multiaddr on the remote side RemotePeer is the Peer on the remote side RemotePublicKey is the public key of the peer on the remote side(*Conn) Scope() network.ConnScope Stat returns metadata pertaining to this connection(*Conn) String() string
*Conn : github.com/libp2p/go-libp2p/core/network.Conn
*Conn : github.com/libp2p/go-libp2p/core/network.ConnMultiaddrs
*Conn : github.com/libp2p/go-libp2p/core/network.ConnScoper
*Conn : github.com/libp2p/go-libp2p/core/network.ConnSecurity
*Conn : github.com/libp2p/go-libp2p/core/network.ConnStat
*Conn : github.com/prometheus/common/expfmt.Closer
*Conn : expvar.Var
*Conn : fmt.Stringer
*Conn : io.Closer
DialBackoff is a type for tracking peer dial backoffs. Dialbackoff is used to
avoid over-dialing the same, dead peers. Whenever we totally time out on all
addresses of a peer, we add the addresses to DialBackoff. Then, whenever we
attempt to dial the peer again, we check each address for backoff. If it's on
backoff, we don't dial the address and exit promptly. If a dial is
successful, the peer and all its addresses are removed from backoff.
* It's safe to use its zero value.
* It's thread-safe.
* It's *not* safe to move this type after using. AddBackoff adds peer's address to backoff.
Backoff is not exponential, it's quadratic and computed according to the
following formula:
BackoffBase + BakoffCoef * PriorBackoffs^2
Where PriorBackoffs is the number of previous backoffs. Backoff returns whether the client should backoff from dialing
peer p at address addr Clear removes a backoff record. Clients should call this after a
successful Dial.
func (*Swarm).Backoff() *DialBackoff
InstantTimer is a timer that triggers at some instant rather than some duration( InstantTimer) Ch() <-chan time.Time( InstantTimer) Reset(d time.Time) bool( InstantTimer) Stop() boolRealTimer
github.com/libp2p/go-libp2p/p2p/host/autorelay.InstantTimer(interface)
github.com/libp2p/go-libp2p/p2p/host/autorelay.RealTimer
InstantTimer : github.com/libp2p/go-libp2p/p2p/host/autorelay.InstantTimer
InstantTimer : google.golang.org/grpc/internal.Timer
func Clock.InstantTimer(when time.Time) InstantTimer
func RealClock.InstantTimer(when time.Time) InstantTimer
Transports optionally implement this interface to indicate the relative
ordering that listeners should be setup. Some transports may optionally
make use of other listeners if they are setup. e.g. WebRTC may reuse the
same UDP port as QUIC, but only when QUIC is setup first.
lower values are setup first.
*github.com/libp2p/go-libp2p/p2p/transport/webrtc.WebRTCTransport
Resolver*madns.Resolver( ResolverFromMaDNS) LookupIPAddr(ctx context.Context, domain string) ([]net.IPAddr, error)( ResolverFromMaDNS) LookupTXT(ctx context.Context, txt string) ([]string, error) Resolve resolves a DNS multiaddr. It will only resolve the first DNS component in the multiaddr.
If you need to resolve multiple DNS components, you may call this function again with each returned address. ResolveDNSAddr implements MultiaddrDNSResolver ResolveDNSComponent implements MultiaddrDNSResolver
ResolverFromMaDNS : github.com/libp2p/go-libp2p/core/network.MultiaddrDNSResolver
ResolverFromMaDNS : github.com/libp2p/go-libp2p/core/transport.Resolver
ResolverFromMaDNS : github.com/multiformats/go-multiaddr-dns.BasicResolver
Stream is the stream type used by swarm. In general, you won't use this type
directly. Close closes the stream, closing both ends and freeing all associated
resources. CloseRead closes the stream for reading. This function does not free resources,
call Close or Reset when done with the stream. CloseWrite closes the stream for writing, flushing all data and sending an EOF.
This function does not free resources, call Close or Reset when done with the
stream. Conn returns the Conn associated with this stream, as an network.Conn(*Stream) ID() string Protocol returns the protocol negotiated on this stream (if set). Read reads bytes from a stream. Reset resets the stream, signaling an error on both ends and freeing all
associated resources.(*Stream) ResetWithError(errCode network.StreamErrorCode) error(*Stream) Scope() network.StreamScope SetDeadline sets the read and write deadlines for this stream. SetProtocol sets the protocol for this stream.
This doesn't actually *do* anything other than record the fact that we're
speaking the given protocol over this stream. It's still up to the user to
negotiate the protocol. This is usually done by the Host. SetReadDeadline sets the read deadline for this stream. SetWriteDeadline sets the write deadline for this stream. Stat returns metadata information for this stream.(*Stream) String() string Write writes bytes to a stream, flushing for each call.
*Stream : github.com/libp2p/go-libp2p/core/network.MuxedStream
*Stream : github.com/libp2p/go-libp2p/core/network.Stream
*Stream : github.com/miekg/dns.Writer
*Stream : github.com/pion/datachannel.ReadDeadliner
*Stream : github.com/pion/datachannel.WriteDeadliner
*Stream : github.com/pion/stun.Connection
*Stream : github.com/pion/stun/v3.Connection
*Stream : github.com/prometheus/common/expfmt.Closer
*Stream : expvar.Var
*Stream : fmt.Stringer
*Stream : internal/bisect.Writer
*Stream : io.Closer
*Stream : io.ReadCloser
*Stream : io.Reader
*Stream : io.ReadWriteCloser
*Stream : io.ReadWriter
*Stream : io.WriteCloser
*Stream : io.Writer
Swarm is a connection muxer, allowing connections to other peers to
be opened and closed, while still using the same Chan for all
communication. The Chan sends/receives Messages, which note the
destination or source Peer. AddListenAddr tells the swarm to listen on a single address. Unlike Listen,
this method does not attempt to filter out bad addresses. AddTransport adds a transport to this swarm.
Satisfies the Network interface from go-libp2p-transport. Backoff returns the DialBackoff object for this swarm.(*Swarm) CanDial(p peer.ID, addr ma.Multiaddr) bool(*Swarm) Close() error ClosePeer closes all connections to the given peer. Connectedness returns our "connectedness" state with the given peer.
To check if we have an open connection, use `s.Connectedness(p) ==
network.Connected`. Conns returns a slice of all connections. ConnsToPeer returns all the live connections to peer. DialPeer connects to a peer. Use network.WithForceDirectDial to force a
direct connection.
The idea is that the client of Swarm does not need to know what network
the connection will happen over. Swarm can use whichever it choses.
This allows us to use various transport protocols, do NAT traversal/relay,
etc. to achieve connection. Done returns a channel that is closed when the swarm is closed. InterfaceListenAddresses returns a list of addresses at which this swarm
listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
use the known local interfaces. Listen sets up listeners for all of the given addresses.
It returns as long as we successfully listen on at least *one* address. ListenAddresses returns a list of addresses at which this swarm listens. ListenClose stop and delete listeners for all of the given addresses. If an
any address belongs to one of the addreses a Listener provides, then the
Listener will close for *all* addresses it provides. For example if you close
and address with `/quic`, then the QUIC listener will close and also close
any `/quic-v1` address. LocalPeer returns the local peer swarm is associated to. NewStream creates a new stream on any available connection to peer, dialing
if necessary.
Use network.WithAllowLimitedConn to open a stream over a limited(relayed)
connection. Notify signs up Notifiee to receive signals when events happen Peers returns a copy of the set of peers swarm is connected to. Peerstore returns this swarms internal Peerstore.(*Swarm) ResourceManager() network.ResourceManager SetStreamHandler assigns the handler for new streams. StopNotify unregisters Notifiee fromr receiving signals StreamHandler gets the handler for new streams. String returns a string representation of Network. TransportForDialing retrieves the appropriate transport for dialing the given
multiaddr. TransportForListening retrieves the appropriate transport for listening on
the given multiaddr.
*Swarm : github.com/libp2p/go-libp2p/core/network.Dialer
*Swarm : github.com/libp2p/go-libp2p/core/network.Network
*Swarm : github.com/libp2p/go-libp2p/core/transport.TransportNetwork
*Swarm : github.com/prometheus/common/expfmt.Closer
*Swarm : expvar.Var
*Swarm : fmt.Stringer
*Swarm : io.Closer
func NewSwarm(local peer.ID, peers peerstore.Peerstore, eventBus event.Bus, opts ...Option) (*Swarm, error)
DefaultDialRanker determines the ranking of outgoing connection attempts.
Addresses are grouped into three distinct groups:
- private addresses (localhost and local networks (RFC 1918))
- public addresses
- relay addresses
Within each group, the addresses are ranked according to the ranking logic described below.
We then dial addresses according to this ranking, with short timeouts applied between dial attempts.
This ranking logic dramatically reduces the number of simultaneous dial attempts, while introducing
no additional latency in the vast majority of cases.
Private and public address groups are dialed in parallel.
Dialing relay addresses is delayed by 500 ms, if we have any non-relay alternatives.
Within each group (private, public, relay addresses) we apply the following ranking logic:
1. If both IPv6 QUIC and IPv4 QUIC addresses are present, we do a Happy Eyeballs RFC 8305 style ranking.
First dial the IPv6 QUIC address with the lowest port. After this we dial the IPv4 QUIC address with
the lowest port delayed by 250ms (PublicQUICDelay) for public addresses, and 30ms (PrivateQUICDelay)
for local addresses. After this we dial all the rest of the addresses delayed by 250ms (PublicQUICDelay)
for public addresses, and 30ms (PrivateQUICDelay) for local addresses.
2. If only one of QUIC IPv6 or QUIC IPv4 addresses are present, dial the QUIC address with the lowest port
first. After this we dial the rest of the QUIC addresses delayed by 250ms (PublicQUICDelay) for public
addresses, and 30ms (PrivateQUICDelay) for local addresses.
3. If a QUIC or WebTransport address is present, TCP addresses dials are delayed relative to the last QUIC dial:
We prefer to end up with a QUIC connection. For public addresses, the delay introduced is 250ms (PublicTCPDelay),
and for private addresses 30ms (PrivateTCPDelay).
4. For the TCP addresses we follow a strategy similar to QUIC with an optimisation for handling the long TCP
handshake time described in 6. If both IPv6 TCP and IPv4 TCP addresses are present, we do a Happy Eyeballs
style ranking. First dial the IPv6 TCP address with the lowest port. After this, dial the IPv4 TCP address
with the lowest port delayed by 250ms (PublicTCPDelay) for public addresses, and 30ms (PrivateTCPDelay)
for local addresses. After this we dial all the rest of the addresses delayed by 250ms (PublicTCPDelay) for
public addresses, and 30ms (PrivateTCPDelay) for local addresses.
5. If only one of TCP IPv6 or TCP IPv4 addresses are present, dial the TCP address with the lowest port
first. After this we dial the rest of the TCP addresses delayed by 250ms (PublicTCPDelay) for public
addresses, and 30ms (PrivateTCPDelay) for local addresses.
6. When a TCP socket is connected and awaiting security and muxer upgrade, we stop new dials for 2*PublicTCPDelay
to allow for the upgrade to complete.
7. WebRTC Direct, and other IP transport addresses are dialed 1 second after the last QUIC or TCP dial.
We only ever need to dial these if the peer doesn't have any other transport available, in which
case these are dialed immediately.
We dial lowest ports first as they are more likely to be the listen port.
WithIPv6BlackHoleSuccessCounter configures swarm to use the provided config for IPv6 black hole detection
n is the size of the sliding window used to evaluate black hole state
min is the minimum number of successes out of n required to not block requests
WithMultiaddrResolver sets a custom multiaddress resolver
WithReadOnlyBlackHoleDetector configures the swarm to use the black hole detector in
read only mode. In Read Only mode dial requests are refused in unknown state and
no updates to the detector state are made. This is useful for services like AutoNAT that
care about accurately providing reachability info.
WithUDPBlackHoleSuccessCounter configures swarm to use the provided config for UDP black hole detection
n is the size of the sliding window used to evaluate black hole state
min is the minimum number of successes out of n required to not block requests
Package-Level Variables (total 17)
BackoffBase is the base amount of time to backoff (default: 5s).
BackoffCoef is the backoff coefficient (default: 1s).
BackoffMax is the maximum backoff time (default: 5m).
DefaultPerPeerRateLimit is the number of concurrent outbound dials to make
per peer
ErrAddrFiltered is returned when trying to register a connection to a
filtered address. You shouldn't see this error unless some underlying
transport is misbehaving.
ErrAllDialsFailed is returned when connecting to a peer has ultimately failed
ErrConnClosed is returned when operating on a closed connection.
ErrDialBackoff is returned by the backoff code when a given peer has
been dialed too frequently
ErrDialRefusedBlackHole is returned when we are in a black holed environment
ErrDialTimeout is returned when one a dial times out due to the global timeout
ErrDialToSelf is returned if we attempt to dial our own peer
ErrGaterDisallowedConnection is returned when the gater prevents us from
forming a connection with a peer.
ErrNoAddresses is returned when we fail to find any addresses for a
peer we're trying to dial.
ErrNoGoodAddresses is returned when we find addresses for a peer but
can't use any of them.
ErrNoTransport is returned when we don't know a transport for the
given multiaddr.
ErrQUICDraft29 wraps ErrNoTransport and provide a more meaningful error message
ErrSwarmClosed is returned when one attempts to operate on a closed swarm.
Package-Level Constants (total 9)
ConcurrentFdDials is the number of concurrent outbound dials over transports
that consume file descriptors
DialAttempts governs how many times a goroutine will try to dial a given peer.
Note: this is down to one, as we have _too many dials_ atm. To add back in,
add loop back in Dial(.)
The 250ms value is from happy eyeballs RFC 8305. This is a rough estimate of 1 RTT
The 250ms value is from happy eyeballs RFC 8305. This is a rough estimate of 1 RTT
The 250ms value is from happy eyeballs RFC 8305. This is a rough estimate of 1 RTT
delay for other transport addresses. This will apply to /webrtc-direct.
duration by which QUIC dials are delayed relative to previous QUIC dial
duration by which TCP dials are delayed relative to the last QUIC dial
RelayDelay is the duration by which relay dials are delayed relative to direct addresses
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.