mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-06-19 08:17:45 +02: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:
parent
5d1390927d
commit
6c2dc54b9e
@ -43,5 +43,5 @@ def main():
|
|||||||
for s in handlers:
|
for s in handlers:
|
||||||
if s.socks & ready:
|
if s.socks & ready:
|
||||||
s.callback()
|
s.callback()
|
||||||
mux.callback()
|
|
||||||
mux.check_fullness()
|
mux.check_fullness()
|
||||||
|
mux.callback()
|
||||||
|
24
ssnet.py
24
ssnet.py
@ -215,6 +215,7 @@ class Mux(Handler):
|
|||||||
self.want = 0
|
self.want = 0
|
||||||
self.inbuf = ''
|
self.inbuf = ''
|
||||||
self.outbuf = []
|
self.outbuf = []
|
||||||
|
self.fullness = 0
|
||||||
self.too_full = False
|
self.too_full = False
|
||||||
self.send(0, CMD_PING, 'chicken')
|
self.send(0, CMD_PING, 'chicken')
|
||||||
|
|
||||||
@ -231,20 +232,24 @@ class Mux(Handler):
|
|||||||
return sum(len(b) for b in self.outbuf)
|
return sum(len(b) for b in self.outbuf)
|
||||||
|
|
||||||
def check_fullness(self):
|
def check_fullness(self):
|
||||||
self.too_full = (self.amount_queued() > 32768)
|
if self.fullness > 65536:
|
||||||
ob = []
|
self.too_full = True
|
||||||
for b in self.outbuf:
|
#ob = []
|
||||||
(s1,s2,c) = struct.unpack('!ccH', b[:4])
|
#for b in self.outbuf:
|
||||||
ob.append(c)
|
# (s1,s2,c) = struct.unpack('!ccH', b[:4])
|
||||||
log('outbuf: %d %r\n' % (self.amount_queued(), ob,))
|
# ob.append(c)
|
||||||
|
#log('outbuf: %d %r\n' % (self.amount_queued(), ob))
|
||||||
|
|
||||||
def send(self, channel, cmd, data):
|
def send(self, channel, cmd, data):
|
||||||
data = str(data)
|
data = str(data)
|
||||||
assert(len(data) <= 65535)
|
assert(len(data) <= 65535)
|
||||||
p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data
|
p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data
|
||||||
self.outbuf.append(p)
|
self.outbuf.append(p)
|
||||||
debug2(' > channel=%d cmd=%s len=%d\n'
|
debug2(' > channel=%d cmd=%s len=%d (fullness=%d)\n'
|
||||||
% (channel, cmd_to_name[cmd], len(data)))
|
% (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):
|
def got_packet(self, channel, cmd, data):
|
||||||
debug2('< channel=%d cmd=%s len=%d\n'
|
debug2('< channel=%d cmd=%s len=%d\n'
|
||||||
@ -253,6 +258,8 @@ class Mux(Handler):
|
|||||||
self.send(0, CMD_PONG, data)
|
self.send(0, CMD_PONG, data)
|
||||||
elif cmd == CMD_PONG:
|
elif cmd == CMD_PONG:
|
||||||
debug2('received PING response\n')
|
debug2('received PING response\n')
|
||||||
|
self.too_full = False
|
||||||
|
self.fullness = 0
|
||||||
elif cmd == CMD_EXIT:
|
elif cmd == CMD_EXIT:
|
||||||
self.ok = False
|
self.ok = False
|
||||||
elif cmd == CMD_CONNECT:
|
elif cmd == CMD_CONNECT:
|
||||||
@ -267,6 +274,7 @@ class Mux(Handler):
|
|||||||
self.wsock.setblocking(False)
|
self.wsock.setblocking(False)
|
||||||
if self.outbuf and self.outbuf[0]:
|
if self.outbuf and self.outbuf[0]:
|
||||||
wrote = _nb_clean(os.write, self.wsock.fileno(), 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:
|
if wrote:
|
||||||
self.outbuf[0] = self.outbuf[0][wrote:]
|
self.outbuf[0] = self.outbuf[0][wrote:]
|
||||||
while self.outbuf and not self.outbuf[0]:
|
while self.outbuf and not self.outbuf[0]:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user