Skip to content

auto-forward: UDP port forwarding (detect /proc/net/udp + datagram relay) #192

Description

@pofallon

Tracked deferral from up --auto-forward (spec 015-auto-forward-ports, task T058; shipped in #188). v1 is TCP-only; this adds UDP.

Goal / acceptance

UDP listeners inside the container are detected and relayed to the host.

Hidden issues / gotchas

  • Detection: the parser (crates/core/src/port_forward/detect.rs) reads /proc/net/tcp{,6} only. UDP needs /proc/net/udp{,6}, which has a different state model — there is no LISTEN state for UDP (the st field isn't 0A). You'd treat a bound UDP socket (often st == 07, with a wildcard/loopback local address) as "forwardable," which is fuzzier than TCP LISTEN and risks false positives (transient client sockets).
  • Relay is fundamentally different. The current relay is a bidirectional byte stream over docker exec -i (nc/socat//dev/tcp). UDP is datagram + connectionless: you need per-source-address pseudo-session tracking, datagram framing, and timeouts. nc//dev/tcp can't do this; you'd need socat UDP-LISTEN:...,fork UDP:127.0.0.1:port (so socat becomes effectively required for UDP — narrows the relay-program fallback), or the eventual embedded agent (auto-forward: persistent in-container multiplexing relay agent (drop per-connection docker exec) #190) extended for UDP.
  • Host side: bind a tokio::net::UdpSocket instead of TcpListener; the registry/Allocation type currently hands back a std::net::TcpListener — needs a transport-aware allocation.
  • Reporting/contract: PortEvent/registry have no protocol/transport field distinguishing TCP vs UDP; would need one to disambiguate (and to avoid colliding a TCP:3000 and UDP:3000 in the host-global registry).
  • Datagram semantics over docker exec add latency/packet-boundary concerns that don't exist for TCP.

Recommended path forward

  1. Add a transport: Tcp|Udp dimension to DetectedPort/ForwardSpec/RegistryEntry/PortEvent (schema bump).
  2. Parse /proc/net/udp{,6} for bound sockets; conservatively forward only wildcard/loopback binds; document the false-positive tradeoff.
  3. UDP relay via socat UDP-LISTEN:<host>,fork,reuseaddr UDP:127.0.0.1:<cport> (fail-fast if socat absent and no embedded agent); host side uses UdpSocket.
  4. Docker integration test with a UDP echo server (socat/nc -u) inside the container.

Notes

Probably best done after the embedded relay agent (#190), which can carry UDP cleanly; until then UDP would hard-depend on socat in the image.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions