changeset 448:9c61e7af0156

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.
author Matt Johnston <matt@ucc.asn.au>
date Tue, 24 Jul 2007 15:40:23 +0000
parents 278805938dcf
children 3e6c536bc023
files channel.h cli-chansession.c common-channel.c common-session.c options.h packet.c
diffstat 6 files changed, 39 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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 {
--- 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);
--- 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;
--- 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;
--- 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 */
--- 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");
 	}