diff -p -u openssh-4.2p1/buffer.c openssh-hpn-4.2p1/buffer.c --- openssh-4.2p1/buffer.c 2005-03-14 07:22:26.000000000 -0500 +++ openssh-hpn-4.2p1/buffer.c 2005-09-08 12:08:40.000000000 -0400 @@ -107,7 +107,7 @@ restart: /* Increase the size of the buffer and retry. */ newlen = buffer->alloc + len + 32768; - if (newlen > BUFFER_MAX_LEN) + if (newlen > BUFFER_MAX_HPN_LEN) fatal("buffer_append_space: alloc %u not supported", newlen); buffer->buf = xrealloc(buffer->buf, newlen); diff -p -u openssh-4.2p1/buffer.h openssh-hpn-4.2p1/buffer.h --- openssh-4.2p1/buffer.h 2005-03-14 07:22:26.000000000 -0500 +++ openssh-hpn-4.2p1/buffer.h 2005-09-08 12:08:40.000000000 -0400 @@ -25,6 +25,7 @@ typedef struct { #define BUFFER_MAX_CHUNK 0x100000 #define BUFFER_MAX_LEN 0xa00000 +#define BUFFER_MAX_HPN_LEN (2>>29)-1 void buffer_init(Buffer *); void buffer_clear(Buffer *); diff -p -u openssh-4.2p1/channels.c openssh-hpn-4.2p1/channels.c --- openssh-4.2p1/channels.c 2005-07-17 03:22:45.000000000 -0400 +++ openssh-hpn-4.2p1/channels.c 2005-09-08 12:08:40.000000000 -0400 @@ -262,6 +262,7 @@ channel_new(char *ctype, int type, int r 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; @@ -716,9 +717,9 @@ static void channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) { u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); - + /* check buffer limits */ - limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF)); + limit = MIN(limit, (BUFFER_MAX_HPN_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF)); if (c->istate == CHAN_INPUT_OPEN && limit > 0 && @@ -1537,14 +1538,29 @@ channel_check_window(Channel *c) !(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 > BUFFER_MAX_HPN_LEN) + tcpwinsz = BUFFER_MAX_HPN_LEN; + } + if (c->dynamic_window && (ret == 0) && + (tcpwinsz > c->local_window_max)) { + addition = 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 -p -u openssh-4.2p1/channels.h openssh-hpn-4.2p1/channels.h --- openssh-4.2p1/channels.h 2005-07-17 03:19:25.000000000 -0400 +++ openssh-hpn-4.2p1/channels.h 2005-09-08 12:08:40.000000000 -0400 @@ -99,6 +99,7 @@ struct Channel { u_int local_window_max; u_int local_consumed; u_int local_maxpacket; + int dynamic_window; int extended_usage; int single_connection; @@ -119,11 +120,11 @@ struct Channel { /* default window/packet sizes for tcp/x11-fwd-channel */ #define CHAN_SES_PACKET_DEFAULT (32*1024) -#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) +#define CHAN_SES_WINDOW_DEFAULT (0xa00000/2) #define CHAN_TCP_PACKET_DEFAULT (32*1024) -#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_TCP_WINDOW_DEFAULT (0xa00000/2) #define CHAN_X11_PACKET_DEFAULT (16*1024) -#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) +#define CHAN_X11_WINDOW_DEFAULT (0xa00000/2) /* possible input states */ #define CHAN_INPUT_OPEN 0 diff -p -u openssh-4.2p1/compat.c openssh-hpn-4.2p1/compat.c --- openssh-4.2p1/compat.c 2005-03-01 05:24:33.000000000 -0500 +++ openssh-hpn-4.2p1/compat.c 2005-09-08 12:08:40.000000000 -0400 @@ -162,6 +162,14 @@ compat_datafellows(const char *version) strlen(check[i].pat), 0) == 1) { debug("match: %s pat %s", version, check[i].pat); datafellows = check[i].bugs; + /* Check to see if the remote side is OpenSSH and not HPN */ + if(strstr(version,"OpenSSH") != NULL) + { + if (strstr(version,"hpn") == NULL) + { + datafellows |= SSH_BUG_LARGEWINDOW; + } + } return; } } diff -p -u openssh-4.2p1/compat.h openssh-hpn-4.2p1/compat.h --- openssh-4.2p1/compat.h 2005-03-01 05:24:33.000000000 -0500 +++ openssh-hpn-4.2p1/compat.h 2005-09-08 12:08:40.000000000 -0400 @@ -56,6 +56,7 @@ #define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 +#define SSH_BUG_LARGEWINDOW 0x02000000 void enable_compat13(void); void enable_compat20(void); Common subdirectories: openssh-4.2p1/contrib and openssh-hpn-4.2p1/contrib Common subdirectories: openssh-4.2p1/openbsd-compat and openssh-hpn-4.2p1/openbsd-compat diff -p -u openssh-4.2p1/readconf.h openssh-hpn-4.2p1/readconf.h --- openssh-4.2p1/readconf.h 2005-06-15 23:19:42.000000000 -0400 +++ openssh-hpn-4.2p1/readconf.h 2005-09-08 12:08:40.000000000 -0400 @@ -57,6 +57,7 @@ typedef struct { int compression_level; /* Compression level 1 (fast) to 9 * (best). */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ + int tcp_rcv_buf; /* user switch to set tcp recv buffer */ LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ Common subdirectories: openssh-4.2p1/regress and openssh-hpn-4.2p1/regress Common subdirectories: openssh-4.2p1/scard and openssh-hpn-4.2p1/scard diff -p -u openssh-4.2p1/scp.c openssh-hpn-4.2p1/scp.c --- openssh-4.2p1/scp.c 2005-08-02 03:07:08.000000000 -0400 +++ openssh-hpn-4.2p1/scp.c 2005-09-08 12:10:35.000000000 -0400 @@ -231,7 +231,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:w:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -292,6 +292,9 @@ main(int argc, char **argv) setmode(0, O_BINARY); #endif break; + case 'w': + addargs(&args, "-w%s", optarg); + break; default: usage(); } @@ -507,7 +510,7 @@ source(int argc, char **argv) off_t i, amt, statbytes; size_t result; int fd = -1, haderr, indx; - char *last, *name, buf[2048]; + char *last, *name, buf[16384]; int len; for (indx = 0; indx < argc; ++indx) { @@ -567,7 +570,11 @@ syserr: run_err("%s: %s", name, strerr (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; - if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { + /* this change decreases the number of read/write syscalls*/ + /* when scp acts as data source. this is the critical change*/ + /* buf can actually remain at 2k but increasing both to 16k*/ + /* seemed to make sense*/ + if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) { next: (void) close(fd); continue; } @@ -728,7 +735,7 @@ sink(int argc, char **argv) int amt, exists, first, mask, mode, ofd, omode; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + char ch, *cp, *np, *targ, *why, *vect[1], buf[16384]; struct timeval tv[2]; #define atime tv[0] @@ -889,7 +896,7 @@ bad: run_err("%s: %s", np, strerror(er continue; } (void) atomicio(vwrite, remout, "", 1); - if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) { (void) close(ofd); continue; } @@ -899,8 +906,8 @@ bad: run_err("%s: %s", np, strerror(er statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); - for (count = i = 0; i < size; i += 4096) { - amt = 4096; + for (count = i = 0; i < size; i += sizeof(buf)) { + amt = sizeof(buf); if (i + amt > size) amt = size - i; count += amt; @@ -917,7 +924,7 @@ bad: run_err("%s: %s", np, strerror(er } while (amt > 0); if (limit_rate) - bwlimit(4096); + bwlimit(sizeof(buf)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ @@ -1033,7 +1040,7 @@ usage(void) { (void) fprintf(stderr, "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" - " [-l limit] [-o ssh_option] [-P port] [-S program]\n" + " [-l limit] [-o ssh_option] [-P port] [-w buffer size] [-S program]\n" " [[user@]host1:]file1 [...] [[user@]host2:]file2\n"); exit(1); } diff -p -u openssh-4.2p1/serverloop.c openssh-hpn-4.2p1/serverloop.c --- openssh-4.2p1/serverloop.c 2005-07-17 03:26:44.000000000 -0400 +++ openssh-hpn-4.2p1/serverloop.c 2005-09-08 12:08:41.000000000 -0400 @@ -895,6 +895,8 @@ server_request_session(void) c = channel_new("session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); + if (!(datafellows & SSH_BUG_LARGEWINDOW)) + 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 -p -u openssh-4.2p1/sshconnect.c openssh-hpn-4.2p1/sshconnect.c --- openssh-4.2p1/sshconnect.c 2005-07-17 03:22:46.000000000 -0400 +++ openssh-hpn-4.2p1/sshconnect.c 2005-09-08 12:08:41.000000000 -0400 @@ -167,13 +167,58 @@ ssh_create_socket(int privileged, struct strerror(errno)); else debug("Allocated local port %d.", p); + + + /* tuning needs to happen after the socket is */ + /* created but before the connection happens */ + /* so winscale is negotiated properly -cjr */ + + /* Set tcp receive buffer if requested */ + if (options.tcp_rcv_buf) + { + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + (void *)&options.tcp_rcv_buf, + sizeof(options.tcp_rcv_buf)) >= 0) + { + debug("setsockopt SO_RCVBUF: %.100s", strerror(errno)); + } + else + { + /* coudln't set the socket size to use spec. */ + /* should default to system param and continue */ + /* warn the user though - cjr */ + error("Couldn't set socket receive buffer as requested. Continuing anyway."); + } + } return sock; } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) error("socket: %.100s", strerror(errno)); - - /* Bind the socket to an alternative local IP address */ + + /* tuning needs to happen after the socket is */ + /* created but before the connection happens */ + /* so winscale is negotiated properly -cjr */ + + /* Set tcp receive buffer if requested */ + if (options.tcp_rcv_buf) + { + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + (void *)&options.tcp_rcv_buf, + sizeof(options.tcp_rcv_buf)) >= 0) + { + debug("setsockopt SO_RCVBUF: %.100s", strerror(errno)); + } + else + { + /* coudln't set the socket size to use spec. */ + /* should default to system param and continue */ + /* warn the user though - cjr */ + error("Couldn't set socket receive buffer as requested. Continuing anyway."); + } + } + + /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL) return sock; @@ -480,7 +525,7 @@ ssh_exchange_identification(void) snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_VERSION); + SSH_RELEASE); if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); diff -p -u openssh-4.2p1/sshd.c openssh-hpn-4.2p1/sshd.c --- openssh-4.2p1/sshd.c 2005-07-26 07:54:56.000000000 -0400 +++ openssh-hpn-4.2p1/sshd.c 2005-09-08 12:08:41.000000000 -0400 @@ -377,7 +377,7 @@ sshd_exchange_identification(int sock_in major = PROTOCOL_MAJOR_1; minor = PROTOCOL_MINOR_1; } - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE); server_version_string = xstrdup(buf); /* Send our protocol version identification. */ diff -p -u openssh-4.2p1/version.h openssh-hpn-4.2p1/version.h --- openssh-4.2p1/version.h 2005-08-31 05:47:07.000000000 -0400 +++ openssh-hpn-4.2p1/version.h 2005-09-08 12:08:41.000000000 -0400 @@ -3,4 +3,5 @@ #define SSH_VERSION "OpenSSH_4.2" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_HPN "-hpn" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN diff -p -u openssh-4.2p1/ssh.c openssh-hpn-4.2p1/ssh.c --- openssh-4.2p1/ssh.c 2005-10-28 12:24:10.000000000 +0200 +++ openssh-hpn-4.2p1/ssh.c 2005-10-28 12:26:55.000000000 +0200 @@ -161,7 +161,7 @@ usage(void) { fprintf(stderr, "usage: ssh [-1246AaBCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D port] [-e escape_char] [-F configfile]\n" +" [-D port] [-e escape_char] [-F configfile] [-w receive buffer size]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" @@ -242,9 +242,12 @@ main(int ac, char **av) /* Parse command-line arguments. */ host = NULL; + /* need to set options.tcp_rcv_buf to 0 */ + options.tcp_rcv_buf = 0; + again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxABCD:F:I:L:MNO:PR:S:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvw:xACD:F:I:L:MNO:PR:S:TVXY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -489,6 +492,9 @@ again: case 'F': config = optarg; break; + case 'w': + options.tcp_rcv_buf = atoi(optarg); + break; default: usage(); } @@ -1098,6 +1104,7 @@ ssh_session2_open(void) window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { + window = 4*CHAN_SES_PACKET_DEFAULT; window >>= 1; packetmax >>= 1; } @@ -1106,6 +1113,9 @@ ssh_session2_open(void) window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); + if (!tty_flag && (!(datafellows & SSH_BUG_LARGEWINDOW))) { + c->dynamic_window = 1; + } debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self);