Expand description
§dig-nat — abstract NAT traversal for DIG Node peer connections
One API, connect, establishes a mutually-authenticated (mTLS) connection to a peer using
the best available NAT-traversal method, transparently. The caller never chooses the method —
they describe the peer once and get back a verified PeerConnection; which technique got there
is reported for observability but is not something the caller handles.
§Traversal order (first success wins, relay last)
Internally the strategy attempts, in this order:
- Direct — peer publicly reachable / already port-forwarded (
method::direct) - UPnP/IGD port mapping (
method::upnp) - NAT-PMP (RFC 6886,
method::natpmp) - PCP (RFC 6887,
method::pcp) - Relay-coordinated hole-punch (RLY-007,
method::hole_punch) - Relayed transport via
relay.dig.net— the LAST resort (relay)
stun (RFC 5389) discovers this node’s reflexive address for candidate advertisement +
hole-punch coordination.
§Streaming-first + multiplexed transport
Whatever tier establishes the connection, the result is uniform: a PeerConnection wrapping a
single mTLS byte stream in yamux multiplexing. The caller opens many cheap concurrent
logical streams (PeerConnection::open_stream) with no head-of-line blocking, and
byte-range streams (PeerConnection::open_range_stream) scoped to [offset, len) of a
resource — so a downloader fetches DIFFERENT ranges from DIFFERENT peers in parallel and
reassembles. The API is streaming (read bytes as they arrive), never buffer-the-whole-response.
§Identity + mTLS
Every peer connection is mutual TLS. A peer’s identity is peer_id = SHA-256(TLS SPKI DER)
(identity, matching dig-gossip). The dial presents this node’s certificate and the
mtls::PeerIdPinningVerifier rejects the handshake unless the remote’s derived peer_id
matches the peer::PeerTarget::peer_id the caller asked for — so the transport is
self-authenticating.
§Graceful fallback + relay resilience
Each method is bounded by a per-method timeout; if ALL fail, connect returns a clear
NatError::AllMethodsFailed (never panics, never hangs). The relay client — used both as
the last-resort transport and as a node’s persistent reachability channel — establishes and
maintains its session with keepalive + capped-exponential-backoff reconnect, tolerates the relay
being down (retries in the background, never crashes the node), logs once per state change, and
honours the DIG_RELAY_URL=off opt-out. See relay::RelayStatus.
§Example
let peer = PeerTarget::with_addr(peer_id, addr, "DIG_MAINNET");
let conn = connect(&peer, &identity, &NatConfig::default()).await?;
println!("connected to {} via {:?}", conn.peer_id, conn.method);Re-exports§
pub use config::LocalIdentity;pub use config::NatConfig;pub use config::NatConfigBuilder;pub use error::MethodError;pub use error::NatError;pub use identity::peer_id_from_leaf_cert_der;pub use identity::peer_id_from_tls_spki_der;pub use identity::PeerId;pub use method::TraversalKind;pub use method::TraversalMethod;pub use mux::AvailabilityAnswer;pub use mux::AvailabilityItem;pub use mux::AvailabilityRequest;pub use mux::AvailabilityResponse;pub use mux::PeerSession;pub use mux::PeerStream;pub use mux::RangeFrame;pub use mux::RangeRequest;pub use peer::PeerConnection;pub use peer::PeerTarget;
Modules§
- config
- Connection configuration — the local identity, relay endpoint, enabled methods, and timeouts
that shape a
crate::connectcall. Built with a fluent builder; the caller never selects the traversal method (only which ones are enabled). - dialer
- The production
Dialer— performs the real rustls mTLS dial to a reachable address and returns aPeerConnectionwhose remotepeer_idhas been verified. - error
- Error + status types for NAT traversal.
- identity
- Peer identity —
peer_id = SHA-256(TLS SubjectPublicKeyInfo DER). - method
- Traversal methods — one module per NAT-traversal technique behind a common
TraversalMethodtrait, plus theTraversalKindtag the strategy orders them by. - mtls
- mTLS layer — every peer connection is a mutually-authenticated TLS stream whose remote
peer_idis verified against the one the caller asked to reach. - mux
- Stream multiplexing + byte-range streams over a single established peer connection.
- peer
- The peer the caller wants to reach (
PeerTarget) and the connection they get back (PeerConnection). - relay
- Relay client — the LAST-RESORT transport + the node’s persistent reachability channel.
- strategy
- The traversal strategy — orders the enabled methods (direct-first, relay-last), tries each with a bounded timeout, and returns the FIRST connection that establishes. This is where “the caller doesn’t choose the method” is realised.
- stun
- Minimal STUN (RFC 5389) client — discover this node’s reflexive (public) transport address.
- wire
- Relay protocol wire types — vendored, byte-identical to
dig-relay’ssrc/wire.rs,dig-node’srelay::RelayMessage, anddig-gossip’srelay_types(requirements RLY-001 through RLY-007).
Functions§
- connect
- Establish a mutually-authenticated connection to
peer, choosing the traversal method transparently (first success wins; relay is the last resort).