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