New dynamic window patch (with limits)

Michael Stevens stevensm at gmail.com
Thu Jul 15 04:53:23 EST 2004


As before, it is described on our website. This should apply fairly
cleanly to both portable and openbsd ssh.

http://www.psc.edu/networking/hpn-ssh/



Only in openssh-3.8.1p1-dynwindow: Makefile
diff -u openssh-3.8.1p1/buffer.c openssh-3.8.1p1-dynwindow/buffer.c
--- openssh-3.8.1p1/buffer.c	2003-11-21 07:56:47.000000000 -0500
+++ openssh-3.8.1p1-dynwindow/buffer.c	2004-07-12 07:49:29.000000000 -0400
@@ -18,6 +18,12 @@
 #include "buffer.h"
 #include "log.h"
 
+void 
+set_unlimited(Buffer *buffer, int new_value)
+{
+	buffer->unlimited = new_value;
+}
+
 /* Initializes the buffer structure. */
 
 void
@@ -30,6 +36,7 @@
 	buffer->alloc = len;
 	buffer->offset = 0;
 	buffer->end = 0;
+	buffer->unlimited = 0;
 }
 
 /* Frees any memory used for the buffer. */
@@ -78,7 +85,8 @@
 	u_int newlen;
 	void *p;
 
-	if (len > 0x100000)
+	if ((buffer->unlimited && len > MAXBUFSZ) || 
+	    (!buffer->unlimited && len > 0x100000))
 		fatal("buffer_append_space: len %u not supported", len);
 
 	/* If the buffer is empty, start using it from the beginning. */
@@ -107,7 +115,8 @@
 	/* Increase the size of the buffer and retry. */
 
 	newlen = buffer->alloc + len + 32768;
-	if (newlen > 0xa00000)
+	if ((buffer->unlimited && newlen > MAXBUFSZ) ||
+	    (!buffer->unlimited && newlen > 0xa00000))
 		fatal("buffer_append_space: alloc %u not supported",
 		    newlen);
 	buffer->buf = xrealloc(buffer->buf, newlen);
diff -u openssh-3.8.1p1/buffer.h openssh-3.8.1p1-dynwindow/buffer.h
--- openssh-3.8.1p1/buffer.h	2002-03-04 20:53:04.000000000 -0500
+++ openssh-3.8.1p1-dynwindow/buffer.h	2004-07-08 07:26:13.000000000 -0400
@@ -16,13 +16,18 @@
 #ifndef BUFFER_H
 #define BUFFER_H
 
+#define MAXBUFSZ (2<<29)-1
+
 typedef struct {
 	u_char	*buf;		/* Buffer for data. */
 	u_int	 alloc;		/* Number of bytes allocated for data. */
 	u_int	 offset;	/* Offset of first byte containing data. */
 	u_int	 end;		/* Offset of last byte containing data. */
+	u_int	 unlimited;
 }       Buffer;
 
+void set_unlimited(Buffer *,int);
+
 void	 buffer_init(Buffer *);
 void	 buffer_clear(Buffer *);
 void	 buffer_free(Buffer *);
diff -u openssh-3.8.1p1/channels.c openssh-3.8.1p1-dynwindow/channels.c
--- openssh-3.8.1p1/channels.c	2004-01-20 19:02:09.000000000 -0500
+++ openssh-3.8.1p1-dynwindow/channels.c	2004-07-13 09:46:58.000000000 -0400
@@ -255,6 +255,7 @@
 	c->local_window_max = window;
 	c->local_consumed = 0;
 	c->local_maxpacket = maxpack;
+	c->dynamic_window = 0;
 	c->remote_id = -1;
 	c->remote_name = xstrdup(remote_name);
 	c->remote_window = 0;
