-
Notifications
You must be signed in to change notification settings - Fork 2
TCP proxy with trunking/striping support
License
apankrat/tcp-striper
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Tcp-striper ----------- (from "to stripe") -- SUMMARY -- Have +--------+ +--------+ | | | | | Peer A | <------[ TCP connection ]------> | Peer B | | | | | +--------+ +--------+ Want +--------+ +---+ +---+ +--------+ | | | | <----> | | | | | Peer A | <--> | P | <----> | P | <--> | Peer B | | | | | <----> | | | | +--------+ +---+ +---+ +--------+ That is - to splice a pair of intermediate proxies into a TCP connection and then have them talk to each other via multiple TCP streams in parallel. In particular, if an active stream between the proxies gets congested, they would switch to another non-congested stream. This should help proxies push more traffic through if/when there are per-stream caps on the route between A and B. Like the ones that certain cable provider has ;) -- STATUS -- 26/09/14 Added datagram pipe - that is a transport layer that implements standard pipe semantics *and* preserves boundaries of packets send()/recv() by the peers. If A sends out 3, 123, 4 bytes, then with plain TCP its peer may end up receiving a single packet of 130 bytes. However, if they are talking over a datagram pipe, the recv() is guaranteed to retrieve 3 chunks, respectively - 3, 123 and 4 byte in size. To play with this, use 'tcp-proxy'. 1. Start a client-facing proxy first: ./tcp-proxy -c 0.0.0.0:11111 127.0.0.1 22222 This will accept a connection on port 11111, connect out to port 22222 and then wrap all data received from 11111 into datagrams before sending them out to 22222. It will also obviously strip the datagram packaging in reverse direction. 2. Start a server-facing proxy second: ./tcp-proxy -s 0.0.0.0:22222 127.0.0.1:22 This will accept a connection on 22222, use it to speak the datagram protocol with a peer and forward raw payloads to the sshd on port 22. 3. Point your ssh at 11111 and observe the magic - ssh -p 11111 localhost Altogether, the contraption will look like this +--------------+ +--------------------+ | ssh -p 11111 | -- ssh/tcp --> | tcp-proxy -c 11111 | +--------------+ +--------------------+ | | ssh/dgm/tcp | v +--------------+ +--------------------+ | sshd | <-- ssh/tcp -- | tcp-proxy -s 22222 | +--------------+ +--------------------+ which is getting close to the original goal. All that's left is to replace "datagram" protocol with "striped" delivery across several connections. 20/09/14 Formalized io_pipe semantics, see /io/inc/libp/io_pipe.h for details. In particular, added support for send_fin() cases where FIN cannot be sent out right away. Cleaned up io_bridge code. 15/09/14 -- 1 -- Re-organized the code as follows: /core - basic type imports, macros, assert() and logging /data - data containers (list and unbalanced map for now) /evl - event loop (select-based for now) /io - IO pipes & Co. - that's where the magic is /sys - the platform glue (socket interface, termio, etc) Each of these has the following structure: ./inc/libp/ <portable-headers> ./inc.$OS/libp/ <os-specific-version-of-the-same> ./src/ <portable-sources> ./src.$OS <os-specific-sources> Then, setting INCLUDE path to ./inc.linux, ./inc and will make the compiler pick an OS-specific version of a header when it encounters #include <libp/foo.h> if such version is present. Otherwise it falls back to a generic portable version. See Makefile for details. -- 2 -- The bestest part is in the /io. The io_pipe interface is a stateful IO abstraction based on TCP, but also allowing extension of the send/recv behavior. For example, a pipe of certain type can provide datagram framing, another type - SSL encryption, third - atomic send() behavior, etc. So you could attach these pipes one to another and get a a reliable encrypted datagram-based connection. Moreover, it becomes possible to write a generalized bridge between any two pipes, which reads from one, writes to another, minds the congestion and properly handles passing of the FINs between the peers. That's io_bridge. This is what tcp-striper does at the moment - it's a simple TCP proxy that accepts a connection on 0.0.0.0:55555, opens another one to 127.0.0.1:22 and then just bridges them together. In other words, it's a TCP relay. The next step would be to add a special pipe type that maintains 2+ connections towards the peer and then stripes all data passed to it via send() between these connections. On the peer's end there'll be a complimentary pipe that would reverse the striping, re-assemble the data into a single stream and pass it to the app's io_bridge for relaying out. Easy-peasy. 28/08/14 * Initial public offering (via github upload) 27/08/14 * Simple TCP proxy with tracking of per-leg congestion (proxy_types.*) 26/08/14 * Select-based event loop (event_loop/*) 25/08/14 * Abstracted socket API (glue/*/socket.h) * Basic data containers (map is unbalanced!) * Basic app scaffolding (asserts, types, macros) * Makefile -------------------------------------------------------------- Work in progress, a weekend project. --------------------------------------------------------------
About
TCP proxy with trunking/striping support
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published