# HG changeset patch # User Matt Johnston # Date 1185291623 0 # Node ID 9c61e7af0156fc185381e754372796c47dcfb0d7 # Parent 278805938dcfa70eb0c238d1263a284fd44758c7 Rearrange the channel buffer sizes into three neat use-editable values in options.h. Increasing RECV_MAX_WINDOW gives big network performance increases - even with the present buffers (which haven't changed) it performs a lot better. Next step is to make the window size a cmdline option. diff -r 278805938dcf -r 9c61e7af0156 channel.h --- a/channel.h Thu Jul 19 15:54:18 2007 +0000 +++ b/channel.h Tue Jul 24 15:40:23 2007 +0000 @@ -45,16 +45,8 @@ /* Not a real type */ #define SSH_OPEN_IN_PROGRESS 99 -#define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11 - connection, so can't be _too_ small */ - #define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */ -#define RECV_MAXWINDOW 8000 /* tweak */ -#define RECV_WINDOWEXTEND 1000 /* We send a "window extend" every - RECV_WINDOWEXTEND bytes */ -#define RECV_MAXPACKET RECV_MAXWINDOW /* tweak */ - struct ChanType; struct Channel { diff -r 278805938dcf -r 9c61e7af0156 cli-chansession.c --- a/cli-chansession.c Thu Jul 19 15:54:18 2007 +0000 +++ b/cli-chansession.c Tue Jul 24 15:40:23 2007 +0000 @@ -350,7 +350,7 @@ channel->errfd = STDERR_FILENO; setnonblocking(STDERR_FILENO); - channel->extrabuf = cbuf_new(RECV_MAXWINDOW); + channel->extrabuf = cbuf_new(RECV_MAX_WINDOW); if (cli_opts.wantpty) { send_chansess_pty_req(channel); diff -r 278805938dcf -r 9c61e7af0156 common-channel.c --- a/common-channel.c Thu Jul 19 15:54:18 2007 +0000 +++ b/common-channel.c Tue Jul 24 15:40:23 2007 +0000 @@ -150,11 +150,11 @@ newchan->await_open = 0; newchan->flushing = 0; - newchan->writebuf = cbuf_new(RECV_MAXWINDOW); + newchan->writebuf = cbuf_new(RECV_MAX_WINDOW); newchan->extrabuf = NULL; /* The user code can set it up */ - newchan->recvwindow = RECV_MAXWINDOW; + newchan->recvwindow = RECV_MAX_WINDOW; newchan->recvdonelen = 0; - newchan->recvmaxpacket = RECV_MAXPACKET; + newchan->recvmaxpacket = RECV_MAX_PAYLOAD_LEN; ses.channels[i] = newchan; ses.chancount++; @@ -421,7 +421,7 @@ channel->recvdonelen = 0; } - dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); + dropbear_assert(channel->recvwindow <= RECV_MAX_WINDOW); dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); dropbear_assert(channel->extrabuf == NULL || channel->recvwindow <= cbuf_getavail(channel->extrabuf)); @@ -710,7 +710,7 @@ dropbear_assert(channel->recvwindow >= datalen); channel->recvwindow -= datalen; - dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); + dropbear_assert(channel->recvwindow <= RECV_MAX_WINDOW); TRACE(("leave recv_msg_channel_data")) } @@ -727,10 +727,10 @@ incr = buf_getint(ses.payload); TRACE(("received window increment %d", incr)) - incr = MIN(incr, MAX_TRANS_WIN_INCR); + incr = MIN(incr, TRANS_MAX_WIN_INCR); channel->transwindow += incr; - channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW); + channel->transwindow = MIN(channel->transwindow, TRANS_MAX_WINDOW); } @@ -769,9 +769,9 @@ remotechan = buf_getint(ses.payload); transwindow = buf_getint(ses.payload); - transwindow = MIN(transwindow, MAX_TRANS_WINDOW); + transwindow = MIN(transwindow, TRANS_MAX_WINDOW); transmaxpacket = buf_getint(ses.payload); - transmaxpacket = MIN(transmaxpacket, MAX_TRANS_PAYLOAD_LEN); + transmaxpacket = MIN(transmaxpacket, TRANS_MAX_PAYLOAD_LEN); /* figure what type of packet it is */ if (typelen > MAX_NAME_LEN) { @@ -970,8 +970,8 @@ buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN); buf_putstring(ses.writepayload, type->name, strlen(type->name)); buf_putint(ses.writepayload, chan->index); - buf_putint(ses.writepayload, RECV_MAXWINDOW); - buf_putint(ses.writepayload, RECV_MAXPACKET); + buf_putint(ses.writepayload, RECV_MAX_WINDOW); + buf_putint(ses.writepayload, RECV_MAX_PAYLOAD_LEN); TRACE(("leave send_msg_channel_open_init()")) return DROPBEAR_SUCCESS; diff -r 278805938dcf -r 9c61e7af0156 common-session.c --- a/common-session.c Thu Jul 19 15:54:18 2007 +0000 +++ b/common-session.c Tue Jul 24 15:40:23 2007 +0000 @@ -69,7 +69,7 @@ kexfirstinitialise(); /* initialise the kex state */ - ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN); + ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN); ses.transseq = 0; ses.readbuf = NULL; diff -r 278805938dcf -r 9c61e7af0156 options.h --- a/options.h Thu Jul 19 15:54:18 2007 +0000 +++ b/options.h Tue Jul 24 15:40:23 2007 +0000 @@ -216,6 +216,20 @@ * shell/sftp session etc. */ /* #define LOG_COMMANDS */ +/* Window size limits. These tend to be a trade-off between memory + usage and network performance: */ +/* Size of the network receive window. This amount of memory is allocated + as a per-channel receive buffer. Increasing this value can make a + significant difference to network performance. */ +#define RECV_MAX_WINDOW 8192 +/* Maximum size of a received SSH data packet - this _MUST_ be >= 32768 + in order to interoperate with other implementations */ +#define RECV_MAX_PAYLOAD_LEN 32768 +/* Maximum size of a transmitted data packet - this can be any value, + though increasing it may not make a significant difference. */ +#define TRANS_MAX_PAYLOAD_LEN 16384 + + /******************************************************************* * You shouldn't edit below here unless you know you need to. *******************************************************************/ @@ -317,16 +331,19 @@ #define MAX_PROPOSED_ALGO 20 /* size/count limits */ +#define MIN_PACKET_LEN 16 -#define MAX_PACKET_LEN 35000 -#define MIN_PACKET_LEN 16 -#define MAX_PAYLOAD_LEN 32768 +#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100))) -#define MAX_TRANS_PAYLOAD_LEN 32768 -#define MAX_TRANS_PACKET_LEN (MAX_TRANS_PAYLOAD_LEN+50) +/* for channel code */ +#define TRANS_MAX_WINDOW 500000000 /* 500MB is sufficient, stopping overflow */ +#define TRANS_MAX_WIN_INCR 500000000 /* overflow prevention */ -#define MAX_TRANS_WINDOW 500000000 /* 500MB is sufficient, stopping overflow */ -#define MAX_TRANS_WIN_INCR 500000000 /* overflow prevention */ +#define RECV_WINDOWEXTEND (RECV_MAX_WINDOW / 3) /* We send a "window extend" every + RECV_WINDOWEXTEND bytes */ + +#define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11 + connection, so can't be _too_ small */ #define MAX_STRING_LEN 1400 /* ~= MAX_PROPOSED_ALGO * MAX_NAME_LEN, also is the max length for a password etc */ diff -r 278805938dcf -r 9c61e7af0156 packet.c --- a/packet.c Thu Jul 19 15:54:18 2007 +0000 +++ b/packet.c Tue Jul 24 15:40:23 2007 +0000 @@ -212,7 +212,7 @@ buf_setpos(ses.readbuf, blocksize); /* check packet length */ - if ((len > MAX_PACKET_LEN) || + if ((len > RECV_MAX_PACKET_LEN) || (len < MIN_PACKET_LEN + macsize) || ((len - macsize) % blocksize != 0)) { dropbear_exit("bad packet size %d", len); @@ -281,7 +281,7 @@ /* payload length */ /* - 4 - 1 is for LEN and PADLEN values */ len = ses.decryptreadbuf->len - padlen - 4 - 1; - if ((len > MAX_PAYLOAD_LEN) || (len < 1)) { + if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) { dropbear_exit("bad packet size"); }