Skip to content

mobydeck/stdio-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

stdio-proxy

A minimal C utility that bridges stdio to a TCP or UDP socket. Designed primarily as an SSH ProxyCommand but useful anywhere you need to tunnel a byte stream over a network connection.

Usage

stdio-proxy [-v] tcp|udp:host:port
Flag Description
-v Verbose — log connection events to stderr
# SSH through an arbitrary TCP host
ssh -o ProxyCommand='stdio-proxy tcp:%h:%p' user@host

# Forward stdin/stdout over UDP
stdio-proxy udp:dns.server:53

How it works

stdin  ──▶  stdio-proxy  ──▶  socket  ──▶  remote
stdout ◀──  stdio-proxy  ◀──  socket  ◀──  remote

A single poll(2) loop multiplexes both directions without threads. When stdin reaches EOF, shutdown(SHUT_WR) sends a TCP half-close (FIN) so the remote server sees end-of-input without the connection being torn down, allowing any pending server response to still arrive. Handles SIGINT/SIGTERM by shutting the socket down cleanly.

Build

Requires GCC and a POSIX libc. Static linking requires glibc-static (RHEL/AlmaLinux: dnf install glibc-static from the CRB repo) or musl-libc-static.

# Dynamic binary (development)
gcc -std=c11 -O2 -o stdio-proxy stdio-proxy.c

# Static binary (default make target)
make

# Static binary via musl (no NSS quirks)
make CC=musl-gcc          # or: make static-musl

The Makefile auto-detects the host architecture and selects the appropriate generic baseline (-march=x86-64 / -march=armv8-a).

Test

Requires Go in PATH (uses the project's existing module).

make test
# or from the repo root:
go test -v ./test/

The test suite compiles a debug binary, then runs 19 integration tests covering argument validation, TCP send/receive, bidirectional echo, TCP half-close, large payloads, and signal handling.