diff options
author | Avery Pennarun <apenwarr@gmail.com> | 2010-05-02 05:39:17 -0400 |
---|---|---|
committer | Avery Pennarun <apenwarr@gmail.com> | 2010-05-02 05:39:17 -0400 |
commit | 6c2dc54b9e93338904495106e34f32eacfb19d94 (patch) | |
tree | a907d1b795b5857f24cbc3cc0fafa76f6de552ce | |
parent | 5d1390927d7ac323ca33acc9ed91c1a7738bf752 (diff) |
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.
-rw-r--r-- | server.py | 2 | ||||
-rw-r--r-- | ssnet.py | 24 |
2 files changed, 17 insertions, 9 deletions
@@ -43,5 +43,5 @@ def main(): for s in handlers: if s.socks & ready: s.callback() - mux.callback() mux.check_fullness() + mux.callback() @@ -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]: |