diff options
author | Avery Pennarun <apenwarr@gmail.com> | 2011-01-25 21:30:56 -0800 |
---|---|---|
committer | Avery Pennarun <apenwarr@gmail.com> | 2011-01-25 22:11:28 -0800 |
commit | e7a19890aa579e94dc99cbd662bd5ed598d642fd (patch) | |
tree | 58c429de30c64bac733b3ece21ca8a8262c6579d | |
parent | 675f19f57e23a640cea64b79f2c368f233f6660b (diff) | |
parent | d9b1bb52e5e994f5d3c9c3a77efea5e81910b6ea (diff) |
Merge branch 'fullness'
Tests with speedtest.net to a linode.com server:
Downstream Upstream
No sshuttle 1.25 Mbit/s 0.55 Mbit/s
Default 0.75 Mbit/s 0.51 Mbit/s
--no-latency-control 1.25 Mbit/s 0.55 Mbit/s
* fullness:
man page for the --no-latency-control option.
options: remove unused 'exe' parameter
options.py: generate usage string correctly for no-* options.
Implement the optional fullness checking a bit more like I like it.
new option to disable fullness checking
-rw-r--r-- | client.py | 15 | ||||
-rwxr-xr-x | main.py | 5 | ||||
-rw-r--r-- | options.py | 9 | ||||
-rw-r--r-- | server.py | 4 | ||||
-rw-r--r-- | ssh.py | 14 | ||||
-rw-r--r-- | sshuttle.md | 20 |
6 files changed, 48 insertions, 19 deletions
@@ -189,7 +189,8 @@ class FirewallClient: raise Fatal('cleanup: %r returned %d' % (self.argv, rv)) -def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets, +def _main(listener, fw, ssh_cmd, remotename, python, latency_control, + seed_hosts, auto_nets, syslog, daemon): handlers = [] if helpers.verbose >= 1: @@ -200,7 +201,8 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets, try: (serverproc, serversock) = ssh.connect(ssh_cmd, remotename, python, - stderr=ssyslog._p and ssyslog._p.stdin) + stderr=ssyslog._p and ssyslog._p.stdin, + options=dict(latency_control=latency_control)) except socket.error, e: if e.args[0] == errno.EPIPE: raise Fatal("failed to establish ssh session (1)") @@ -300,11 +302,13 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets, raise Fatal('server died with error code %d' % rv) ssnet.runonce(handlers, mux) + if latency_control: + mux.check_fullness() mux.callback() - mux.check_fullness() -def main(listenip, ssh_cmd, remotename, python, seed_hosts, auto_nets, +def main(listenip, ssh_cmd, remotename, python, latency_control, + seed_hosts, auto_nets, subnets_include, subnets_exclude, syslog, daemon, pidfile): if syslog: ssyslog.start_syslog() @@ -344,7 +348,8 @@ def main(listenip, ssh_cmd, remotename, python, seed_hosts, auto_nets, try: return _main(listener, fw, ssh_cmd, remotename, - python, seed_hosts, auto_nets, syslog, daemon) + python, latency_control, + seed_hosts, auto_nets, syslog, daemon) finally: try: if daemon: @@ -60,6 +60,7 @@ x,exclude= exclude this subnet (can be used more than once) v,verbose increase debug message verbosity e,ssh-cmd= the command to use to connect to the remote [ssh] seed-hosts= with -H, use these hostnames for initial scan (comma-separated) +no-latency-control sacrifice latency to improve bandwidth benchmarks D,daemon run in the background as a daemon syslog send log messages to syslog (default if you use --daemon) pidfile= pidfile name (only if using --daemon) [./sshuttle.pid] @@ -67,7 +68,7 @@ server (internal use only) firewall (internal use only) hostwatch (internal use only) """ -o = options.Options('sshuttle', optspec) +o = options.Options(optspec) (opt, flags, extra) = o.parse(sys.argv[1:]) if opt.daemon: @@ -78,6 +79,7 @@ try: if opt.server: if len(extra) != 0: o.fatal('no arguments expected') + server.latency_control = opt.latency_control sys.exit(server.main()) elif opt.firewall: if len(extra) != 1: @@ -108,6 +110,7 @@ try: opt.ssh_cmd, remotename, opt.python, + opt.latency_control, sh, opt.auto_nets, parse_subnets(includes), @@ -76,9 +76,8 @@ class Options: By default, the parser function is getopt.gnu_getopt, and the abort behaviour is to exit the program. """ - def __init__(self, exe, optspec, optfunc=getopt.gnu_getopt, + def __init__(self, optspec, optfunc=getopt.gnu_getopt, onabort=_default_onabort): - self.exe = exe self.optspec = optspec self._onabort = onabort self.optfunc = optfunc @@ -122,8 +121,8 @@ class Options: defval = None flagl = flags.split(',') flagl_nice = [] - for f in flagl: - f,dvi = _remove_negative_kv(f, _intify(defval)) + for _f in flagl: + f,dvi = _remove_negative_kv(_f, _intify(defval)) self._aliases[f] = _remove_negative_k(flagl[0]) self._hasparms[f] = has_parm self._defaults[f] = dvi @@ -135,7 +134,7 @@ class Options: self._aliases[f_nice] = _remove_negative_k(flagl[0]) self._longopts.append(f + (has_parm and '=' or '')) self._longopts.append('no-' + f) - flagl_nice.append('--' + f) + flagl_nice.append('--' + _f) flags_nice = ', '.join(flagl_nice) if has_parm: flags_nice += ' ...' @@ -111,6 +111,7 @@ def main(): helpers.logprefix = ' s: ' else: helpers.logprefix = 'server: ' + debug1('latency control setting = %r\n' % latency_control) routes = list(list_routes()) debug1('available routes:\n') @@ -172,5 +173,6 @@ def main(): raise Fatal('hostwatch exited unexpectedly: code 0x%04x\n' % rv) ssnet.runonce(handlers, mux) - mux.check_fullness() + if latency_control: + mux.check_fullness() mux.callback() @@ -14,14 +14,16 @@ def readfile(name): raise Exception("can't find file %r in any of %r" % (name, path)) -def empackage(z, filename): +def empackage(z, filename, data=None): (path,basename) = os.path.split(filename) - content = z.compress(readfile(filename)) + if not data: + data = readfile(filename) + content = z.compress(data) content += z.flush(zlib.Z_SYNC_FLUSH) - return '%s\n%d\n%s' % (basename,len(content), content) + return '%s\n%d\n%s' % (basename, len(content), content) -def connect(ssh_cmd, rhostport, python, stderr): +def connect(ssh_cmd, rhostport, python, stderr, options): main_exe = sys.argv[0] portl = [] @@ -52,7 +54,9 @@ def connect(ssh_cmd, rhostport, python, stderr): z = zlib.compressobj(1) content = readfile('assembler.py') - content2 = (empackage(z, 'helpers.py') + + optdata = ''.join("%s=%r\n" % (k,v) for (k,v) in options.items()) + content2 = (empackage(z, 'cmdline_options.py', optdata) + + empackage(z, 'helpers.py') + empackage(z, 'compat/ssubprocess.py') + empackage(z, 'ssnet.py') + empackage(z, 'hostwatch.py') + diff --git a/sshuttle.md b/sshuttle.md index c52c6cd..6168740 100644 --- a/sshuttle.md +++ b/sshuttle.md @@ -1,6 +1,6 @@ -% sshuttle(8) Sshuttle 0.44 +% sshuttle(8) Sshuttle 0.46 % Avery Pennarun <apenwarr@gmail.com> -% 2010-12-31 +% 2011-01-25 # NAME @@ -109,6 +109,22 @@ entire subnet to the VPN. if you use this option to give it a few names to start from. +--no-latency-control +: sacrifice latency to improve bandwidth benchmarks. ssh + uses really big socket buffers, which can overload the + connection if you start doing large file transfers, + thus making all your other sessions inside the same + tunnel go slowly. Normally, sshuttle tries to avoid + this problem using a "fullness check" that allows only + a certain amount of outstanding data to be buffered at + a time. But on high-bandwidth links, this can leave a + lot of your bandwidth underutilized. It also makes + sshuttle seem slow in bandwidth benchmarks (benchmarks + rarely test ping latency, which is what sshuttle is + trying to control). This option disables the latency + control feature, maximizing bandwidth usage. Use at + your own risk. + -D, --daemon : automatically fork into the background after connecting to the remote server. Implies `--syslog`. |