Expand description
Fallback TCP handler registry (tsnet.Server.RegisterFallbackTCPHandler parity).
Fallback TCP handler registry (tsnet.Server.RegisterFallbackTCPHandler parity).
Go tsnet lets an embedder register a callback consulted for every inbound TCP flow that
matches no explicit Listener. The callback inspects the (src, dst) tuple and either
declines (intercept = false, try the next handler) or claims the flow (intercept = true),
optionally returning a per-connection handler. This module is the faithful equivalent on the
application netstack.
§How an unmatched flow is observed
smoltcp RSTs an inbound SYN to a port with no matching listener inside its ingress loop,
before any of our code runs. The single lever it gives us is the same one
ts_forwarder::all_port uses: a raw (Ipv4, Tcp) socket whose accepts() sets
handled_by_raw_socket = true, which suppresses that RST and hands us a copy of every
inbound TCP packet. We read each SYN’s destination port and lazily materialize a per-port
any-IP listener; the peer’s SYN retransmit is then accepted by that listener and dispatched to
the registered handlers.
§The observer runs only while a handler is registered
Because the raw observer suppresses the unmatched-SYN RST for the whole netstack, it must not be running when there are no fallback handlers — otherwise a node with zero handlers would stop RSTing unrouted SYNs (silently swallowing them) instead of cleanly refusing. So the observer is started on the first registration and torn down on the last deregistration, leaving the default fail-closed RST behavior pristine whenever no handler is installed.
§Anti-leak
The raw observer never creates a host socket and never dials anything; it only learns ports.
Every accepted flow is handed to the embedder’s own handler over the overlay netstack — never a
host socket. Ports already owned by an explicit tcp_listener are skipped (queried read-only
via CreateSocket::bound_tcp_ports) so a fallback listener never competes with a real one. A
flow no handler claims is closed (fail-closed), never direct-dialed. IPv4-only.
Structs§
- Fallback
TcpHandle - RAII deregistration handle for a fallback callback (mirrors the
unregister func()Go returns). - Fallback
TcpManager - Manages the fallback-TCP handler registry and the lifecycle of the raw-SYN observer.
Type Aliases§
- Fallback
Conn Future - The future returned by a
FallbackConnHandler; spawned to service one accepted flow. - Fallback
Conn Handler - Per-connection handler returned by a fallback callback that claims a flow. Consumes the
accepted overlay
TcpStreamand returns a future the manager spawns. Mirrors thefunc(net.Conn)Gotsnetreturns from its fallback callback. - Fallback
Decision - A fallback callback’s decision for one
(src, dst)flow: an optional per-connection handler and whether this callback intercepts the flow. Matches Go’s(handler func(net.Conn), intercept bool):