@@ -702,6 +703,10 @@
 channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
 {
 	u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
+	if (!c->input.unlimited && limit > 0x10000)
+		limit = 0x10000;
+	else if (c->input.unlimited && limit > MAXBUFSZ)
+		limit = MAXBUFSZ; 
 
 	if (c->istate == CHAN_INPUT_OPEN &&
 	    limit > 0 &&
@@ -1488,14 +1493,29 @@
 	    !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
 	    c->local_window < c->local_window_max/2 &&
 	    c->local_consumed > 0) {
+		u_int32_t tcpwinsz = 0;
+		socklen_t optsz = sizeof(tcpwinsz);
+		int ret = -1;
+		u_int32_t addition = 0;
+		if (c->dynamic_window) {
+			ret = getsockopt(packet_get_connection_in(), 
+				SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
+			if ((ret == 0) && tcpwinsz/2 > MAXBUFSZ) 
+				tcpwinsz = MAXBUFSZ/2;
+		}
+		if (c->dynamic_window && (ret == 0) && 
+		    (2*tcpwinsz > c->local_window_max)) {
+			addition = 2 * tcpwinsz - c->local_window_max;
+			c->local_window_max += addition;
+		}
 		packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
 		packet_put_int(c->remote_id);
-		packet_put_int(c->local_consumed);
+		packet_put_int(c->local_consumed + addition);
 		packet_send();
 		debug2("channel %d: window %d sent adjust %d",
 		    c->self, c->local_window,
 		    c->local_consumed);
-		c->local_window += c->local_consumed;
+		c->local_window += c->local_consumed + addition;
 		c->local_consumed = 0;
 	}
 	return 1;
diff -u openssh-3.8.1p1/channels.h openssh-3.8.1p1-dynwindow/channels.h
--- openssh-3.8.1p1/channels.h	2003-10-02 02:17:00.000000000 -0400
+++ openssh-3.8.1p1-dynwindow/channels.h	2004-07-07 09:54:55.000000000 -0400
@@ -97,6 +97,7 @@
 	u_int	local_window_max;
 	u_int	local_consumed;
 	u_int	local_maxpacket;
+	int	dynamic_window;
 	int     extended_usage;
 	int	single_connection;
 
Only in openssh-3.8.1p1-dynwindow: config.h
Only in openssh-3.8.1p1-dynwindow: config.status
Common subdirectories: openssh-3.8.1p1/contrib and
openssh-3.8.1p1-dynwindow/contrib
Common subdirectories: openssh-3.8.1p1/openbsd-compat and
openssh-3.8.1p1-dynwindow/openbsd-compat
Common subdirectories: openssh-3.8.1p1/regress and
openssh-3.8.1p1-dynwindow/regress
Common subdirectories: openssh-3.8.1p1/scard and openssh-3.8.1p1-dynwindow/scard
diff -u openssh-3.8.1p1/serverloop.c openssh-3.8.1p1-dynwindow/serverloop.c
--- openssh-3.8.1p1/serverloop.c	2004-01-20 19:02:50.000000000 -0500
+++ openssh-3.8.1p1-dynwindow/serverloop.c	2004-07-07 09:53:44.000000000 -0400
@@ -894,6 +894,9 @@
 	c = channel_new("session", SSH_CHANNEL_LARVAL,
 	    -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
 	    0, "server-session", 1);
+	set_unlimited(&c->input,1);
+	set_unlimited(&c->output,1);
+	c->dynamic_window = 1;
 	if (session_open(the_authctxt, c->self) != 1) {
 		debug("session open failed, free channel %d", c->self);
 		channel_free(c);
diff -u openssh-3.8.1p1/ssh.c openssh-3.8.1p1-dynwindow/ssh.c
--- openssh-3.8.1p1/ssh.c	2004-03-21 17:36:01.000000000 -0500
+++ openssh-3.8.1p1-dynwindow/ssh.c	2004-07-07 09:54:03.000000000 -0400
@@ -1117,7 +1117,11 @@
 	    "session", SSH_CHANNEL_OPENING, in, out, err,
 	    window, packetmax, CHAN_EXTENDED_WRITE,
 	    "client-session", /*nonblock*/0);
-
+	if (!tty_flag) {
+		c->dynamic_window = 1;
+		set_unlimited(&c->input,1);
+		set_unlimited(&c->output,1);
+	}
 	debug3("ssh_session2_open: channel_new: %d", c->self);
 
 	channel_send_open(c->self);
Only in openssh-3.8.1p1-dynwindow: ssh_prng_cmds




More information about the openssh-unix-dev mailing list