iocopy
An async io engine in 54 lines of C
Motivation
tcpforward
Common uses
- remote assistance to someone behind a NAT
- port reassignment, proxying, tunneling
- see the tcpforward article for more
Example
tcpforward -l 0.0.0.0:443 -c localhost:22
Motivation
tcpforward has a long-standing bug...
Motivation
tcpforward has a long-standing bug...
- it's written in Perl
- it should be written in C
- even better: rewrite as a small, generic unix program
- reuse other programs
- less is more!
Motivation
54 lines of code should be enough for anyone, right?
Specification
What can we reuse?
- ucspi-tcp suite
- sockets: addressing, connecting, accepting, listening
What's still missing?
- the core async io engine in tcpforward
- takes pairs of (rfd,wfd) file descriptors
- uses non-blocking i/o to copy data from rfd to wfd
Specification
Basic operation: copy data between pairs of file descriptors.
What would a command line interface to this look like?
Specification
Basic operation: copy data between pairs of file descriptors.
What would a command line interface to this look like?
iocopy [options] rfd1 wfd1 rfd2 wfd2 ...
Specification
Q: What's an equivalent UNIX program for this invocation?
iocopy 0 1
Specification
Q: What's an equivalent UNIX program for this invocation?
iocopy 0 1
A: cat(1), dd(1), others
Specification
Here's another invocation:
iocopy v 0 7 6 1
Q: What is the significance of descriptors 6 and 7?
Implementation
The async io engine must do typical producer-consumer stuff:
- buffer data from rfd until wfd becomes writable
- buffer is empty? mask writable event
- buffer is non-empty? mask readable event
- shutdown the read side on eof
- shutdown the write side after eof and buffer drain
- exit after all channels get eof and are drained
Implementation
- C code
- only uses the standard C library
- nothing fancy like libevent or libev
- just a select(2) loop
Implementation
Not obfuscated C per se... Some stats:
- 8 lines of #includes (boo...)
- 8 lines of argument processing and setup
- 24 lines of async io engine code
- 13 lines of declarations, whitespace etc
- ...checks for errors and dies with appropriate messages!
Demo