1
1
mirror of https://github.com/sshuttle/sshuttle.git synced 2025-02-24 06:11:11 +01:00

More latency fixes: use a PING/PONG pair to limit queue length.

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.
This commit is contained in:
Avery Pennarun 2010-05-02 05:39:17 -04:00
parent 5d1390927d
commit 6c2dc54b9e
2 changed files with 17 additions and 9 deletions

View File

@ -43,5 +43,5 @@ def main():
for s in handlers:
if s.socks & ready:
s.callback()
mux.callback()
mux.check_fullness()
mux.callback()

View File

@ -215,6 +215,7 @@ class Mux(Handler):
self.want = 0
self.inbuf = ''
self.outbuf = []
self.fullness = 0
self.too_full = False
self.send(0, CMD_PING, 'chicken')
@ -231,20 +232,24 @@ class Mux(Handler):
return sum(len(b) for b in self.outbuf)
def check_fullness(self):
self.too_full = (self.amount_queued() > 32768)
ob = []
for b in self.outbuf:
(s1,s2,c) = struct.unpack('!ccH', b[:4])
ob.append(c)
log('outbuf: %d %r\n' % (self.amount_queued(), ob,))
if self.fullness > 65536:
self.too_full = True
#ob = []
#for b in self.outbuf:
# (s1,s2,c) = struct.unpack('!ccH', b[:4])
# ob.append(c)
#log('outbuf: %d %r\n' % (self.amount_queued(), ob))
def send(self, channel, cmd, data):
data = str(data)
assert(len(data) <= 65535)
p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data
self.outbuf.append(p)
debug2(' > channel=%d cmd=%s len=%d\n'
% (channel, cmd_to_name[cmd], len(data)))
debug2(' > channel=%d cmd=%s len=%d (fullness=%d)\n'
% (channel, cmd_to_name[cmd], len(data), self.fullness))
if self.fullness < 32768 and self.fullness+len(data) > 32768:
self.send(0, CMD_PING, 'rttest')
self.fullness += len(data)
def got_packet(self, channel, cmd, data):
debug2('< channel=%d cmd=%s len=%d\n'
@ -253,6 +258,8 @@ class Mux(Handler):
self.send(0, CMD_PONG, data)
elif cmd == CMD_PONG:
debug2('received PING response\n')
self.too_full = False
self.fullness = 0
elif cmd == CMD_EXIT:
self.ok = False
elif cmd == CMD_CONNECT:
@ -267,6 +274,7 @@ class Mux(Handler):
self.wsock.setblocking(False)
if self.outbuf and self.outbuf[0]:
wrote = _nb_clean(os.write, self.wsock.fileno(), self.outbuf[0])
debug2('wrote: %d/%d\n' % (wrote, len(self.outbuf[0])))
if wrote:
self.outbuf[0] = self.outbuf[0][wrote:]
while self.outbuf and not self.outbuf[0]: