Skip to main content

Module fallback_tcp

Module fallback_tcp 

Source
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§

FallbackTcpHandle
RAII deregistration handle for a fallback callback (mirrors the unregister func() Go returns).
FallbackTcpManager
Manages the fallback-TCP handler registry and the lifecycle of the raw-SYN observer.

Type Aliases§

FallbackConnFuture
The future returned by a FallbackConnHandler; spawned to service one accepted flow.
FallbackConnHandler
Per-connection handler returned by a fallback callback that claims a flow. Consumes the accepted overlay TcpStream and returns a future the manager spawns. Mirrors the func(net.Conn) Go tsnet returns from its fallback callback.
FallbackDecision
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):