Pipes a TCP socket and a CONNECT tunnel together, both directions at once,
until either side ends. Useful at both ends: a client joins a local
application's socket to the tunnel, an exit joins the tunnel to the
destination's.
Backpressure both ways. Socket → tunnel: the socket is paused until the
tunnel's write() resolves, which it does only when the IBB window has
room. Tunnel → socket: nothing more is read from the tunnel while the
socket's buffer is over its high-water mark, and the unread tunnel stops
acking — so a slow reader on either side slows the sender on the other,
end to end, instead of filling someone's memory.
No half-close. The tunnel has none, so when the TCP side ends its
sending, the tunnel is closed — after what the socket already sent has
been delivered — and when the tunnel ends, the socket is ended.
Pipes a TCP socket and a CONNECT tunnel together, both directions at once, until either side ends. Useful at both ends: a client joins a local application's socket to the tunnel, an exit joins the tunnel to the destination's.