ConnAs works in a similar way to errors.As. It allows a user to cut
through the interface layers and extract a specific type of connection
if available.
This serves as a sort of escape hatch to allow users to leverage some
connection specific feature without having to support that feature for
all connections. Getting RTT information is one example.
It also allows us, within the library, to get specific types of
connections out of the interface box. This would have been useful in the
recent changes in tcpreuse. See
https://github.com/libp2p/go-libp2p/pull/3181 and
https://github.com/libp2p/go-libp2p/pull/3142.
Getting access to the underlying type can lead to hard to debug issues.
For example, if a user mutates connection state on the underlying type,
hooks that relied on only mutating that state from the wrapped
connection would never be called.
It is up to the user to ensure they are using this safely.
Multiple libp2p transports can share the same port (TCP, QUIC,
WebTransport, WebRTC-direct), causing duplicate AddMapping calls
for the same protocol/port combination. This fix adds deduplication
in NAT.AddMapping to prevent redundant NAT device operations and
reduce log spam.
Router restarts can cause UPnP/NAT-PMP services to change their
listening ports, leading to connection refused errors. This fix
implements automatic NAT rediscovery when consecutive connection
failures are detected, restoring all existing port mappings on
the new NAT instance.
See https://github.com/libp2p/go-libp2p/issues/3224#issuecomment-2866844723
for details on the router behavior that motivated this fix.
Providing unknown addresses to the user, helps them infer whether autonatv2 has any more addresses it might confirm.
There's no upside to not sending this information.
This also changes host.ConfirmedAddrs to return all the three categories, Reachable, Unreachable, and Unknown addrs.
This rate limits new connections to prevent DoS attacks.
For effectively rate limiting QUIC connections, we now gate QUIC connection attempts before the handshake, so that we don't spend compute on handshakes for connections that will eventually be cancelled.
We can only set a single ConnContext per quic-go Transport, as there's only 1 listener per quic-go Transport. So we cannot set a different ConnContext for listeners on the same address.
As we're now gating QUIC connections before the handshake, we use source address verification to ensure that spoofed IPs cannot DoS new connections from a particular IP. This is done by ensuring that some of the connection attempts always verify the source address. We get DoS protection at the expense of increased latency of source address verification.
This introduces addrsReachabilityTracker that tracks reachability on
a set of addresses. It probes reachability for addresses periodically
and has an exponential backoff in case there are too many errors
or we don't have any valid autonatv2 peer.
There's no smartness in the address selection logic currently. We just
test all provided addresses. It also doesn't use the addresses provided
by `AddrsFactory`, so currently there's no way to get a user provided
address tested for reachability, something that would be a problem for
dns addresses. I intend to introduce an alternative to
`AddrsFactory`, something like, `AnnounceAddrs(addrs []ma.Multiaddr)`
that's just appended to the set of addresses that we have, and check
reachability for those addresses.
There's only one method exposed in the BasicHost right now that's
`ReachableAddrs() []ma.Multiadd`r that returns the host's reachable
addrs. Users can also use the event `EvtHostReachableAddrsChanged`
to be notified when any addrs reachability changes.