If the server was having trouble starting, we would print a lot of
unnecessary stuff from iptables. We shouldn't even have bothered *starting*
iptables if the server was dead anyway.
Previous versions depended on having 'sudo' in your PATH. Now that we can
feel safe that --iptables will clean up properly when you exit, and it
doesn't need to authenticate twice, the advantages of sudo aren't strictly
needed. Good old 'su' is a reasonable fallback - and everybody has it,
which is nice.
Unfortunately su doesn't let you redirect stdin, so I had to play a stupid
fd trick to make it work.
Now the sudo iptables subprocess persists for the entire life of sshuttle.
The benefits of this are:
- no need to authenticate again at shutdown (failure of which could cause us
to not clean up iptables)
- if the main process dies unexpectedly, iptables still gets cleaned up
- the password prompt can happen *before* starting the ssh/server process,
which means it'll stand out and the password prompt won't be overwritten.
It seems ssh is kind of stupid and uses a really big SO_SNDBUF (hundreds of
kbytes). Thus, we can't depend on the socket's output buffer to limit our
latency down to something reasonable. Instead, limit the amount of data we
can send in a single round trip.
Now if we aren't given an explicit port, we always initiate the port search
at 12300 and count upward looking for an available port.
Normally the kernel will assign us a random port, but that's not ideal
in our case because we'd like to use the same port numbers whenever
possible; that avoids piling up crap inside iptables in the (hopefully
unlikely) event that we die without cleaning up correctly.
When regenerating outgoing connections, we set TTL=42 to prevent re-proxying
of requests. That's a little hacky, but at least it avoids infinite loops.