]> git.pld-linux.org Git - packages/openssh.git/commitdiff
- hpn patch updated to hpn13v6
authorElan Ruusamäe <glen@pld-linux.org>
Fri, 4 Sep 2009 11:40:29 +0000 (11:40 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    openssh-5.0p1-hpn13v4.diff -> 1.2
    openssh-5.2p1-hpn13v6.diff -> 1.1
    openssh.spec -> 1.321

openssh-5.0p1-hpn13v4.diff [deleted file]
openssh-5.2p1-hpn13v6.diff [new file with mode: 0644]
openssh.spec

diff --git a/openssh-5.0p1-hpn13v4.diff b/openssh-5.0p1-hpn13v4.diff
deleted file mode 100644 (file)
index 202ea88..0000000
+++ /dev/null
@@ -1,2415 +0,0 @@
-diff -NupwB openssh-5.0p1/auth2.c openssh-5.0p1-hpn13v4-sink/auth2.c
---- openssh-5.0p1/auth2.c      2007-10-26 00:26:16.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/auth2.c 2008-05-07 13:54:53.000000000 -0400
-@@ -44,6 +44,7 @@
- #include "dispatch.h"
- #include "pathnames.h"
- #include "buffer.h"
-+#include "canohost.h"
- #ifdef GSSAPI
- #include "ssh-gss.h"
-@@ -67,6 +68,9 @@ extern Authmethod method_hostbased;
- extern Authmethod method_gssapi;
- #endif
-+static int log_flag = 0;
-+
-+
- Authmethod *authmethods[] = {
-       &method_none,
-       &method_pubkey,
-@@ -150,6 +154,11 @@ input_userauth_request(int type, u_int32
-       service = packet_get_string(NULL);
-       method = packet_get_string(NULL);
-       debug("userauth-request for user %s service %s method %s", user, service, method);
-+      if (!log_flag) {
-+              logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
-+                    get_remote_ipaddr(), get_remote_port(), user);
-+              log_flag = 1;
-+      }
-       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
-       if ((style = strchr(user, ':')) != NULL)
-diff -NupwB openssh-5.0p1/buffer.c openssh-5.0p1-hpn13v4-sink/buffer.c
---- openssh-5.0p1/buffer.c     2006-08-04 22:39:39.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/buffer.c        2008-05-07 13:55:20.000000000 -0400
-@@ -127,7 +127,9 @@ restart:
-       /* Increase the size of the buffer and retry. */
-       newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
--      if (newlen > BUFFER_MAX_LEN)
-+      /* need it to be slightly larger than the MAX LEN for this */
-+      /* still investigating *why* but this works for now -cjr */
-+      if (newlen >= (BUFFER_MAX_LEN_HPN + BUFFER_MAX_CHUNK)) 
-               fatal("buffer_append_space: alloc %u not supported",
-                   newlen);
-       buffer->buf = xrealloc(buffer->buf, 1, newlen);
-diff -NupwB openssh-5.0p1/buffer.h openssh-5.0p1-hpn13v4-sink/buffer.h
---- openssh-5.0p1/buffer.h     2006-08-04 22:39:39.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/buffer.h        2008-05-07 13:54:53.000000000 -0400
-@@ -16,6 +16,9 @@
- #ifndef BUFFER_H
- #define BUFFER_H
-+/* move the following to a more appropriate place and name */
-+#define BUFFER_MAX_LEN_HPN          0x4000000  /* 64MB */
-+
- typedef struct {
-       u_char  *buf;           /* Buffer for data. */
-       u_int    alloc;         /* Number of bytes allocated for data. */
-diff -NupwB openssh-5.0p1/channels.c openssh-5.0p1-hpn13v4-sink/channels.c
---- openssh-5.0p1/channels.c   2008-04-02 17:43:57.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/channels.c      2008-05-07 13:55:20.000000000 -0400
-@@ -311,6 +311,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;
-@@ -765,11 +766,39 @@ channel_pre_open_13(Channel *c, fd_set *
-               FD_SET(c->sock, writeset);
- }
-+int channel_tcpwinsz () {
-+        u_int32_t tcpwinsz = 0;
-+        socklen_t optsz = sizeof(tcpwinsz);
-+      int ret = -1;
-+
-+      /* if we aren't on a socket return 128KB*/
-+      if(!packet_connection_is_on_socket()) 
-+          return(128*1024);
-+      ret = getsockopt(packet_get_connection_in(),
-+                       SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-+      /* return no more than 64MB */
-+      if (ret == 0) {
-+              if (tcpwinsz > BUFFER_MAX_LEN_HPN) 
-+          tcpwinsz = BUFFER_MAX_LEN_HPN;
-+      } else {
-+              fatal("Could not getsockopt in channel_tcpwinsz");
-+      }
-+      debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
-+             packet_get_connection_in());
-+      return(tcpwinsz);
-+}
-+
- 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 */
-+      if ((!c->tcpwinsz) || (c->dynamic_window > 0))
-+          c->tcpwinsz = channel_tcpwinsz();
-+      
-+      limit = MIN(limit, 2 * c->tcpwinsz);
-+      
-       if (c->istate == CHAN_INPUT_OPEN &&
-           limit > 0 &&
-           buffer_len(&c->input) < limit &&
-@@ -1661,14 +1690,22 @@ channel_check_window(Channel *c)
-           c->local_maxpacket*3) ||
-           c->local_window < c->local_window_max/2) &&
-           c->local_consumed > 0) {
-+              u_int addition = 0;
-+              /* adjust max window size if we are in a dynamic environment */
-+              if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
-+                      /* grow the window somewhat aggressively to maintain pressure */
-+                      addition = 1.5*(c->tcpwinsz - c->local_window_max);
-+                      c->local_window_max += addition;
-+                      debug2("Channel %d window size: %d", c->self, c->local_window_max);
-+              }
-               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;
-@@ -1871,11 +1908,12 @@ channel_after_select(fd_set *readset, fd
- /* If there is data to send to the connection, enqueue some of it now. */
--void
-+int
- channel_output_poll(void)
- {
-       Channel *c;
-       u_int i, len;
-+      int packet_length = 0;
-       for (i = 0; i < channels_alloc; i++) {
-               c = channels[i];
-@@ -1915,7 +1953,7 @@ channel_output_poll(void)
-                                       packet_start(SSH2_MSG_CHANNEL_DATA);
-                                       packet_put_int(c->remote_id);
-                                       packet_put_string(data, dlen);
--                                      packet_send();
-+                                      packet_length = packet_send();
-                                       c->remote_window -= dlen + 4;
-                                       xfree(data);
-                               }
-@@ -1945,7 +1983,7 @@ channel_output_poll(void)
-                                   SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
-                               packet_put_int(c->remote_id);
-                               packet_put_string(buffer_ptr(&c->input), len);
--                              packet_send();
-+                              packet_length = packet_send();
-                               buffer_consume(&c->input, len);
-                               c->remote_window -= len;
-                       }
-@@ -1980,12 +2018,13 @@ channel_output_poll(void)
-                       packet_put_int(c->remote_id);
-                       packet_put_int(SSH2_EXTENDED_DATA_STDERR);
-                       packet_put_string(buffer_ptr(&c->extended), len);
--                      packet_send();
-+                      packet_length = packet_send();
-                       buffer_consume(&c->extended, len);
-                       c->remote_window -= len;
-                       debug2("channel %d: sent ext data %d", c->self, len);
-               }
-       }
-+      return (packet_length);
- }
-@@ -2342,7 +2381,8 @@ channel_set_af(int af)
- static int
- channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
--    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
-+    const char *host_to_connect, u_short port_to_connect, int gateway_ports, 
-+    int hpn_disabled, int hpn_buffer_size)
- {
-       Channel *c;
-       int sock, r, success = 0, wildcard = 0, is_client;
-@@ -2456,9 +2496,15 @@ channel_setup_fwd_listener(int type, con
-                       continue;
-               }
-               /* Allocate a channel number for the socket. */
-+              /* explicitly test for hpn disabled option. if true use smaller window size */
-+              if (hpn_disabled)
-               c = channel_new("port listener", type, sock, sock, -1,
-                   CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-                   0, "port listener", 1);
-+              else
-+                      c = channel_new("port listener", type, sock, sock, -1,
-+                        hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
-+                        0, "port listener", 1); 
-               strlcpy(c->path, host, sizeof(c->path));
-               c->host_port = port_to_connect;
-               c->listening_port = listen_port;
-@@ -2495,20 +2541,22 @@ channel_cancel_rport_listener(const char
- /* protocol local port fwd, used by ssh (and sshd in v1) */
- int
- channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
--    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
-+    const char *host_to_connect, u_short port_to_connect, int gateway_ports, 
-+    int hpn_disabled, int hpn_buffer_size)
- {
-       return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
-           listen_host, listen_port, host_to_connect, port_to_connect,
--          gateway_ports);
-+          gateway_ports, hpn_disabled, hpn_buffer_size);
- }
- /* protocol v2 remote port fwd, used by sshd */
- int
- channel_setup_remote_fwd_listener(const char *listen_address,
--    u_short listen_port, int gateway_ports)
-+    u_short listen_port, int gateway_ports, int hpn_disabled, int hpn_buffer_size)
- {
-       return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
--          listen_address, listen_port, NULL, 0, gateway_ports);
-+          listen_address, listen_port, NULL, 0, gateway_ports, 
-+          hpn_disabled, hpn_buffer_size);
- }
- /*
-@@ -2623,7 +2671,8 @@ channel_request_rforward_cancel(const ch
-  * message if there was an error).
-  */
- int
--channel_input_port_forward_request(int is_root, int gateway_ports)
-+channel_input_port_forward_request(int is_root, int gateway_ports,
-+                                 int hpn_disabled, int hpn_buffer_size)
- {
-       u_short port, host_port;
-       int success = 0;
-@@ -2649,7 +2698,7 @@ channel_input_port_forward_request(int i
-       /* Initiate forwarding */
-       success = channel_setup_local_fwd_listener(NULL, port, hostname,
--          host_port, gateway_ports);
-+          host_port, gateway_ports, hpn_disabled, hpn_buffer_size);
-       /* Free the argument string. */
-       xfree(hostname);
-@@ -2853,7 +2902,8 @@ channel_send_window_changes(void)
-  */
- int
- x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
--    int single_connection, u_int *display_numberp, int **chanids)
-+    int single_connection, u_int *display_numberp, int **chanids, 
-+    int hpn_disabled, int hpn_buffer_size)
- {
-       Channel *nc = NULL;
-       int display_number, sock;
-@@ -2947,10 +2997,17 @@ x11_create_display_inet(int x11_display_
-       *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
-       for (n = 0; n < num_socks; n++) {
-               sock = socks[n];
-+              /* Is this really necassary? */
-+              if (hpn_disabled) 
-               nc = channel_new("x11 listener",
-                   SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
-                   CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-                   0, "X11 inet listener", 1);
-+              else 
-+                      nc = channel_new("x11 listener",
-+                          SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
-+                          hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
-+                          0, "X11 inet listener", 1);
-               nc->single_connection = single_connection;
-               (*chanids)[n] = nc->self;
-       }
-diff -NupwB openssh-5.0p1/channels.h openssh-5.0p1-hpn13v4-sink/channels.h
---- openssh-5.0p1/channels.h   2007-06-12 09:38:54.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/channels.h      2008-05-07 13:54:53.000000000 -0400
-@@ -98,8 +98,10 @@ struct Channel {
-       u_int   local_window_max;
-       u_int   local_consumed;
-       u_int   local_maxpacket;
-+      int     dynamic_window;
-       int     extended_usage;
-       int     single_connection;
-+      u_int   tcpwinsz;       
-       char   *ctype;          /* type */
-@@ -122,9 +124,11 @@ struct Channel {
- /* default window/packet sizes for tcp/x11-fwd-channel */
- #define CHAN_SES_PACKET_DEFAULT       (32*1024)
--#define CHAN_SES_WINDOW_DEFAULT       (64*CHAN_SES_PACKET_DEFAULT)
-+#define CHAN_SES_WINDOW_DEFAULT       (4*CHAN_SES_PACKET_DEFAULT)
-+
- #define CHAN_TCP_PACKET_DEFAULT       (32*1024)
--#define CHAN_TCP_WINDOW_DEFAULT       (64*CHAN_TCP_PACKET_DEFAULT)
-+#define CHAN_TCP_WINDOW_DEFAULT       (4*CHAN_TCP_PACKET_DEFAULT)
-+
- #define CHAN_X11_PACKET_DEFAULT       (16*1024)
- #define CHAN_X11_WINDOW_DEFAULT       (4*CHAN_X11_PACKET_DEFAULT)
-@@ -193,7 +197,7 @@ void        channel_input_window_adjust(int, u
- void   channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
- void     channel_after_select(fd_set *, fd_set *);
--void     channel_output_poll(void);
-+int      channel_output_poll(void);
- int      channel_not_very_much_buffered_data(void);
- void     channel_close_all(void);
-@@ -208,21 +212,21 @@ void      channel_add_permitted_opens(char *
- int    channel_add_adm_permitted_opens(char *, int);
- void   channel_clear_permitted_opens(void);
- void   channel_clear_adm_permitted_opens(void);
--int      channel_input_port_forward_request(int, int);
-+int      channel_input_port_forward_request(int, int, int, int);
- int    channel_connect_to(const char *, u_short);
- int    channel_connect_by_listen_address(u_short);
- int    channel_request_remote_forwarding(const char *, u_short,
-            const char *, u_short);
- int    channel_setup_local_fwd_listener(const char *, u_short,
--           const char *, u_short, int);
-+           const char *, u_short, int, int, int);
- void   channel_request_rforward_cancel(const char *host, u_short port);
--int    channel_setup_remote_fwd_listener(const char *, u_short, int);
-+int    channel_setup_remote_fwd_listener(const char *, u_short, int, int, int);
- int    channel_cancel_rport_listener(const char *, u_short);
- /* x11 forwarding */
- int    x11_connect_display(void);
--int    x11_create_display_inet(int, int, int, u_int *, int **);
-+int    x11_create_display_inet(int, int, int, u_int *, int **, int, int);
- void     x11_input_open(int, u_int32_t, void *);
- void   x11_request_forwarding_with_spoofing(int, const char *, const char *,
-           const char *);
-diff -NupwB openssh-5.0p1/cipher.c openssh-5.0p1-hpn13v4-sink/cipher.c
---- openssh-5.0p1/cipher.c     2006-08-04 22:39:39.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/cipher.c        2008-05-07 13:54:53.000000000 -0400
-@@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi
- extern const EVP_CIPHER *evp_ssh1_3des(void);
- extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
- extern const EVP_CIPHER *evp_aes_128_ctr(void);
-+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
- extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
- struct Cipher {
-@@ -81,9 +82,9 @@ struct Cipher {
-       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
-       { "rijndael-cbc@lysator.liu.se",
-                               SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
--      { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
--      { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
--      { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
-+      { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_ctr_mt },
-+      { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_ctr_mt },
-+      { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_ctr_mt },
- #ifdef USE_CIPHER_ACSS
-       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
- #endif
-@@ -156,7 +157,8 @@ ciphers_valid(const char *names)
-       for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
-           (p = strsep(&cp, CIPHER_SEP))) {
-               c = cipher_by_name(p);
--              if (c == NULL || c->number != SSH_CIPHER_SSH2) {
-+              if (c == NULL || (c->number != SSH_CIPHER_SSH2 && 
-+c->number != SSH_CIPHER_NONE)) {
-                       debug("bad cipher %s [%s]", p, names);
-                       xfree(cipher_list);
-                       return 0;
-@@ -330,6 +332,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
-       int evplen;
-       switch (c->number) {
-+      case SSH_CIPHER_NONE:
-       case SSH_CIPHER_SSH2:
-       case SSH_CIPHER_DES:
-       case SSH_CIPHER_BLOWFISH:
-@@ -364,6 +367,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
-       int evplen = 0;
-       switch (c->number) {
-+      case SSH_CIPHER_NONE:
-       case SSH_CIPHER_SSH2:
-       case SSH_CIPHER_DES:
-       case SSH_CIPHER_BLOWFISH:
-diff -NupwB openssh-5.0p1/cipher-ctr-mt.c openssh-5.0p1-hpn13v4-sink/cipher-ctr-mt.c
---- openssh-5.0p1/cipher-ctr-mt.c      1969-12-31 19:00:00.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/cipher-ctr-mt.c 2008-05-07 13:54:53.000000000 -0400
-@@ -0,0 +1,473 @@
-+/*
-+ * OpenSSH Multi-threaded AES-CTR Cipher
-+ *
-+ * Author: Benjamin Bennett <ben@psc.edu>
-+ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
-+ *
-+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
-+ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+#include "includes.h"
-+
-+#include <sys/types.h>
-+
-+#include <stdarg.h>
-+#include <string.h>
-+
-+#include <openssl/evp.h>
-+
-+#include "xmalloc.h"
-+#include "log.h"
-+
-+/* compatibility with old or broken OpenSSL versions */
-+#include "openbsd-compat/openssl-compat.h"
-+
-+#ifndef USE_BUILTIN_RIJNDAEL
-+#include <openssl/aes.h>
-+#endif
-+
-+#include <pthread.h>
-+
-+/*-------------------- TUNABLES --------------------*/
-+/* Number of pregen threads to use */
-+#define CIPHER_THREADS        2
-+
-+/* Number of keystream queues */
-+#define NUMKQ         (CIPHER_THREADS + 2)
-+
-+/* Length of a keystream queue */
-+#define KQLEN         4096
-+
-+/* Processor cacheline length */
-+#define CACHELINE_LEN 64
-+
-+/* Collect thread stats and print at cancellation when in debug mode */
-+/* #define CIPHER_THREAD_STATS */
-+
-+/* Use single-byte XOR instead of 8-byte XOR */
-+/* #define CIPHER_BYTE_XOR */
-+/*-------------------- END TUNABLES --------------------*/
-+
-+
-+const EVP_CIPHER *evp_aes_ctr_mt(void);
-+
-+#ifdef CIPHER_THREAD_STATS
-+/*
-+ * Struct to collect thread stats
-+ */
-+struct thread_stats {
-+      u_int   fills;
-+      u_int   skips;
-+      u_int   waits;
-+      u_int   drains;
-+};
-+
-+/*
-+ * Debug print the thread stats
-+ * Use with pthread_cleanup_push for displaying at thread cancellation
-+ */
-+static void
-+thread_loop_stats(void *x)
-+{
-+      struct thread_stats *s = x;
-+
-+      debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
-+                      s->fills, s->skips, s->waits);
-+}
-+
-+ #define STATS_STRUCT(s)      struct thread_stats s
-+ #define STATS_INIT(s)                { memset(&s, 0, sizeof(s)); }
-+ #define STATS_FILL(s)                { s.fills++; }
-+ #define STATS_SKIP(s)                { s.skips++; }
-+ #define STATS_WAIT(s)                { s.waits++; }
-+ #define STATS_DRAIN(s)               { s.drains++; }
-+#else
-+ #define STATS_STRUCT(s)
-+ #define STATS_INIT(s)
-+ #define STATS_FILL(s)
-+ #define STATS_SKIP(s)
-+ #define STATS_WAIT(s)
-+ #define STATS_DRAIN(s)
-+#endif
-+
-+/* Keystream Queue state */
-+enum {
-+      KQINIT,
-+      KQEMPTY,
-+      KQFILLING,
-+      KQFULL,
-+      KQDRAINING
-+};
-+
-+/* Keystream Queue struct */
-+struct kq {
-+      u_char          keys[KQLEN][AES_BLOCK_SIZE];
-+      u_char          ctr[AES_BLOCK_SIZE];
-+      u_char          pad0[CACHELINE_LEN];
-+      volatile int    qstate;
-+      pthread_mutex_t lock;
-+      pthread_cond_t  cond;
-+      u_char          pad1[CACHELINE_LEN];
-+};
-+
-+/* Context struct */
-+struct ssh_aes_ctr_ctx
-+{
-+      struct kq       q[NUMKQ];
-+      AES_KEY         aes_ctx;
-+      STATS_STRUCT(stats);
-+      u_char          aes_counter[AES_BLOCK_SIZE];
-+      pthread_t       tid[CIPHER_THREADS];
-+      int             state;
-+      int             qidx;
-+      int             ridx;
-+};
-+
-+/* <friedl>
-+ * increment counter 'ctr',
-+ * the counter is of size 'len' bytes and stored in network-byte-order.
-+ * (LSB at ctr[len-1], MSB at ctr[0])
-+ */
-+static void
-+ssh_ctr_inc(u_char *ctr, u_int len)
-+{
-+      int i;
-+
-+      for (i = len - 1; i >= 0; i--)
-+              if (++ctr[i])   /* continue on overflow */
-+                      return;
-+}
-+
-+/*
-+ * Add num to counter 'ctr'
-+ */
-+static void
-+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
-+{
-+      int i;
-+      uint16_t n;
-+
-+      for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
-+              n = ctr[i] + (num & 0xff) + n;
-+              num >>= 8;
-+              ctr[i] = n & 0xff;
-+              n >>= 8;
-+      }
-+}
-+
-+/*
-+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
-+ */
-+static void
-+thread_loop_cleanup(void *x)
-+{
-+      pthread_mutex_unlock((pthread_mutex_t *)x);
-+}
-+
-+/*
-+ * The life of a pregen thread:
-+ *    Find empty keystream queues and fill them using their counter.
-+ *    When done, update counter for the next fill.
-+ */
-+static void *
-+thread_loop(void *x)
-+{
-+      AES_KEY key;
-+      STATS_STRUCT(stats);
-+      struct ssh_aes_ctr_ctx *c = x;
-+      struct kq *q;
-+      int i;
-+      int qidx;
-+
-+      /* Threads stats on cancellation */
-+      STATS_INIT(stats);
-+#ifdef CIPHER_THREAD_STATS
-+      pthread_cleanup_push(thread_loop_stats, &stats);
-+#endif
-+
-+      /* Thread local copy of AES key */
-+      memcpy(&key, &c->aes_ctx, sizeof(key));
-+
-+      /*
-+       * Handle the special case of startup, one thread must fill
-+       * the first KQ then mark it as draining. Lock held throughout.
-+       */
-+      if (pthread_equal(pthread_self(), c->tid[0])) {
-+              q = &c->q[0];
-+              pthread_mutex_lock(&q->lock);
-+              if (q->qstate == KQINIT) {
-+                      for (i = 0; i < KQLEN; i++) {
-+                              AES_encrypt(q->ctr, q->keys[i], &key);
-+                              ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+                      }
-+                      ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+                      q->qstate = KQDRAINING;
-+                      STATS_FILL(stats);
-+                      pthread_cond_broadcast(&q->cond);
-+              }
-+              pthread_mutex_unlock(&q->lock);
-+      }
-+      else 
-+              STATS_SKIP(stats);
-+
-+      /*
-+       * Normal case is to find empty queues and fill them, skipping over
-+       * queues already filled by other threads and stopping to wait for
-+       * a draining queue to become empty.
-+       *
-+       * Multiple threads may be waiting on a draining queue and awoken
-+       * when empty.  The first thread to wake will mark it as filling,
-+       * others will move on to fill, skip, or wait on the next queue.
-+       */
-+      for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
-+              /* Check if I was cancelled, also checked in cond_wait */
-+              pthread_testcancel();
-+
-+              /* Lock queue and block if its draining */
-+              q = &c->q[qidx];
-+              pthread_mutex_lock(&q->lock);
-+              pthread_cleanup_push(thread_loop_cleanup, &q->lock);
-+              while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
-+                      STATS_WAIT(stats);
-+                      pthread_cond_wait(&q->cond, &q->lock);
-+              }
-+              pthread_cleanup_pop(0);
-+
-+              /* If filling or full, somebody else got it, skip */
-+              if (q->qstate != KQEMPTY) {
-+                      pthread_mutex_unlock(&q->lock);
-+                      STATS_SKIP(stats);
-+                      continue;
-+              }
-+
-+              /*
-+               * Empty, let's fill it.
-+               * Queue lock is relinquished while we do this so others
-+               * can see that it's being filled.
-+               */
-+              q->qstate = KQFILLING;
-+              pthread_mutex_unlock(&q->lock);
-+              for (i = 0; i < KQLEN; i++) {
-+                      AES_encrypt(q->ctr, q->keys[i], &key);
-+                      ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+              }
-+
-+              /* Re-lock, mark full and signal consumer */
-+              pthread_mutex_lock(&q->lock);
-+              ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+              q->qstate = KQFULL;
-+              STATS_FILL(stats);
-+              pthread_cond_signal(&q->cond);
-+              pthread_mutex_unlock(&q->lock);
-+      }
-+
-+#ifdef CIPHER_THREAD_STATS
-+      /* Stats */
-+      pthread_cleanup_pop(1);
-+#endif
-+
-+      return NULL;
-+}
-+
-+static int
-+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
-+    u_int len)
-+{
-+      struct ssh_aes_ctr_ctx *c;
-+      struct kq *q, *oldq;
-+      int ridx;
-+      u_char *buf;
-+
-+      if (len == 0)
-+              return (1);
-+      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
-+              return (0);
-+
-+      q = &c->q[c->qidx];
-+      ridx = c->ridx;
-+
-+      /* src already padded to block multiple */
-+      while (len > 0) {
-+              buf = q->keys[ridx];
-+
-+#ifdef CIPHER_BYTE_XOR
-+              dest[0] = src[0] ^ buf[0];
-+              dest[1] = src[1] ^ buf[1];
-+              dest[2] = src[2] ^ buf[2];
-+              dest[3] = src[3] ^ buf[3];
-+              dest[4] = src[4] ^ buf[4];
-+              dest[5] = src[5] ^ buf[5];
-+              dest[6] = src[6] ^ buf[6];
-+              dest[7] = src[7] ^ buf[7];
-+              dest[8] = src[8] ^ buf[8];
-+              dest[9] = src[9] ^ buf[9];
-+              dest[10] = src[10] ^ buf[10];
-+              dest[11] = src[11] ^ buf[11];
-+              dest[12] = src[12] ^ buf[12];
-+              dest[13] = src[13] ^ buf[13];
-+              dest[14] = src[14] ^ buf[14];
-+              dest[15] = src[15] ^ buf[15];
-+#else
-+              *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
-+              *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
-+                                              *(uint64_t *)(buf + 8);
-+#endif
-+
-+              dest += 16;
-+              src += 16;
-+              len -= 16;
-+              ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
-+
-+              /* Increment read index, switch queues on rollover */
-+              if ((ridx = (ridx + 1) % KQLEN) == 0) {
-+                      oldq = q;
-+
-+                      /* Mark next queue draining, may need to wait */
-+                      c->qidx = (c->qidx + 1) % NUMKQ;
-+                      q = &c->q[c->qidx];
-+                      pthread_mutex_lock(&q->lock);
-+                      while (q->qstate != KQFULL) {
-+                              STATS_WAIT(c->stats);
-+                              pthread_cond_wait(&q->cond, &q->lock);
-+                      }
-+                      q->qstate = KQDRAINING;
-+                      pthread_mutex_unlock(&q->lock);
-+
-+                      /* Mark consumed queue empty and signal producers */
-+                      pthread_mutex_lock(&oldq->lock);
-+                      oldq->qstate = KQEMPTY;
-+                      STATS_DRAIN(c->stats);
-+                      pthread_cond_broadcast(&oldq->cond);
-+                      pthread_mutex_unlock(&oldq->lock);
-+              }
-+      }
-+      c->ridx = ridx;
-+      return (1);
-+}
-+
-+#define HAVE_NONE       0
-+#define HAVE_KEY        1
-+#define HAVE_IV         2
-+static int
-+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-+    int enc)
-+{
-+      struct ssh_aes_ctr_ctx *c;
-+      int i;
-+
-+      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-+              c = xmalloc(sizeof(*c));
-+
-+              c->state = HAVE_NONE;
-+              for (i = 0; i < NUMKQ; i++) {
-+                      pthread_mutex_init(&c->q[i].lock, NULL);
-+                      pthread_cond_init(&c->q[i].cond, NULL);
-+              }
-+
-+              STATS_INIT(c->stats);
-+              
-+              EVP_CIPHER_CTX_set_app_data(ctx, c);
-+      }
-+
-+      if (c->state == (HAVE_KEY | HAVE_IV)) {
-+              /* Cancel pregen threads */
-+              for (i = 0; i < CIPHER_THREADS; i++)
-+                      pthread_cancel(c->tid[i]);
-+              for (i = 0; i < CIPHER_THREADS; i++)
-+                      pthread_join(c->tid[i], NULL);
-+              /* Start over getting key & iv */
-+              c->state = HAVE_NONE;
-+      }
-+
-+      if (key != NULL) {
-+              AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                  &c->aes_ctx);
-+              c->state |= HAVE_KEY;
-+      }
-+
-+      if (iv != NULL) {
-+              memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-+              c->state |= HAVE_IV;
-+      }
-+
-+      if (c->state == (HAVE_KEY | HAVE_IV)) {
-+              /* Clear queues */
-+              memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
-+              c->q[0].qstate = KQINIT;
-+              for (i = 1; i < NUMKQ; i++) {
-+                      memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
-+                      ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
-+                      c->q[i].qstate = KQEMPTY;
-+              }
-+              c->qidx = 0;
-+              c->ridx = 0;
-+
-+              /* Start threads */
-+              for (i = 0; i < CIPHER_THREADS; i++) {
-+                      pthread_create(&c->tid[i], NULL, thread_loop, c);
-+              }
-+              pthread_mutex_lock(&c->q[0].lock);
-+              while (c->q[0].qstate != KQDRAINING)
-+                      pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
-+              pthread_mutex_unlock(&c->q[0].lock);
-+              
-+      }
-+      return (1);
-+}
-+
-+static int
-+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+      struct ssh_aes_ctr_ctx *c;
-+      int i;
-+
-+      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-+#ifdef CIPHER_THREAD_STATS
-+              debug("main thread: %u drains, %u waits", c->stats.drains,
-+                              c->stats.waits);
-+#endif
-+              /* Cancel pregen threads */
-+              for (i = 0; i < CIPHER_THREADS; i++)
-+                      pthread_cancel(c->tid[i]);
-+              for (i = 0; i < CIPHER_THREADS; i++)
-+                      pthread_join(c->tid[i], NULL);
-+
-+              memset(c, 0, sizeof(*c));
-+              xfree(c);
-+              EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-+      }
-+      return (1);
-+}
-+
-+/* <friedl> */
-+const EVP_CIPHER *
-+evp_aes_ctr_mt(void)
-+{
-+      static EVP_CIPHER aes_ctr;
-+
-+      memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
-+      aes_ctr.nid = NID_undef;
-+      aes_ctr.block_size = AES_BLOCK_SIZE;
-+      aes_ctr.iv_len = AES_BLOCK_SIZE;
-+      aes_ctr.key_len = 16;
-+      aes_ctr.init = ssh_aes_ctr_init;
-+      aes_ctr.cleanup = ssh_aes_ctr_cleanup;
-+      aes_ctr.do_cipher = ssh_aes_ctr;
-+#ifndef SSH_OLD_EVP
-+      aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
-+          EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
-+#endif
-+      return (&aes_ctr);
-+}
-diff -NupwB openssh-5.0p1/clientloop.c openssh-5.0p1-hpn13v4-sink/clientloop.c
---- openssh-5.0p1/clientloop.c 2008-03-07 02:33:30.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/clientloop.c    2008-05-07 14:19:44.000000000 -0400
-@@ -923,13 +923,16 @@ client_process_control(fd_set *readset)
-       set_nonblock(client_fd);
-+      if (options.hpn_disabled) 
-       window = CHAN_SES_WINDOW_DEFAULT;
-+      else
-+        window = options.hpn_buffer_size;
-+
-       packetmax = CHAN_SES_PACKET_DEFAULT;
-       if (cctx->want_tty) {
-               window >>= 1;
-               packetmax >>= 1;
-       }
--      
-       c = channel_new("session", SSH_CHANNEL_OPENING,
-           new_fd[0], new_fd[1], new_fd[2], window, packetmax,
-           CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
-@@ -1034,7 +1037,8 @@ process_cmdline(void)
-               if (local) {
-                       if (channel_setup_local_fwd_listener(fwd.listen_host,
-                           fwd.listen_port, fwd.connect_host,
--                          fwd.connect_port, options.gateway_ports) < 0) {
-+                          fwd.connect_port, options.gateway_ports, 
-+                          options.hpn_disabled, options.hpn_buffer_size) < 0) {
-                               logit("Port forwarding failed.");
-                               goto out;
-                       }
-@@ -1737,10 +1741,16 @@ client_request_forwarded_tcpip(const cha
-               xfree(listen_address);
-               return NULL;
-       }
-+      if (options.hpn_disabled) 
-       c = channel_new("forwarded-tcpip",
-           SSH_CHANNEL_CONNECTING, sock, sock, -1,
-           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
-           originator_address, 1);
-+      else
-+              c = channel_new("forwarded-tcpip",
-+                  SSH_CHANNEL_CONNECTING, sock, sock, -1,
-+                  options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0,
-+                  originator_address, 1);
-       xfree(originator_address);
-       xfree(listen_address);
-       return c;
-@@ -1774,9 +1784,15 @@ client_request_x11(const char *request_t
-       sock = x11_connect_display();
-       if (sock < 0)
-               return NULL;
-+      /* again is this really necessary for X11? */
-+      if (options.hpn_disabled) 
-       c = channel_new("x11",
-           SSH_CHANNEL_X11_OPEN, sock, sock, -1,
-           CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
-+      else 
-+              c = channel_new("x11",
-+                  SSH_CHANNEL_X11_OPEN, sock, sock, -1,
-+                  options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
-       c->force_drain = 1;
-       return c;
- }
-@@ -1825,10 +1841,18 @@ client_request_tun_fwd(int tun_mode, int
-               return -1;
-       }
-+      if(options.hpn_disabled)
-       c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
--          CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
-+                              CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-+                              0, "tun", 1);
-+      else
-+      c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
-+                              options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
-+                              0, "tun", 1);
-       c->datagram = 1;
-+
-+
- #if defined(SSH_TUN_FILTER)
-       if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
-               channel_register_filter(c->self, sys_tun_infilter,
-diff -NupwB openssh-5.0p1/clientloop.c.rej openssh-5.0p1-hpn13v4-sink/clientloop.c.rej
---- openssh-5.0p1/clientloop.c.rej     1969-12-31 19:00:00.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/clientloop.c.rej        2008-05-07 13:55:20.000000000 -0400
-@@ -0,0 +1,55 @@
-+***************
-+*** 1724,1735 ****
-+      if (options.hpn_disabled) 
-+      c = channel_new("forwarded-tcpip",
-+          SSH_CHANNEL_CONNECTING, sock, sock, -1,
-+-         CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
-+          originator_address, 1);
-+      else
-+              c = channel_new("forwarded-tcpip",
-+                  SSH_CHANNEL_CONNECTING, sock, sock, -1,
-+-                 options.hpn_buffer_size, options.hpn_buffer_size, 0,
-+                  originator_address, 1);
-+      xfree(originator_address);
-+      xfree(listen_address);
-+--- 1724,1735 ----
-+      if (options.hpn_disabled) 
-+      c = channel_new("forwarded-tcpip",
-+          SSH_CHANNEL_CONNECTING, sock, sock, -1,
-++         CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
-+          originator_address, 1);
-+      else
-+              c = channel_new("forwarded-tcpip",
-+                  SSH_CHANNEL_CONNECTING, sock, sock, -1,
-++                 options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0,
-+                  originator_address, 1);
-+      xfree(originator_address);
-+      xfree(listen_address);
-+***************
-+*** 1791,1806 ****
-+      sock = ssh_get_authentication_socket();
-+      if (sock < 0)
-+              return NULL;
-+-     /* not sure this is really needed here either */
-+-     if (options.hpn_disabled) 
-+-     c = channel_new("authentication agent connection",
-+-         SSH_CHANNEL_OPEN, sock, sock, -1,
-+-         CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
-+-         "authentication agent connection", 1);
-+-     else
-+              c = channel_new("authentication agent connection",
-+                  SSH_CHANNEL_OPEN, sock, sock, -1,
-+-                 options.hpn_buffer_size, options.hpn_buffer_size, 0,
-+                  "authentication agent connection", 1);
-+      c->force_drain = 1;
-+      return c;
-+--- 1791,1799 ----
-+      sock = ssh_get_authentication_socket();
-+      if (sock < 0)
-+              return NULL;
-+              c = channel_new("authentication agent connection",
-+                  SSH_CHANNEL_OPEN, sock, sock, -1,
-++         CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
-+                  "authentication agent connection", 1);
-+      c->force_drain = 1;
-+      return c;
-diff -NupwB openssh-5.0p1/compat.c openssh-5.0p1-hpn13v4-sink/compat.c
---- openssh-5.0p1/compat.c     2007-01-05 00:26:46.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/compat.c        2008-05-07 13:54:53.000000000 -0400
-@@ -169,6 +169,15 @@ 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;
-+                                      debug("Remote is NON-HPN aware");
-+                              }
-+                      }
-                       return;
-               }
-       }
-diff -NupwB openssh-5.0p1/compat.h openssh-5.0p1-hpn13v4-sink/compat.h
---- openssh-5.0p1/compat.h     2007-01-05 00:26:46.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/compat.h        2008-05-07 13:54:53.000000000 -0400
-@@ -57,6 +57,7 @@
- #define SSH_BUG_FIRSTKEX      0x00800000
- #define SSH_OLD_FORWARD_ADDR  0x01000000
- #define SSH_BUG_RFWD_ADDR     0x02000000
-+#define SSH_BUG_LARGEWINDOW     0x04000000
- void     enable_compat13(void);
- void     enable_compat20(void);
-Common subdirectories: openssh-5.0p1/contrib and openssh-5.0p1-hpn13v4-sink/contrib
-diff -NupwB openssh-5.0p1/HPN-README openssh-5.0p1-hpn13v4-sink/HPN-README
---- openssh-5.0p1/HPN-README   1969-12-31 19:00:00.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/HPN-README      2008-05-07 13:54:53.000000000 -0400
-@@ -0,0 +1,128 @@
-+Notes:
-+
-+MULTI-THREADED CIPHER:
-+The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
-+on hosts with multiple cores to use more than one processing core during encryption. 
-+Tests have show significant throughput performance increases when using MTR-AES-CTR up 
-+to and including a full gigabit per second on quad core systems. It should be possible to 
-+achieve full line rate on dual core systems but OS and data management overhead makes this
-+more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single 
-+thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal 
-+performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. 
-+The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
-+nomenclature. 
-+Use examples:         ssh -caes128-ctr you@host.com
-+              scp -oCipher=aes256-ctr file you@host.com:~/file
-+
-+NONE CIPHER:
-+To use the NONE option you must have the NoneEnabled switch set on the server and
-+you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
-+feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not 
-+spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
-+be disabled. 
-+
-+The performance increase will only be as good as the network and TCP stack tuning
-+on the reciever side of the connection allows. As a rule of thumb a user will need 
-+at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
-+HPN-SSH home page describes this in greater detail. 
-+
-+http://www.psc.edu/networking/projects/hpn-ssh
-+
-+BUFFER SIZES:
-+
-+If HPN is disabled the receive buffer size will be set to the 
-+OpenSSH default of 64K.
-+
-+If an HPN system connects to a nonHPN system the receive buffer will
-+be set to the HPNBufferSize value. The default is 2MB but user adjustable.
-+
-+If an HPN to HPN connection is established a number of different things might
-+happen based on the user options and conditions. 
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set 
-+HPN Buffer Size = up to 64MB 
-+This is the default state. The HPN buffer size will grow to a maximum of 64MB 
-+as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is 
-+geared towards 10GigE transcontinental connections. 
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = TCP receive buffer value. 
-+Users on non-autotuning systesm should disable TCPRcvBufPoll in the 
-+ssh_cofig and sshd_config
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. 
-+This would be the system defined TCP receive buffer (RWIN).
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
-+HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
-+Generally there is no need to set both.
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = grows to HPNBufferSize
-+The buffer will grow up to the maximum size specified here. 
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
-+HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
-+Generally there is no need to set both of these, especially on autotuning 
-+systems. However, if the users wishes to override the autotuning this would be 
-+one way to do it.
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
-+HPN Buffer Size = TCPRcvBuf. 
-+This will override autotuning and set the TCP recieve buffer to the user defined 
-+value.
-+
-+
-+HPN Specific Configuration options
-+
-+TcpRcvBuf=[int]KB client
-+      set the TCP socket receive buffer to n Kilobytes. It can be set up to the 
-+maximum socket size allowed by the system. This is useful in situations where 
-+the tcp receive window is set low but the maximum buffer size is set 
-+higher (as is typical). This works on a per TCP connection basis. You can also 
-+use this to artifically limit the transfer rate of the connection. In these 
-+cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. 
-+Default is the current system wide tcp receive buffer size.
-+
-+TcpRcvBufPoll=[yes/no] client/server
-+      enable of disable the polling of the tcp receive buffer through the life 
-+of the connection. You would want to make sure that this option is enabled 
-+for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) 
-+default is yes.
-+
-+NoneEnabled=[yes/no] client/server
-+      enable or disable the use of the None cipher. Care must always be used 
-+when enabling this as it will allow users to send data in the clear. However, 
-+it is important to note that authentication information remains encrypted 
-+even if this option is enabled. Set to no by default.
-+
-+NoneSwitch=[yes/no] client
-+     Switch the encryption cipher being used to the None cipher after
-+authentication takes place. NoneEnabled must be enabled on both the client
-+and server side of the connection. When the connection switches to the NONE
-+cipher a warning is sent to STDERR. The connection attempt will fail with an
-+error if a client requests a NoneSwitch from the server that does not explicitly
-+have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
-+interactive (shell) sessions and it will fail silently. Set to no by default.
-+
-+HPNDisabled=[yes/no] client/server
-+     In some situations, such as transfers on a local area network, the impact 
-+of the HPN code produces a net decrease in performance. In these cases it is 
-+helpful to disable the HPN functionality. By default HPNDisabled is set to no. 
-+
-+HPNBufferSize=[int]KB client/server
-+     This is the default buffer size the HPN functionality uses when interacting
-+with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
-+option as applied to the internal SSH flow control. This value can range from 
-+1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
-+problems depending on the length of the network path. The default size of this buffer
-+is 2MB.
-+
-+
-+Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
-+         The majority of the actual coding for versions up to HPN12v1 was performed
-+         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was 
-+       implemented by Ben Bennet (ben@psc.edu). This work was financed, in part,
-+         by Cisco System, Inc., the National Library of Medicine, 
-+       and the National Science Foundation. 
-diff -NupwB openssh-5.0p1/kex.c openssh-5.0p1-hpn13v4-sink/kex.c
---- openssh-5.0p1/kex.c        2007-06-05 04:30:18.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/kex.c   2008-05-07 13:54:53.000000000 -0400
-@@ -48,6 +48,7 @@
- #include "match.h"
- #include "dispatch.h"
- #include "monitor.h"
-+#include "canohost.h"
- #define KEX_COOKIE_LEN        16
-@@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
- static void kex_choose_conf(Kex *);
- /* put algorithm proposal into buffer */
--static void
-+/* used in sshconnect.c as well as kex.c */
-+void
- kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
- {
-       u_int i;
-@@ -376,6 +378,13 @@ kex_choose_conf(Kex *kex)
-       int nenc, nmac, ncomp;
-       u_int mode, ctos, need;
-       int first_kex_follows, type;
-+      int log_flag = 0;
-+
-+      int auth_flag;
-+
-+      auth_flag = packet_authentication_state();
-+
-+      debug ("AUTH STATE IS %d", auth_flag);
-       my   = kex_buf2prop(&kex->my, NULL);
-       peer = kex_buf2prop(&kex->peer, &first_kex_follows);
-@@ -400,11 +409,34 @@ kex_choose_conf(Kex *kex)
-               choose_enc (&newkeys->enc,  cprop[nenc],  sprop[nenc]);
-               choose_mac (&newkeys->mac,  cprop[nmac],  sprop[nmac]);
-               choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
-+              debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
-+              if (strcmp(newkeys->enc.name, "none") == 0) {
-+                              debug("Requesting NONE. Authflag is %d", auth_flag);                    
-+                      if (auth_flag == 1) {
-+                              debug("None requested post authentication.");
-+                      } else {
-+                              fatal("Pre-authentication none cipher requests are not allowed.");
-+                      }
-+              } 
-               debug("kex: %s %s %s %s",
-                   ctos ? "client->server" : "server->client",
-                   newkeys->enc.name,
-                   newkeys->mac.name,
-                   newkeys->comp.name);
-+              /* client starts withctos = 0 && log flag = 0 and no log*/
-+              /* 2nd client pass ctos=1 and flag = 1 so no log*/
-+              /* server starts with ctos =1 && log_flag = 0 so log */
-+              /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
-+              /* -cjr*/
-+              if (ctos && !log_flag) {
-+                      logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
-+                            get_remote_ipaddr(),
-+                            get_remote_port(),
-+                            newkeys->enc.name,
-+                            newkeys->mac.name,
-+                            newkeys->comp.name);
-+              }
-+              log_flag = 1;
-       }
-       choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
-       choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
-diff -NupwB openssh-5.0p1/kex.h openssh-5.0p1-hpn13v4-sink/kex.h
---- openssh-5.0p1/kex.h        2007-06-11 00:01:42.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/kex.h   2008-05-07 13:54:53.000000000 -0400
-@@ -127,6 +127,8 @@ struct Kex {
-       void    (*kex[KEX_MAX])(Kex *);
- };
-+void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
-+
- Kex   *kex_setup(char *[PROPOSAL_MAX]);
- void   kex_finish(Kex *);
-diff -NupwB openssh-5.0p1/Makefile.in openssh-5.0p1-hpn13v4-sink/Makefile.in
---- openssh-5.0p1/Makefile.in  2008-03-12 21:41:31.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/Makefile.in     2008-05-07 13:54:53.000000000 -0400
-@@ -43,7 +43,7 @@ CC=@CC@
- LD=@LD@
- CFLAGS=@CFLAGS@
- CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
--LIBS=@LIBS@
-+LIBS=@LIBS@ -lpthread
- SSHDLIBS=@SSHDLIBS@
- LIBEDIT=@LIBEDIT@
- AR=@AR@
-@@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
- LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
-       canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
--      cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
-+      cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
-       compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
-       log.o match.o md-sha256.o moduli.o nchan.o packet.o \
-       readpass.o rsa.o ttymodes.o xmalloc.o \
-diff -NupwB openssh-5.0p1/myproposal.h openssh-5.0p1-hpn13v4-sink/myproposal.h
---- openssh-5.0p1/myproposal.h 2007-06-11 00:01:42.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/myproposal.h    2008-05-07 13:54:53.000000000 -0400
-@@ -46,6 +46,8 @@
-       "arcfour128,arcfour256,arcfour," \
-       "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
-       "aes128-ctr,aes192-ctr,aes256-ctr"
-+#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
-+      ",none"
- #define       KEX_DEFAULT_MAC \
-       "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
-       "hmac-ripemd160@openssh.com," \
-Common subdirectories: openssh-5.0p1/openbsd-compat and openssh-5.0p1-hpn13v4-sink/openbsd-compat
-diff -NupwB openssh-5.0p1/packet.c openssh-5.0p1-hpn13v4-sink/packet.c
---- openssh-5.0p1/packet.c     2008-03-07 02:33:30.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/packet.c        2008-05-07 13:54:53.000000000 -0400
-@@ -712,7 +712,7 @@ packet_enable_delayed_compress(void)
- /*
-  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
-  */
--static void
-+static int
- packet_send2_wrapped(void)
- {
-       u_char type, *cp, *macbuf = NULL;
-@@ -824,11 +824,13 @@ packet_send2_wrapped(void)
-               set_newkeys(MODE_OUT);
-       else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
-               packet_enable_delayed_compress();
-+      return(packet_length);
- }
--static void
-+static int
- packet_send2(void)
- {
-+        static int packet_length = 0;
-       static int rekeying = 0;
-       struct packet *p;
-       u_char type, *cp;
-@@ -846,7 +848,7 @@ packet_send2(void)
-                       memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
-                       buffer_init(&outgoing_packet);
-                       TAILQ_INSERT_TAIL(&outgoing, p, next);
--                      return;
-+                      return(sizeof(Buffer));
-               }
-       }
-@@ -854,7 +856,7 @@ packet_send2(void)
-       if (type == SSH2_MSG_KEXINIT)
-               rekeying = 1;
--      packet_send2_wrapped();
-+      packet_length = packet_send2_wrapped();
-       /* after a NEWKEYS message we can send the complete queue */
-       if (type == SSH2_MSG_NEWKEYS) {
-@@ -867,19 +869,22 @@ packet_send2(void)
-                           sizeof(Buffer));
-                       TAILQ_REMOVE(&outgoing, p, next);
-                       xfree(p);
--                      packet_send2_wrapped();
-+                      packet_length += packet_send2_wrapped();
-               }
-       }
-+      return(packet_length);
- }
--void
-+int
- packet_send(void)
- {
-+  int packet_len = 0;
-       if (compat20)
--              packet_send2();
-+              packet_len = packet_send2();
-       else
-               packet_send1();
-       DBG(debug("packet_send done"));
-+      return(packet_len);
- }
- /*
-@@ -1419,21 +1424,23 @@ packet_disconnect(const char *fmt,...)
- /* Checks if there is any buffered output, and tries to write some of the output. */
--void
-+int
- packet_write_poll(void)
- {
--      int len = buffer_len(&output);
-+      int len = 0;
-+      len = buffer_len(&output);
-       if (len > 0) {
-               len = write(connection_out, buffer_ptr(&output), len);
-               if (len <= 0) {
-                       if (errno == EAGAIN)
--                              return;
-+                        return (0);
-                       else
-                               fatal("Write failed: %.100s", strerror(errno));
-               }
-               buffer_consume(&output, len);
-       }
-+      return(len);
- }
- /*
-@@ -1441,14 +1448,15 @@ packet_write_poll(void)
-  * written.
-  */
--void
-+int
- packet_write_wait(void)
- {
-       fd_set *setp;
-+      u_int bytes_sent = 0;
-       setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
-           sizeof(fd_mask));
--      packet_write_poll();
-+      bytes_sent += packet_write_poll();
-       while (packet_have_data_to_write()) {
-               memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
-                   sizeof(fd_mask));
-@@ -1456,9 +1464,10 @@ packet_write_wait(void)
-               while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
-                   (errno == EAGAIN || errno == EINTR))
-                       ;
--              packet_write_poll();
-+              bytes_sent += packet_write_poll();
-       }
-       xfree(setp);
-+      return (bytes_sent);
- }
- /* Returns true if there is buffered data to write to the connection. */
-@@ -1580,12 +1589,24 @@ packet_send_ignore(int nbytes)
-       }
- }
-+int rekey_requested = 0;
-+void
-+packet_request_rekeying(void)
-+{
-+      rekey_requested = 1;
-+}
-+
- #define MAX_PACKETS   (1U<<31)
- int
- packet_need_rekeying(void)
- {
-       if (datafellows & SSH_BUG_NOREKEY)
-               return 0;
-+      if (rekey_requested == 1)
-+      {
-+              rekey_requested = 0;
-+              return 1;
-+      }
-       return
-           (p_send.packets > MAX_PACKETS) ||
-           (p_read.packets > MAX_PACKETS) ||
-@@ -1610,3 +1631,9 @@ packet_set_authenticated(void)
- {
-       after_authentication = 1;
- }
-+
-+int
-+packet_authentication_state(void)
-+{
-+      return(after_authentication);
-+}
-diff -NupwB openssh-5.0p1/packet.h openssh-5.0p1-hpn13v4-sink/packet.h
---- openssh-5.0p1/packet.h     2008-03-07 02:33:30.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/packet.h        2008-05-07 13:54:53.000000000 -0400
-@@ -20,6 +20,9 @@
- #include <openssl/bn.h>
-+void
-+packet_request_rekeying(void);
-+
- void     packet_set_connection(int, int);
- void     packet_set_nonblocking(void);
- int      packet_get_connection_in(void);
-@@ -34,6 +37,7 @@ void     packet_set_interactive(int);
- int      packet_is_interactive(void);
- void     packet_set_server(void);
- void     packet_set_authenticated(void);
-+int    packet_authentication_state(void);
- void     packet_start(u_char);
- void     packet_put_char(int ch);
-@@ -43,7 +47,7 @@ void     packet_put_bignum2(BIGNUM * val
- void     packet_put_string(const void *buf, u_int len);
- void     packet_put_cstring(const char *str);
- void     packet_put_raw(const void *buf, u_int len);
--void     packet_send(void);
-+int      packet_send(void);
- int      packet_read(void);
- void     packet_read_expect(int type);
-@@ -71,8 +75,8 @@ void  packet_set_state(int, u_int32_t, u
- int    packet_get_ssh1_cipher(void);
- void   packet_set_iv(int, u_char *);
--void     packet_write_poll(void);
--void     packet_write_wait(void);
-+int      packet_write_poll(void);
-+int      packet_write_wait(void);
- int      packet_have_data_to_write(void);
- int      packet_not_very_much_data_to_write(void);
-diff -NupwB openssh-5.0p1/progressmeter.c openssh-5.0p1-hpn13v4-sink/progressmeter.c
---- openssh-5.0p1/progressmeter.c      2006-08-04 22:39:40.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/progressmeter.c 2008-05-07 13:54:53.000000000 -0400
-@@ -68,6 +68,8 @@ static time_t last_update;   /* last progr
- static char *file;            /* name of the file being transferred */
- static off_t end_pos;         /* ending position of transfer */
- static off_t cur_pos;         /* transfer position as of last refresh */
-+static off_t last_pos;
-+static off_t max_delta_pos = 0;
- static volatile off_t *counter;       /* progress counter */
- static long stalled;          /* how long we have been stalled */
- static int bytes_per_second;  /* current speed in bytes per second */
-@@ -128,12 +130,17 @@ refresh_progress_meter(void)
-       int hours, minutes, seconds;
-       int i, len;
-       int file_len;
-+      off_t delta_pos;
-       transferred = *counter - cur_pos;
-       cur_pos = *counter;
-       now = time(NULL);
-       bytes_left = end_pos - cur_pos;
-+      delta_pos = cur_pos - last_pos;
-+      if (delta_pos > max_delta_pos) 
-+              max_delta_pos = delta_pos;
-+
-       if (bytes_left > 0)
-               elapsed = now - last_update;
-       else {
-@@ -158,7 +165,7 @@ refresh_progress_meter(void)
-       /* filename */
-       buf[0] = '\0';
--      file_len = win_size - 35;
-+      file_len = win_size - 45;
-       if (file_len > 0) {
-               len = snprintf(buf, file_len + 1, "\r%s", file);
-               if (len < 0)
-@@ -175,7 +182,8 @@ refresh_progress_meter(void)
-               percent = ((float)cur_pos / end_pos) * 100;
-       else
-               percent = 100;
--      snprintf(buf + strlen(buf), win_size - strlen(buf),
-+
-+      snprintf(buf + strlen(buf), win_size - strlen(buf-8),
-           " %3d%% ", percent);
-       /* amount transferred */
-@@ -188,6 +196,11 @@ refresh_progress_meter(void)
-           (off_t)bytes_per_second);
-       strlcat(buf, "/s ", win_size);
-+      /* instantaneous rate */
-+      format_rate(buf + strlen(buf), win_size - strlen(buf),
-+          delta_pos);
-+      strlcat(buf, "/s ", win_size);
-+
-       /* ETA */
-       if (!transferred)
-               stalled += elapsed;
-@@ -224,6 +237,7 @@ refresh_progress_meter(void)
-       atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
-       last_update = now;
-+      last_pos = cur_pos;
- }
- /*ARGSUSED*/
-@@ -270,6 +284,7 @@ void
- stop_progress_meter(void)
- {
-       alarm(0);
-+      char lbuf[10];
-       if (!can_output())
-               return;
-@@ -278,6 +293,8 @@ stop_progress_meter(void)
-       if (cur_pos != end_pos)
-               refresh_progress_meter();
-+      format_rate(lbuf, sizeof(lbuf), max_delta_pos);
-+      printf("\nMax throughput: %s/s\n", lbuf);
-       atomicio(vwrite, STDOUT_FILENO, "\n", 1);
- }
-diff -NupwB openssh-5.0p1/readconf.c openssh-5.0p1-hpn13v4-sink/readconf.c
---- openssh-5.0p1/readconf.c   2008-02-10 06:25:52.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/readconf.c      2008-05-07 13:54:53.000000000 -0400
-@@ -130,6 +130,8 @@ typedef enum {
-       oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
-       oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
-       oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
-+      oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
-+      oHPNBufferSize,
-       oDeprecated, oUnsupported
- } OpCodes;
-@@ -226,6 +228,12 @@ static struct {
-       { "tunneldevice", oTunnelDevice },
-       { "localcommand", oLocalCommand },
-       { "permitlocalcommand", oPermitLocalCommand },
-+        { "noneenabled", oNoneEnabled },
-+        { "tcprcvbufpoll", oTcpRcvBufPoll },
-+        { "tcprcvbuf", oTcpRcvBuf },
-+        { "noneswitch", oNoneSwitch },
-+      { "hpndisabled", oHPNDisabled },
-+      { "hpnbuffersize", oHPNBufferSize },
-       { NULL, oBadOption }
- };
-@@ -454,6 +462,37 @@ parse_flag:
-               intptr = &options->check_host_ip;
-               goto parse_flag;
-+      case oNoneEnabled:
-+              intptr = &options->none_enabled;
-+              goto parse_flag;
-+ 
-+      /* we check to see if the command comes from the */
-+      /* command line or not. If it does then enable it */
-+      /* otherwise fail. NONE should never be a default configuration */
-+      case oNoneSwitch:
-+              if(strcmp(filename,"command-line")==0)
-+              {               
-+                  intptr = &options->none_switch;
-+                  goto parse_flag;
-+              } else {
-+                  error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
-+                  error("Continuing...");
-+                  debug("NoneSwitch directive found in %.200s.", filename);
-+                  return 0;
-+              }
-+
-+      case oHPNDisabled:
-+              intptr = &options->hpn_disabled;
-+              goto parse_flag;
-+
-+      case oHPNBufferSize:
-+              intptr = &options->hpn_buffer_size;
-+              goto parse_int;
-+
-+      case oTcpRcvBufPoll:
-+              intptr = &options->tcp_rcv_buf_poll;
-+              goto parse_flag;
-+
-       case oVerifyHostKeyDNS:
-               intptr = &options->verify_host_key_dns;
-               goto parse_yesnoask;
-@@ -632,6 +671,10 @@ parse_int:
-               intptr = &options->connection_attempts;
-               goto parse_int;
-+      case oTcpRcvBuf:
-+              intptr = &options->tcp_rcv_buf;
-+              goto parse_int;
-+
-       case oCipher:
-               intptr = &options->cipher;
-               arg = strdelim(&s);
-@@ -1065,6 +1108,12 @@ initialize_options(Options * options)
-       options->tun_remote = -1;
-       options->local_command = NULL;
-       options->permit_local_command = -1;
-+      options->none_switch = -1;
-+      options->none_enabled = -1;
-+      options->hpn_disabled = -1;
-+      options->hpn_buffer_size = -1;
-+      options->tcp_rcv_buf_poll = -1;
-+      options->tcp_rcv_buf = -1;
- }
- /*
-@@ -1187,6 +1236,29 @@ fill_default_options(Options * options)
-               options->server_alive_interval = 0;
-       if (options->server_alive_count_max == -1)
-               options->server_alive_count_max = 3;
-+      if (options->none_switch == -1)
-+              options->none_switch = 0;
-+      if (options->hpn_disabled == -1)
-+              options->hpn_disabled = 0;
-+      if (options->hpn_buffer_size > -1)
-+      {
-+        /* if a user tries to set the size to 0 set it to 1KB */
-+              if (options->hpn_buffer_size == 0)
-+              options->hpn_buffer_size = 1024;
-+              /*limit the buffer to 64MB*/
-+              if (options->hpn_buffer_size > 65536)
-+              {
-+                      options->hpn_buffer_size = 65536*1024;
-+                      debug("User requested buffer larger than 64MB. Request reverted to 64MB");
-+              }
-+              debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
-+      }
-+      if (options->tcp_rcv_buf == 0)
-+              options->tcp_rcv_buf = 1;
-+      if (options->tcp_rcv_buf > -1) 
-+              options->tcp_rcv_buf *=1024;
-+      if (options->tcp_rcv_buf_poll == -1)
-+              options->tcp_rcv_buf_poll = 1;
-       if (options->control_master == -1)
-               options->control_master = 0;
-       if (options->hash_known_hosts == -1)
-diff -NupwB openssh-5.0p1/readconf.h openssh-5.0p1-hpn13v4-sink/readconf.h
---- openssh-5.0p1/readconf.h   2008-02-10 06:25:52.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/readconf.h      2008-05-07 13:54:53.000000000 -0400
-@@ -56,6 +56,11 @@ 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 */
-+      int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
-+      int     hpn_disabled;    /* Switch to disable HPN buffer management */
-+      int     hpn_buffer_size; /* User definable size for HPN buffer window */
-+
-       LogLevel log_level;     /* Level for logging. */
-       int     port;           /* Port to connect. */
-@@ -101,6 +106,8 @@ typedef struct {
-       int     enable_ssh_keysign;
-       int64_t rekey_limit;
-+      int     none_switch;    /* Use none cipher */
-+      int     none_enabled;   /* Allow none to be used */
-       int     no_host_authentication_for_localhost;
-       int     identities_only;
-       int     server_alive_interval;
-Common subdirectories: openssh-5.0p1/regress and openssh-5.0p1-hpn13v4-sink/regress
-Common subdirectories: openssh-5.0p1/scard and openssh-5.0p1-hpn13v4-sink/scard
-diff -NupwB openssh-5.0p1/scp.c openssh-5.0p1-hpn13v4-sink/scp.c
---- openssh-5.0p1/scp.c        2008-03-13 20:59:50.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/scp.c   2008-05-07 13:54:53.000000000 -0400
-@@ -631,7 +631,7 @@ source(int argc, char **argv)
-       BUF *bp;
-       off_t i, amt, statbytes;
-       int fd = -1, haderr, indx;
--      char *last, *name, buf[2048], encname[MAXPATHLEN];
-+      char *last, *name, buf[16384], encname[MAXPATHLEN];
-       int len;
-       for (indx = 0; indx < argc; ++indx) {
-@@ -863,7 +863,7 @@ sink(int argc, char **argv)
-       mode_t mode, omode, mask;
-       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]
-diff -NupwB openssh-5.0p1/servconf.c openssh-5.0p1-hpn13v4-sink/servconf.c
---- openssh-5.0p1/servconf.c   2008-02-10 06:48:55.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/servconf.c      2008-05-07 13:54:53.000000000 -0400
-@@ -123,11 +123,20 @@ initialize_server_options(ServerOptions 
-       options->num_permitted_opens = -1;
-       options->adm_forced_command = NULL;
-       options->chroot_directory = NULL;
-+      options->none_enabled = -1;
-+      options->tcp_rcv_buf_poll = -1;
-+      options->hpn_disabled = -1;
-+      options->hpn_buffer_size = -1;
- }
- void
- fill_default_server_options(ServerOptions *options)
- {
-+      /* needed for hpn socket tests */
-+      int sock;
-+      int socksize;
-+      int socksizelen = sizeof(int);
-+
-       /* Portable-specific options */
-       if (options->use_pam == -1)
-               options->use_pam = 0;
-@@ -251,6 +260,42 @@ fill_default_server_options(ServerOption
-       if (options->permit_tun == -1)
-               options->permit_tun = SSH_TUNMODE_NO;
-+      if (options->hpn_disabled == -1) 
-+              options->hpn_disabled = 0;
-+
-+      if (options->hpn_buffer_size == -1) {
-+              /* option not explicitly set. Now we have to figure out */
-+              /* what value to use */
-+              if (options->hpn_disabled == 1) {
-+                      options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
-+              } else {
-+                      /* get the current RCV size and set it to that */
-+                      /*create a socket but don't connect it */
-+                      /* we use that the get the rcv socket size */
-+                      sock = socket(AF_INET, SOCK_STREAM, 0);
-+                      getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
-+                                 &socksize, &socksizelen);
-+                      close(sock);
-+                      options->hpn_buffer_size = socksize;
-+                      debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
-+                      
-+              } 
-+      } else {
-+              /* we have to do this incase the user sets both values in a contradictory */
-+              /* manner. hpn_disabled overrrides hpn_buffer_size*/
-+              if (options->hpn_disabled <= 0) {
-+                      if (options->hpn_buffer_size == 0)
-+                              options->hpn_buffer_size = 1;
-+                      /* limit the maximum buffer to 64MB */
-+                      if (options->hpn_buffer_size > 64*1024) {
-+                              options->hpn_buffer_size = 64*1024*1024;
-+                      } else {
-+                              options->hpn_buffer_size *= 1024;
-+                      }
-+              } else
-+                      options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
-+      }
-+
-       /* Turn privilege separation on by default */
-       if (use_privsep == -1)
-               use_privsep = 1;
-@@ -293,7 +338,8 @@ typedef enum {
-       sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
-       sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
-       sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
--      sUsePrivilegeSeparation,
-+      sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
-+      sHPNDisabled, sHPNBufferSize,
-       sDeprecated, sUnsupported
- } ServerOpCodes;
-@@ -405,6 +451,10 @@ static struct {
-       { "permitopen", sPermitOpen, SSHCFG_ALL },
-       { "forcecommand", sForceCommand, SSHCFG_ALL },
-       { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
-+      { "noneenabled", sNoneEnabled },
-+      { "hpndisabled", sHPNDisabled },
-+      { "hpnbuffersize", sHPNBufferSize },
-+      { "tcprcvbufpoll", sTcpRcvBufPoll },
-       { NULL, sBadOption, 0 }
- };
-@@ -420,6 +470,7 @@ parse_token(const char *cp, const char *
-       for (i = 0; keywords[i].name; i++)
-               if (strcasecmp(cp, keywords[i].name) == 0) {
-+                      debug ("Config token is %s", keywords[i].name);
-                       *flags = keywords[i].flags;
-                       return keywords[i].opcode;
-               }
-@@ -831,6 +882,22 @@ parse_flag:
-                       *intptr = value;
-               break;
-+      case sNoneEnabled:
-+              intptr = &options->none_enabled;
-+              goto parse_flag;
-+
-+      case sTcpRcvBufPoll:
-+              intptr = &options->tcp_rcv_buf_poll;
-+              goto parse_flag;
-+
-+      case sHPNDisabled:
-+              intptr = &options->hpn_disabled;
-+              goto parse_flag;
-+
-+      case sHPNBufferSize:
-+              intptr = &options->hpn_buffer_size;
-+              goto parse_int;
-+
-       case sIgnoreUserKnownHosts:
-               intptr = &options->ignore_user_known_hosts;
-               goto parse_flag;
-diff -NupwB openssh-5.0p1/servconf.h openssh-5.0p1-hpn13v4-sink/servconf.h
---- openssh-5.0p1/servconf.h   2008-03-07 02:31:24.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/servconf.h      2008-05-07 13:54:53.000000000 -0400
-@@ -140,6 +140,10 @@ typedef struct {
-       char   *adm_forced_command;
-       int     use_pam;                /* Enable auth via PAM */
-+        int     none_enabled;           /* enable NONE cipher switch */
-+        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
-+      int     hpn_disabled;           /* disable hpn functionality. false by default */
-+      int     hpn_buffer_size;        /* set the hpn buffer size - default 3MB */
-       int     permit_tun;
-diff -NupwB openssh-5.0p1/serverloop.c openssh-5.0p1-hpn13v4-sink/serverloop.c
---- openssh-5.0p1/serverloop.c 2008-03-07 02:33:30.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/serverloop.c    2008-05-07 13:54:53.000000000 -0400
-@@ -92,10 +92,10 @@ static int fdin;           /* Descriptor for stdi
- static int fdout;             /* Descriptor for stdout (for reading);
-                                  May be same number as fdin. */
- static int fderr;             /* Descriptor for stderr.  May be -1. */
--static long stdin_bytes = 0;  /* Number of bytes written to stdin. */
--static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
--static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
--static long fdout_bytes = 0;  /* Number of stdout bytes read from program. */
-+static u_long stdin_bytes = 0;        /* Number of bytes written to stdin. */
-+static u_long stdout_bytes = 0;       /* Number of stdout bytes sent to client. */
-+static u_long stderr_bytes = 0;       /* Number of stderr bytes sent to client. */
-+static u_long fdout_bytes = 0;        /* Number of stdout bytes read from program. */
- static int stdin_eof = 0;     /* EOF message received from client. */
- static int fdout_eof = 0;     /* EOF encountered reading from fdout. */
- static int fderr_eof = 0;     /* EOF encountered readung from fderr. */
-@@ -119,6 +119,20 @@ static volatile sig_atomic_t received_si
- static void server_init_dispatch(void);
- /*
-+ * Returns current time in seconds from Jan 1, 1970 with the maximum
-+ * available resolution.
-+ */
-+
-+static double
-+get_current_time(void)
-+{
-+      struct timeval tv;
-+      gettimeofday(&tv, NULL);
-+      return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
-+}
-+
-+
-+/*
-  * we write to this pipe if a SIGCHLD is caught in order to avoid
-  * the race between select() and child_terminated
-  */
-@@ -407,6 +421,7 @@ process_input(fd_set *readset)
-               } else {
-                       /* Buffer any received data. */
-                       packet_process_incoming(buf, len);
-+                      fdout_bytes += len;
-               }
-       }
-       if (compat20)
-@@ -429,6 +444,7 @@ process_input(fd_set *readset)
-               } else {
-                       buffer_append(&stdout_buffer, buf, len);
-                       fdout_bytes += len;
-+                      debug ("FD out now: %ld", fdout_bytes);
-               }
-       }
-       /* Read and buffer any available stderr data from the program. */
-@@ -495,7 +511,7 @@ process_output(fd_set *writeset)
-       }
-       /* Send any buffered packet data to the client. */
-       if (FD_ISSET(connection_out, writeset))
--              packet_write_poll();
-+              stdin_bytes += packet_write_poll();
- }
- /*
-@@ -812,8 +828,10 @@ server_loop2(Authctxt *authctxt)
- {
-       fd_set *readset = NULL, *writeset = NULL;
-       int rekeying = 0, max_fd, nalloc = 0;
-+      double start_time, total_time;
-       debug("Entering interactive session for SSH2.");
-+      start_time = get_current_time();
-       mysignal(SIGCHLD, sigchld_handler);
-       child_terminated = 0;
-@@ -875,6 +893,11 @@ server_loop2(Authctxt *authctxt)
-       /* free remaining sessions, e.g. remove wtmp entries */
-       session_destroy_all(NULL);
-+      total_time = get_current_time() - start_time;
-+      logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
-+            get_remote_ipaddr(), get_remote_port(),
-+            stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
-+            fdout_bytes / total_time);
- }
- static void
-@@ -956,9 +979,14 @@ server_request_direct_tcpip(void)
-       xfree(originator);
-       if (sock < 0)
-               return NULL;
-+      if (options.hpn_disabled)
-       c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
-           sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
-           CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
-+      else
-+              c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
-+                  sock, sock, -1, options.hpn_buffer_size,
-+                  CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
-       return c;
- }
-@@ -993,8 +1021,12 @@ server_request_tun(void)
-       sock = tun_open(tun, mode);
-       if (sock < 0)
-               goto done;
-+      if (options.hpn_disabled)
-       c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
-           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
-+      else
-+              c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
-+                  options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
-       c->datagram = 1;
- #if defined(SSH_TUN_FILTER)
-       if (mode == SSH_TUNMODE_POINTOPOINT)
-@@ -1024,6 +1056,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 ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled))
-+              c->dynamic_window = 1;
-       if (session_open(the_authctxt, c->self) != 1) {
-               debug("session open failed, free channel %d", c->self);
-               channel_free(c);
-@@ -1120,7 +1154,8 @@ server_input_global_request(int type, u_
-               } else {
-                       /* Start listening on the port */
-                       success = channel_setup_remote_fwd_listener(
--                          listen_address, listen_port, options.gateway_ports);
-+                          listen_address, listen_port, options.gateway_ports, 
-+                          options.hpn_disabled, options.hpn_buffer_size);
-               }
-               xfree(listen_address);
-       } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
-diff -NupwB openssh-5.0p1/session.c openssh-5.0p1-hpn13v4-sink/session.c
---- openssh-5.0p1/session.c    2008-03-26 20:03:05.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/session.c       2008-05-07 13:54:53.000000000 -0400
-@@ -217,6 +217,7 @@ auth_input_request_forwarding(struct pas
-               packet_disconnect("listen: %.100s", strerror(errno));
-       /* Allocate a channel for the authentication agent socket. */
-+      /* this shouldn't matter if its hpn or not - cjr */
-       nc = channel_new("auth socket",
-           SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
-           CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-@@ -354,7 +355,8 @@ do_authenticated1(Authctxt *authctxt)
-                       }
-                       debug("Received TCP/IP port forwarding request.");
-                       if (channel_input_port_forward_request(s->pw->pw_uid == 0,
--                          options.gateway_ports) < 0) {
-+                            options.gateway_ports, options.hpn_disabled,
-+                              options.hpn_buffer_size) < 0) {
-                               debug("Port forwarding failed.");
-                               break;
-                       }
-@@ -2147,11 +2149,18 @@ session_set_fds(Session *s, int fdin, in
-        */
-       if (s->chanid == -1)
-               fatal("no channel for session %d", s->self);
-+      if(options.hpn_disabled) 
-       channel_set_fds(s->chanid,
-           fdout, fdin, fderr,
-           fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
-           1,
-           CHAN_SES_WINDOW_DEFAULT);
-+      else
-+              channel_set_fds(s->chanid,
-+                  fdout, fdin, fderr,
-+                  fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
-+                  1,
-+                  options.hpn_buffer_size);
- }
- /*
-@@ -2496,7 +2505,8 @@ session_setup_x11fwd(Session *s)
-       }
-       if (x11_create_display_inet(options.x11_display_offset,
-           options.x11_use_localhost, s->single_connection,
--          &s->display_number, &s->x11_chanids) == -1) {
-+          &s->display_number, &s->x11_chanids, 
-+          options.hpn_disabled, options.hpn_buffer_size) == -1) {
-               debug("x11_create_display_inet failed.");
-               return 0;
-       }
-diff -NupwB openssh-5.0p1/ssh.c openssh-5.0p1-hpn13v4-sink/ssh.c
---- openssh-5.0p1/ssh.c        2008-02-28 03:13:52.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/ssh.c   2008-05-07 13:55:20.000000000 -0400
-@@ -503,9 +503,6 @@ main(int ac, char **av)
-                       no_shell_flag = 1;
-                       no_tty_flag = 1;
-                       break;
--              case 'T':
--                      no_tty_flag = 1;
--                      break;
-               case 'o':
-                       dummy = 1;
-                       line = xstrdup(optarg);
-@@ -514,6 +511,13 @@ main(int ac, char **av)
-                               exit(255);
-                       xfree(line);
-                       break;
-+              case 'T':
-+                      no_tty_flag = 1;
-+                      /* ensure that the user doesn't try to backdoor a */
-+                      /* null cipher switch on an interactive session */
-+                      /* so explicitly disable it no matter what */
-+                      options.none_switch=0;
-+                      break;
-               case 's':
-                       subsystem_flag = 1;
-                       break;
-@@ -842,7 +846,8 @@ ssh_init_forwarding(void)
-                   options.local_forwards[i].listen_port,
-                   options.local_forwards[i].connect_host,
-                   options.local_forwards[i].connect_port,
--                  options.gateway_ports);
-+                  options.gateway_ports, options.hpn_disabled,
-+                  options.hpn_buffer_size);
-       }
-       if (i > 0 && success != i && options.exit_on_forward_failure)
-               fatal("Could not request local forwarding.");
-@@ -1160,6 +1165,10 @@ ssh_session2_open(void)
- {
-       Channel *c;
-       int window, packetmax, in, out, err;
-+      int sock;
-+      int socksize;
-+      int socksizelen = sizeof(int);
-+      int init_window_size;
-       if (stdin_null_flag) {
-               in = open(_PATH_DEVNULL, O_RDONLY);
-@@ -1180,9 +1189,76 @@ ssh_session2_open(void)
-       if (!isatty(err))
-               set_nonblock(err);
--      window = CHAN_SES_WINDOW_DEFAULT;
-+      /* we need to check to see if what they want to do about buffer */
-+      /* sizes here. In a hpn to nonhpn connection we want to limit */
-+      /* the window size to something reasonable in case the far side */
-+      /* has the large window bug. In hpn to hpn connection we want to */
-+      /* use the max window size but allow the user to override it */
-+      /* lastly if they disabled hpn then use the ssh std window size */
-+
-+      /* so why don't we just do a getsockopt() here and set the */
-+      /* ssh window to that? In the case of a autotuning receive */
-+      /* window the window would get stuck at the initial buffer */
-+      /* size generally less than 96k. Therefore we need to set the */
-+      /* maximum ssh window size to the maximum hpn buffer size */
-+      /* unless the user has specifically set the tcprcvbufpoll */
-+      /* to no. In which case we *can* just set the window to the */
-+      /* minimum of the hpn buffer size and tcp receive buffer size */
-+      
-+      if(options.hpn_disabled)
-+      {
-+              options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
-+              init_window_size = CHAN_SES_WINDOW_DEFAULT;
-+      }
-+      else if (datafellows & SSH_BUG_LARGEWINDOW) 
-+      {
-+              debug("HPN to Non-HPN Connection");
-+              if (options.hpn_buffer_size < 0)
-+                      options.hpn_buffer_size = 2*1024*1024;
-+              init_window_size = options.hpn_buffer_size;
-+      } 
-+      else 
-+      {
-+              if (options.hpn_buffer_size < 0)
-+                      options.hpn_buffer_size = BUFFER_MAX_LEN_HPN;
-+
-+              /*create a socket but don't connect it */
-+              /* we use that the get the rcv socket size */
-+              sock = socket(AF_INET, SOCK_STREAM, 0);
-+              /* if they are using the tcp_rcv_buf option */
-+              /* attempt to set the buffer size to that */
-+              if (options.tcp_rcv_buf > 0) 
-+                      setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
-+                                 sizeof(options.tcp_rcv_buf));
-+              getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
-+                         &socksize, &socksizelen);
-+              close(sock);
-+              init_window_size = socksize;
-+              if (options.tcp_rcv_buf_poll <= 0) 
-+              {
-+                      options.hpn_buffer_size = MIN(socksize,options.hpn_buffer_size);
-+                      debug ("MIN of TCP RWIN and HPNBufferSize: %d", options.hpn_buffer_size);
-+              } 
-+              else
-+              {
-+                      if (options.tcp_rcv_buf > 0) 
-+                      { 
-+                              options.hpn_buffer_size = MIN(options.tcp_rcv_buf, options.hpn_buffer_size);
-+                              debug ("MIN of TCPRcvBuf and HPNBufferSize: %d", options.hpn_buffer_size);
-+              }
-+              }
-+              
-+      }
-+
-+
-+      debug("Final hpn_buffer_size: %d bytes", options.hpn_buffer_size);
-+      debug("Initial channel window size: %d bytes", init_window_size);
-+
-+      window = init_window_size;
-+
-       packetmax = CHAN_SES_PACKET_DEFAULT;
-       if (tty_flag) {
-+              window = 4*CHAN_SES_PACKET_DEFAULT;
-               window >>= 1;
-               packetmax >>= 1;
-       }
-@@ -1190,7 +1266,10 @@ ssh_session2_open(void)
-           "session", SSH_CHANNEL_OPENING, in, out, err,
-           window, packetmax, CHAN_EXTENDED_WRITE,
-           "client-session", /*nonblock*/0);
--
-+      if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
-+              c->dynamic_window = 1;
-+              debug ("Enabled Dynamic Window Scaling\n");
-+      }
-       debug3("ssh_session2_open: channel_new: %d", c->self);
-       channel_send_open(c->self);
-diff -NupwB openssh-5.0p1/sshconnect2.c openssh-5.0p1-hpn13v4-sink/sshconnect2.c
---- openssh-5.0p1/sshconnect2.c        2008-02-10 06:25:53.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/sshconnect2.c   2008-05-07 13:54:53.000000000 -0400
-@@ -73,6 +73,12 @@
- extern char *client_version_string;
- extern char *server_version_string;
- extern Options options;
-+extern Kex *xxx_kex;
-+
-+/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
-+/* if it is set then prevent the switch to the null cipher */
-+
-+extern int tty_flag;
- /*
-  * SSH2 key exchange
-@@ -326,6 +332,28 @@ ssh_userauth2(const char *local_user, co
-       pubkey_cleanup(&authctxt);
-       dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
-+      /* if the user wants to use the none cipher do it */
-+      /* post authentication and only if the right conditions are met */
-+      /* both of the NONE commands must be true and there must be no */
-+      /* tty allocated */
-+      if ((options.none_switch == 1) && (options.none_enabled == 1)) 
-+      {
-+              if (!tty_flag) /* no null on tty sessions */
-+              {
-+                      debug("Requesting none rekeying...");
-+                      myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
-+                      myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
-+                      kex_prop2buf(&xxx_kex->my,myproposal);
-+                      packet_request_rekeying();
-+                      fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
-+              }
-+              else
-+              {
-+                      /* requested NONE cipher when in a tty */
-+                      debug("Cannot switch to NONE cipher with tty allocated");
-+                      fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
-+              }
-+      }
-       debug("Authentication succeeded (%s).", authctxt.method->name);
- }
-diff -NupwB openssh-5.0p1/sshconnect.c openssh-5.0p1-hpn13v4-sink/sshconnect.c
---- openssh-5.0p1/sshconnect.c 2007-12-28 10:43:51.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/sshconnect.c    2008-05-07 13:54:53.000000000 -0400
-@@ -184,6 +184,31 @@ ssh_proxy_connect(const char *host, u_sh
- }
- /*
-+ * Set TCP receive buffer if requested.
-+ * Note: tuning needs to happen after the socket is
-+ * created but before the connection happens
-+ * so winscale is negotiated properly -cjr
-+ */
-+static void
-+ssh_set_socket_recvbuf(int sock)
-+{
-+      void *buf = (void *)&options.tcp_rcv_buf;
-+      int sz = sizeof(options.tcp_rcv_buf);
-+      int socksize;
-+      int socksizelen = sizeof(int);
-+
-+      debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
-+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
-+        getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
-+        debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
-+      }
-+      else
-+              error("Couldn't set socket receive buffer to %d: %.100s",
-+                  options.tcp_rcv_buf, strerror(errno));
-+}
-+
-+
-+/*
-  * Creates a (possibly privileged) socket for use as the ssh connection.
-  */
- static int
-@@ -206,12 +231,18 @@ ssh_create_socket(int privileged, struct
-                           strerror(errno));
-               else
-                       debug("Allocated local port %d.", p);
-+
-+              if (options.tcp_rcv_buf > 0)
-+                      ssh_set_socket_recvbuf(sock);           
-               return sock;
-       }
-       sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-       if (sock < 0)
-               error("socket: %.100s", strerror(errno));
-+      if (options.tcp_rcv_buf > 0)
-+              ssh_set_socket_recvbuf(sock);
-+      
-       /* Bind the socket to an alternative local IP address */
-       if (options.bind_address == NULL)
-               return sock;
-@@ -553,7 +584,7 @@ ssh_exchange_identification(int timeout_
-       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 -NupwB openssh-5.0p1/sshd.c openssh-5.0p1-hpn13v4-sink/sshd.c
---- openssh-5.0p1/sshd.c       2008-03-11 07:58:25.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/sshd.c  2008-05-07 13:54:53.000000000 -0400
-@@ -136,6 +136,9 @@ int deny_severity;
- #define REEXEC_CONFIG_PASS_FD         (STDERR_FILENO + 3)
- #define REEXEC_MIN_FREE_FD            (STDERR_FILENO + 4)
-+int myflag = 0;
-+
-+
- extern char *__progname;
- /* Server configuration options. */
-@@ -421,7 +424,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. */
-@@ -472,6 +475,9 @@ sshd_exchange_identification(int sock_in
-       }
-       debug("Client protocol version %d.%d; client software version %.100s",
-           remote_major, remote_minor, remote_version);
-+      logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
-+            get_remote_ipaddr(), get_remote_port(),
-+          remote_major, remote_minor, remote_version);
-       compat_datafellows(remote_version);
-@@ -953,6 +959,8 @@ server_listen(void)
-       int ret, listen_sock, on = 1;
-       struct addrinfo *ai;
-       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
-+      int socksize;
-+      int socksizelen = sizeof(int);
-       for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
-               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
-@@ -999,6 +1007,11 @@ server_listen(void)
-               debug("Bind to port %s on %s.", strport, ntop);
-+              getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
-+                                 &socksize, &socksizelen);
-+              debug("Server TCP RWIN socket size: %d", socksize);
-+              debug("HPN Buffer Size: %d", options.hpn_buffer_size);
-+
-               /* Bind the socket to the desired port. */
-               if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
-                       error("Bind to port %s on %s failed: %.200s.",
-@@ -2130,9 +2143,15 @@ do_ssh2_kex(void)
- {
-       Kex *kex;
-+      myflag++;
-+      debug ("MYFLAG IS %d", myflag);
-       if (options.ciphers != NULL) {
-               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
-+      } else if (options.none_enabled == 1) {
-+              debug ("WARNING: None cipher enabled");
-+              myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-+              myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
-       }
-       myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-           compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
-diff -NupwB openssh-5.0p1/sshd_config openssh-5.0p1-hpn13v4-sink/sshd_config
---- openssh-5.0p1/sshd_config  2008-02-10 06:40:12.000000000 -0500
-+++ openssh-5.0p1-hpn13v4-sink/sshd_config     2008-05-07 13:54:53.000000000 -0400
-@@ -110,6 +110,20 @@ Protocol 2
- # override default of no subsystems
- Subsystem     sftp    /usr/libexec/sftp-server
-+# the following are HPN related configuration options
-+# tcp receive buffer polling. disable in non autotuning kernels
-+#TcpRcvBufPoll yes
-+ 
-+# allow the use of the none cipher
-+#NoneEnabled no
-+
-+# disable hpn performance boosts. 
-+#HPNDisabled no
-+
-+# buffer size for hpn to non-hpn connections
-+#HPNBufferSize 2048
-+
-+
- # Example of overriding settings on a per-user basis
- #Match User anoncvs
- #     X11Forwarding no
-diff -NupwB openssh-5.0p1/version.h openssh-5.0p1-hpn13v4-sink/version.h
---- openssh-5.0p1/version.h    2008-04-03 05:53:08.000000000 -0400
-+++ openssh-5.0p1-hpn13v4-sink/version.h       2008-05-07 13:55:50.000000000 -0400
-@@ -3,4 +3,5 @@
- #define SSH_VERSION   "OpenSSH_5.0"
- #define SSH_PORTABLE  "p1"
--#define SSH_RELEASE   SSH_VERSION SSH_PORTABLE
-+#define SSH_HPN         "-hpn13v4"
-+#define SSH_RELEASE   SSH_VERSION SSH_PORTABLE SSH_HPN
diff --git a/openssh-5.2p1-hpn13v6.diff b/openssh-5.2p1-hpn13v6.diff
new file mode 100644 (file)
index 0000000..a8f179e
--- /dev/null
@@ -0,0 +1,3693 @@
+diff -NupwB openssh-5.2p1-canonical/auth2.c openssh-5.2p1-hpn13v6/auth2.c
+--- openssh-5.2p1-canonical/auth2.c    2008-11-05 00:20:46.000000000 -0500
++++ openssh-5.2p1-hpn13v6/auth2.c      2009-05-14 12:36:10.000000000 -0400
+@@ -49,6 +49,7 @@
+ #include "dispatch.h"
+ #include "pathnames.h"
+ #include "buffer.h"
++#include "canohost.h"
+ #ifdef GSSAPI
+ #include "ssh-gss.h"
+@@ -75,6 +76,9 @@ extern Authmethod method_gssapi;
+ extern Authmethod method_jpake;
+ #endif
++static int log_flag = 0;
++
++
+ Authmethod *authmethods[] = {
+       &method_none,
+       &method_pubkey,
+@@ -225,6 +229,11 @@ input_userauth_request(int type, u_int32
+       service = packet_get_string(NULL);
+       method = packet_get_string(NULL);
+       debug("userauth-request for user %s service %s method %s", user, service, method);
++      if (!log_flag) {
++              logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
++                    get_remote_ipaddr(), get_remote_port(), user);
++              log_flag = 1;
++      }
+       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+       if ((style = strchr(user, ':')) != NULL)
+diff -NupwB openssh-5.2p1-canonical/buffer.c openssh-5.2p1-hpn13v6/buffer.c
+--- openssh-5.2p1-canonical/buffer.c   2006-08-04 22:39:39.000000000 -0400
++++ openssh-5.2p1-hpn13v6/buffer.c     2009-05-14 12:36:10.000000000 -0400
+@@ -127,7 +127,7 @@ restart:
+       /* Increase the size of the buffer and retry. */
+       newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
+-      if (newlen > BUFFER_MAX_LEN)
++      if (newlen > BUFFER_MAX_LEN_HPN)
+               fatal("buffer_append_space: alloc %u not supported",
+                   newlen);
+       buffer->buf = xrealloc(buffer->buf, 1, newlen);
+diff -NupwB openssh-5.2p1-canonical/buffer.h openssh-5.2p1-hpn13v6/buffer.h
+--- openssh-5.2p1-canonical/buffer.h   2008-05-19 00:59:37.000000000 -0400
++++ openssh-5.2p1-hpn13v6/buffer.h     2009-05-14 12:36:10.000000000 -0400
+@@ -16,6 +16,9 @@
+ #ifndef BUFFER_H
+ #define BUFFER_H
++/* move the following to a more appropriate place and name */
++#define BUFFER_MAX_LEN_HPN          0x4000000  /* 64MB */
++
+ typedef struct {
+       u_char  *buf;           /* Buffer for data. */
+       u_int    alloc;         /* Number of bytes allocated for data. */
+diff -NupwB openssh-5.2p1-canonical/channels.c openssh-5.2p1-hpn13v6/channels.c
+--- openssh-5.2p1-canonical/channels.c 2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/channels.c   2009-05-14 12:36:10.000000000 -0400
+@@ -169,8 +169,14 @@ static void port_open_helper(Channel *c,
+ static int connect_next(struct channel_connect *);
+ static void channel_connect_ctx_free(struct channel_connect *);
++
++static int hpn_disabled = 0;
++static int hpn_buffer_size = 2 * 1024 * 1024;
++
+ /* -- channel core */
++
++
+ Channel *
+ channel_by_id(int id)
+ {
+@@ -308,6 +314,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;
+@@ -798,11 +805,35 @@ channel_pre_open_13(Channel *c, fd_set *
+               FD_SET(c->sock, writeset);
+ }
++int channel_tcpwinsz () {
++        u_int32_t tcpwinsz = 0;
++        socklen_t optsz = sizeof(tcpwinsz);
++      int ret = -1;
++
++      /* if we aren't on a socket return 128KB*/
++      if(!packet_connection_is_on_socket()) 
++          return(128*1024);
++      ret = getsockopt(packet_get_connection_in(),
++                       SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
++      /* return no more than 64MB */
++      if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
++          tcpwinsz = BUFFER_MAX_LEN_HPN;
++      debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
++             packet_get_connection_in());
++      return(tcpwinsz);
++}
++
+ 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 */
++      if ((!c->tcpwinsz) || (c->dynamic_window > 0))
++          c->tcpwinsz = channel_tcpwinsz();
++      
++      limit = MIN(limit, 2 * c->tcpwinsz);
++      
+       if (c->istate == CHAN_INPUT_OPEN &&
+           limit > 0 &&
+           buffer_len(&c->input) < limit &&
+@@ -1759,14 +1790,21 @@ channel_check_window(Channel *c)
+           c->local_maxpacket*3) ||
+           c->local_window < c->local_window_max/2) &&
+           c->local_consumed > 0) {
++              u_int addition = 0;
++              /* adjust max window size if we are in a dynamic environment */
++              if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
++                      /* grow the window somewhat aggressively to maintain pressure */
++                      addition = 1.5*(c->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;
+@@ -1969,11 +2007,12 @@ channel_after_select(fd_set *readset, fd
+ /* If there is data to send to the connection, enqueue some of it now. */
+-void
++int
+ channel_output_poll(void)
+ {
+       Channel *c;
+       u_int i, len;
++      int packet_length = 0;
+       for (i = 0; i < channels_alloc; i++) {
+               c = channels[i];
+@@ -2013,7 +2052,7 @@ channel_output_poll(void)
+                                       packet_start(SSH2_MSG_CHANNEL_DATA);
+                                       packet_put_int(c->remote_id);
+                                       packet_put_string(data, dlen);
+-                                      packet_send();
++                                      packet_length = packet_send();
+                                       c->remote_window -= dlen + 4;
+                                       xfree(data);
+                               }
+@@ -2043,7 +2082,7 @@ channel_output_poll(void)
+                                   SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
+                               packet_put_int(c->remote_id);
+                               packet_put_string(buffer_ptr(&c->input), len);
+-                              packet_send();
++                              packet_length = packet_send();
+                               buffer_consume(&c->input, len);
+                               c->remote_window -= len;
+                       }
+@@ -2078,12 +2117,13 @@ channel_output_poll(void)
+                       packet_put_int(c->remote_id);
+                       packet_put_int(SSH2_EXTENDED_DATA_STDERR);
+                       packet_put_string(buffer_ptr(&c->extended), len);
+-                      packet_send();
++                      packet_length = packet_send();
+                       buffer_consume(&c->extended, len);
+                       c->remote_window -= len;
+                       debug2("channel %d: sent ext data %d", c->self, len);
+               }
+       }
++      return (packet_length);
+ }
+@@ -2459,6 +2499,15 @@ channel_set_af(int af)
+       IPv4or6 = af;
+ }
++
++void 
++channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size)
++{
++              hpn_disabled = external_hpn_disabled;
++      hpn_buffer_size = external_hpn_buffer_size;
++      debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size);
++}
++
+ static int
+ channel_setup_fwd_listener(int type, const char *listen_addr,
+     u_short listen_port, int *allocated_listen_port,
+@@ -2610,9 +2659,15 @@ channel_setup_fwd_listener(int type, con
+               }
+               /* Allocate a channel number for the socket. */
++              /* explicitly test for hpn disabled option. if true use smaller window size */
++              if (hpn_disabled)
+               c = channel_new("port listener", type, sock, sock, -1,
+                   CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+                   0, "port listener", 1);
++              else
++                      c = channel_new("port listener", type, sock, sock, -1,
++                        hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
++                        0, "port listener", 1); 
+               c->path = xstrdup(host);
+               c->host_port = port_to_connect;
+               c->listening_port = listen_port;
+@@ -3151,10 +3206,17 @@ x11_create_display_inet(int x11_display_
+       *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
+       for (n = 0; n < num_socks; n++) {
+               sock = socks[n];
++              /* Is this really necassary? */
++              if (hpn_disabled) 
+               nc = channel_new("x11 listener",
+                   SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
+                   CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
+                   0, "X11 inet listener", 1);
++              else 
++                      nc = channel_new("x11 listener",
++                          SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
++                          hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
++                          0, "X11 inet listener", 1);
+               nc->single_connection = single_connection;
+               (*chanids)[n] = nc->self;
+       }
+diff -NupwB openssh-5.2p1-canonical/channels.h openssh-5.2p1-hpn13v6/channels.h
+--- openssh-5.2p1-canonical/channels.h 2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/channels.h   2009-05-14 12:36:10.000000000 -0400
+@@ -115,8 +115,10 @@ struct Channel {
+       u_int   local_window_max;
+       u_int   local_consumed;
+       u_int   local_maxpacket;
++      int     dynamic_window;
+       int     extended_usage;
+       int     single_connection;
++      u_int   tcpwinsz;       
+       char   *ctype;          /* type */
+@@ -146,9 +148,11 @@ struct Channel {
+ /* default window/packet sizes for tcp/x11-fwd-channel */
+ #define CHAN_SES_PACKET_DEFAULT       (32*1024)
+-#define CHAN_SES_WINDOW_DEFAULT       (64*CHAN_SES_PACKET_DEFAULT)
++#define CHAN_SES_WINDOW_DEFAULT       (4*CHAN_SES_PACKET_DEFAULT)
++
+ #define CHAN_TCP_PACKET_DEFAULT       (32*1024)
+-#define CHAN_TCP_WINDOW_DEFAULT       (64*CHAN_TCP_PACKET_DEFAULT)
++#define CHAN_TCP_WINDOW_DEFAULT       (4*CHAN_TCP_PACKET_DEFAULT)
++
+ #define CHAN_X11_PACKET_DEFAULT       (16*1024)
+ #define CHAN_X11_WINDOW_DEFAULT       (4*CHAN_X11_PACKET_DEFAULT)
+@@ -221,7 +225,7 @@ void        channel_input_status_confirm(int, 
+ void   channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
+ void     channel_after_select(fd_set *, fd_set *);
+-void     channel_output_poll(void);
++int      channel_output_poll(void);
+ int      channel_not_very_much_buffered_data(void);
+ void     channel_close_all(void);
+@@ -277,4 +281,7 @@ void        chan_rcvd_ieof(Channel *);
+ void   chan_write_failed(Channel *);
+ void   chan_obuf_empty(Channel *);
++/* hpn handler */
++void     channel_set_hpn(int, int);
++
+ #endif
+diff -NupwB openssh-5.2p1-canonical/cipher.c openssh-5.2p1-hpn13v6/cipher.c
+--- openssh-5.2p1-canonical/cipher.c   2009-01-28 00:38:41.000000000 -0500
++++ openssh-5.2p1-hpn13v6/cipher.c     2009-05-14 12:36:10.000000000 -0400
+@@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi
+ extern const EVP_CIPHER *evp_ssh1_3des(void);
+ extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+ extern const EVP_CIPHER *evp_aes_128_ctr(void);
++extern const EVP_CIPHER *evp_aes_ctr_mt(void);
+ extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
+ struct Cipher {
+@@ -82,9 +83,9 @@ struct Cipher {
+       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+       { "rijndael-cbc@lysator.liu.se",
+                               SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+-      { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
+-      { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
+-      { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
++      { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_ctr_mt },
++      { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_ctr_mt },
++      { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_ctr_mt },
+ #ifdef USE_CIPHER_ACSS
+       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
+ #endif
+@@ -163,7 +164,8 @@ ciphers_valid(const char *names)
+       for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
+           (p = strsep(&cp, CIPHER_SEP))) {
+               c = cipher_by_name(p);
+-              if (c == NULL || c->number != SSH_CIPHER_SSH2) {
++              if (c == NULL || (c->number != SSH_CIPHER_SSH2 && 
++c->number != SSH_CIPHER_NONE)) {
+                       debug("bad cipher %s [%s]", p, names);
+                       xfree(cipher_list);
+                       return 0;
+@@ -337,6 +339,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
+       int evplen;
+       switch (c->number) {
++      case SSH_CIPHER_NONE:
+       case SSH_CIPHER_SSH2:
+       case SSH_CIPHER_DES:
+       case SSH_CIPHER_BLOWFISH:
+@@ -371,6 +374,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
+       int evplen = 0;
+       switch (c->number) {
++      case SSH_CIPHER_NONE:
+       case SSH_CIPHER_SSH2:
+       case SSH_CIPHER_DES:
+       case SSH_CIPHER_BLOWFISH:
+diff -NupwB openssh-5.2p1-canonical/cipher-ctr-mt.c openssh-5.2p1-hpn13v6/cipher-ctr-mt.c
+--- openssh-5.2p1-canonical/cipher-ctr-mt.c    1969-12-31 19:00:00.000000000 -0500
++++ openssh-5.2p1-hpn13v6/cipher-ctr-mt.c      2009-05-14 12:36:10.000000000 -0400
+@@ -0,0 +1,473 @@
++/*
++ * OpenSSH Multi-threaded AES-CTR Cipher
++ *
++ * Author: Benjamin Bennett <ben@psc.edu>
++ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
++ *
++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
++ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include "includes.h"
++
++#include <sys/types.h>
++
++#include <stdarg.h>
++#include <string.h>
++
++#include <openssl/evp.h>
++
++#include "xmalloc.h"
++#include "log.h"
++
++/* compatibility with old or broken OpenSSL versions */
++#include "openbsd-compat/openssl-compat.h"
++
++#ifndef USE_BUILTIN_RIJNDAEL
++#include <openssl/aes.h>
++#endif
++
++#include <pthread.h>
++
++/*-------------------- TUNABLES --------------------*/
++/* Number of pregen threads to use */
++#define CIPHER_THREADS        2
++
++/* Number of keystream queues */
++#define NUMKQ         (CIPHER_THREADS + 2)
++
++/* Length of a keystream queue */
++#define KQLEN         4096
++
++/* Processor cacheline length */
++#define CACHELINE_LEN 64
++
++/* Collect thread stats and print at cancellation when in debug mode */
++/* #define CIPHER_THREAD_STATS */
++
++/* Use single-byte XOR instead of 8-byte XOR */
++/* #define CIPHER_BYTE_XOR */
++/*-------------------- END TUNABLES --------------------*/
++
++
++const EVP_CIPHER *evp_aes_ctr_mt(void);
++
++#ifdef CIPHER_THREAD_STATS
++/*
++ * Struct to collect thread stats
++ */
++struct thread_stats {
++      u_int   fills;
++      u_int   skips;
++      u_int   waits;
++      u_int   drains;
++};
++
++/*
++ * Debug print the thread stats
++ * Use with pthread_cleanup_push for displaying at thread cancellation
++ */
++static void
++thread_loop_stats(void *x)
++{
++      struct thread_stats *s = x;
++
++      debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
++                      s->fills, s->skips, s->waits);
++}
++
++ #define STATS_STRUCT(s)      struct thread_stats s
++ #define STATS_INIT(s)                { memset(&s, 0, sizeof(s)); }
++ #define STATS_FILL(s)                { s.fills++; }
++ #define STATS_SKIP(s)                { s.skips++; }
++ #define STATS_WAIT(s)                { s.waits++; }
++ #define STATS_DRAIN(s)               { s.drains++; }
++#else
++ #define STATS_STRUCT(s)
++ #define STATS_INIT(s)
++ #define STATS_FILL(s)
++ #define STATS_SKIP(s)
++ #define STATS_WAIT(s)
++ #define STATS_DRAIN(s)
++#endif
++
++/* Keystream Queue state */
++enum {
++      KQINIT,
++      KQEMPTY,
++      KQFILLING,
++      KQFULL,
++      KQDRAINING
++};
++
++/* Keystream Queue struct */
++struct kq {
++      u_char          keys[KQLEN][AES_BLOCK_SIZE];
++      u_char          ctr[AES_BLOCK_SIZE];
++      u_char          pad0[CACHELINE_LEN];
++      volatile int    qstate;
++      pthread_mutex_t lock;
++      pthread_cond_t  cond;
++      u_char          pad1[CACHELINE_LEN];
++};
++
++/* Context struct */
++struct ssh_aes_ctr_ctx
++{
++      struct kq       q[NUMKQ];
++      AES_KEY         aes_ctx;
++      STATS_STRUCT(stats);
++      u_char          aes_counter[AES_BLOCK_SIZE];
++      pthread_t       tid[CIPHER_THREADS];
++      int             state;
++      int             qidx;
++      int             ridx;
++};
++
++/* <friedl>
++ * increment counter 'ctr',
++ * the counter is of size 'len' bytes and stored in network-byte-order.
++ * (LSB at ctr[len-1], MSB at ctr[0])
++ */
++static void
++ssh_ctr_inc(u_char *ctr, u_int len)
++{
++      int i;
++
++      for (i = len - 1; i >= 0; i--)
++              if (++ctr[i])   /* continue on overflow */
++                      return;
++}
++
++/*
++ * Add num to counter 'ctr'
++ */
++static void
++ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
++{
++      int i;
++      uint16_t n;
++
++      for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
++              n = ctr[i] + (num & 0xff) + n;
++              num >>= 8;
++              ctr[i] = n & 0xff;
++              n >>= 8;
++      }
++}
++
++/*
++ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
++ */
++static void
++thread_loop_cleanup(void *x)
++{
++      pthread_mutex_unlock((pthread_mutex_t *)x);
++}
++
++/*
++ * The life of a pregen thread:
++ *    Find empty keystream queues and fill them using their counter.
++ *    When done, update counter for the next fill.
++ */
++static void *
++thread_loop(void *x)
++{
++      AES_KEY key;
++      STATS_STRUCT(stats);
++      struct ssh_aes_ctr_ctx *c = x;
++      struct kq *q;
++      int i;
++      int qidx;
++
++      /* Threads stats on cancellation */
++      STATS_INIT(stats);
++#ifdef CIPHER_THREAD_STATS
++      pthread_cleanup_push(thread_loop_stats, &stats);
++#endif
++
++      /* Thread local copy of AES key */
++      memcpy(&key, &c->aes_ctx, sizeof(key));
++
++      /*
++       * Handle the special case of startup, one thread must fill
++       * the first KQ then mark it as draining. Lock held throughout.
++       */
++      if (pthread_equal(pthread_self(), c->tid[0])) {
++              q = &c->q[0];
++              pthread_mutex_lock(&q->lock);
++              if (q->qstate == KQINIT) {
++                      for (i = 0; i < KQLEN; i++) {
++                              AES_encrypt(q->ctr, q->keys[i], &key);
++                              ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
++                      }
++                      ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
++                      q->qstate = KQDRAINING;
++                      STATS_FILL(stats);
++                      pthread_cond_broadcast(&q->cond);
++              }
++              pthread_mutex_unlock(&q->lock);
++      }
++      else 
++              STATS_SKIP(stats);
++
++      /*
++       * Normal case is to find empty queues and fill them, skipping over
++       * queues already filled by other threads and stopping to wait for
++       * a draining queue to become empty.
++       *
++       * Multiple threads may be waiting on a draining queue and awoken
++       * when empty.  The first thread to wake will mark it as filling,
++       * others will move on to fill, skip, or wait on the next queue.
++       */
++      for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
++              /* Check if I was cancelled, also checked in cond_wait */
++              pthread_testcancel();
++
++              /* Lock queue and block if its draining */
++              q = &c->q[qidx];
++              pthread_mutex_lock(&q->lock);
++              pthread_cleanup_push(thread_loop_cleanup, &q->lock);
++              while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
++                      STATS_WAIT(stats);
++                      pthread_cond_wait(&q->cond, &q->lock);
++              }
++              pthread_cleanup_pop(0);
++
++              /* If filling or full, somebody else got it, skip */
++              if (q->qstate != KQEMPTY) {
++                      pthread_mutex_unlock(&q->lock);
++                      STATS_SKIP(stats);
++                      continue;
++              }
++
++              /*
++               * Empty, let's fill it.
++               * Queue lock is relinquished while we do this so others
++               * can see that it's being filled.
++               */
++              q->qstate = KQFILLING;
++              pthread_mutex_unlock(&q->lock);
++              for (i = 0; i < KQLEN; i++) {
++                      AES_encrypt(q->ctr, q->keys[i], &key);
++                      ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
++              }
++
++              /* Re-lock, mark full and signal consumer */
++              pthread_mutex_lock(&q->lock);
++              ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
++              q->qstate = KQFULL;
++              STATS_FILL(stats);
++              pthread_cond_signal(&q->cond);
++              pthread_mutex_unlock(&q->lock);
++      }
++
++#ifdef CIPHER_THREAD_STATS
++      /* Stats */
++      pthread_cleanup_pop(1);
++#endif
++
++      return NULL;
++}
++
++static int
++ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
++    u_int len)
++{
++      struct ssh_aes_ctr_ctx *c;
++      struct kq *q, *oldq;
++      int ridx;
++      u_char *buf;
++
++      if (len == 0)
++              return (1);
++      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
++              return (0);
++
++      q = &c->q[c->qidx];
++      ridx = c->ridx;
++
++      /* src already padded to block multiple */
++      while (len > 0) {
++              buf = q->keys[ridx];
++
++#ifdef CIPHER_BYTE_XOR
++              dest[0] = src[0] ^ buf[0];
++              dest[1] = src[1] ^ buf[1];
++              dest[2] = src[2] ^ buf[2];
++              dest[3] = src[3] ^ buf[3];
++              dest[4] = src[4] ^ buf[4];
++              dest[5] = src[5] ^ buf[5];
++              dest[6] = src[6] ^ buf[6];
++              dest[7] = src[7] ^ buf[7];
++              dest[8] = src[8] ^ buf[8];
++              dest[9] = src[9] ^ buf[9];
++              dest[10] = src[10] ^ buf[10];
++              dest[11] = src[11] ^ buf[11];
++              dest[12] = src[12] ^ buf[12];
++              dest[13] = src[13] ^ buf[13];
++              dest[14] = src[14] ^ buf[14];
++              dest[15] = src[15] ^ buf[15];
++#else
++              *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
++              *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
++                                              *(uint64_t *)(buf + 8);
++#endif
++
++              dest += 16;
++              src += 16;
++              len -= 16;
++              ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
++
++              /* Increment read index, switch queues on rollover */
++              if ((ridx = (ridx + 1) % KQLEN) == 0) {
++                      oldq = q;
++
++                      /* Mark next queue draining, may need to wait */
++                      c->qidx = (c->qidx + 1) % NUMKQ;
++                      q = &c->q[c->qidx];
++                      pthread_mutex_lock(&q->lock);
++                      while (q->qstate != KQFULL) {
++                              STATS_WAIT(c->stats);
++                              pthread_cond_wait(&q->cond, &q->lock);
++                      }
++                      q->qstate = KQDRAINING;
++                      pthread_mutex_unlock(&q->lock);
++
++                      /* Mark consumed queue empty and signal producers */
++                      pthread_mutex_lock(&oldq->lock);
++                      oldq->qstate = KQEMPTY;
++                      STATS_DRAIN(c->stats);
++                      pthread_cond_broadcast(&oldq->cond);
++                      pthread_mutex_unlock(&oldq->lock);
++              }
++      }
++      c->ridx = ridx;
++      return (1);
++}
++
++#define HAVE_NONE       0
++#define HAVE_KEY        1
++#define HAVE_IV         2
++static int
++ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
++    int enc)
++{
++      struct ssh_aes_ctr_ctx *c;
++      int i;
++
++      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
++              c = xmalloc(sizeof(*c));
++
++              c->state = HAVE_NONE;
++              for (i = 0; i < NUMKQ; i++) {
++                      pthread_mutex_init(&c->q[i].lock, NULL);
++                      pthread_cond_init(&c->q[i].cond, NULL);
++              }
++
++              STATS_INIT(c->stats);
++              
++              EVP_CIPHER_CTX_set_app_data(ctx, c);
++      }
++
++      if (c->state == (HAVE_KEY | HAVE_IV)) {
++              /* Cancel pregen threads */
++              for (i = 0; i < CIPHER_THREADS; i++)
++                      pthread_cancel(c->tid[i]);
++              for (i = 0; i < CIPHER_THREADS; i++)
++                      pthread_join(c->tid[i], NULL);
++              /* Start over getting key & iv */
++              c->state = HAVE_NONE;
++      }
++
++      if (key != NULL) {
++              AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
++                  &c->aes_ctx);
++              c->state |= HAVE_KEY;
++      }
++
++      if (iv != NULL) {
++              memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
++              c->state |= HAVE_IV;
++      }
++
++      if (c->state == (HAVE_KEY | HAVE_IV)) {
++              /* Clear queues */
++              memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
++              c->q[0].qstate = KQINIT;
++              for (i = 1; i < NUMKQ; i++) {
++                      memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
++                      ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
++                      c->q[i].qstate = KQEMPTY;
++              }
++              c->qidx = 0;
++              c->ridx = 0;
++
++              /* Start threads */
++              for (i = 0; i < CIPHER_THREADS; i++) {
++                      pthread_create(&c->tid[i], NULL, thread_loop, c);
++              }
++              pthread_mutex_lock(&c->q[0].lock);
++              while (c->q[0].qstate != KQDRAINING)
++                      pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
++              pthread_mutex_unlock(&c->q[0].lock);
++              
++      }
++      return (1);
++}
++
++static int
++ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
++{
++      struct ssh_aes_ctr_ctx *c;
++      int i;
++
++      if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
++#ifdef CIPHER_THREAD_STATS
++              debug("main thread: %u drains, %u waits", c->stats.drains,
++                              c->stats.waits);
++#endif
++              /* Cancel pregen threads */
++              for (i = 0; i < CIPHER_THREADS; i++)
++                      pthread_cancel(c->tid[i]);
++              for (i = 0; i < CIPHER_THREADS; i++)
++                      pthread_join(c->tid[i], NULL);
++
++              memset(c, 0, sizeof(*c));
++              xfree(c);
++              EVP_CIPHER_CTX_set_app_data(ctx, NULL);
++      }
++      return (1);
++}
++
++/* <friedl> */
++const EVP_CIPHER *
++evp_aes_ctr_mt(void)
++{
++      static EVP_CIPHER aes_ctr;
++
++      memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
++      aes_ctr.nid = NID_undef;
++      aes_ctr.block_size = AES_BLOCK_SIZE;
++      aes_ctr.iv_len = AES_BLOCK_SIZE;
++      aes_ctr.key_len = 16;
++      aes_ctr.init = ssh_aes_ctr_init;
++      aes_ctr.cleanup = ssh_aes_ctr_cleanup;
++      aes_ctr.do_cipher = ssh_aes_ctr;
++#ifndef SSH_OLD_EVP
++      aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
++          EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
++#endif
++      return (&aes_ctr);
++}
+diff -NupwB openssh-5.2p1-canonical/clientloop.c openssh-5.2p1-hpn13v6/clientloop.c
+--- openssh-5.2p1-canonical/clientloop.c       2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/clientloop.c 2009-05-14 12:36:10.000000000 -0400
+@@ -1688,9 +1688,15 @@ client_request_x11(const char *request_t
+       sock = x11_connect_display();
+       if (sock < 0)
+               return NULL;
++      /* again is this really necessary for X11? */
++      if (options.hpn_disabled) 
+       c = channel_new("x11",
+           SSH_CHANNEL_X11_OPEN, sock, sock, -1,
+           CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
++      else 
++              c = channel_new("x11",
++                  SSH_CHANNEL_X11_OPEN, sock, sock, -1,
++                  options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
+       c->force_drain = 1;
+       return c;
+ }
+@@ -1710,9 +1716,15 @@ client_request_agent(const char *request
+       sock = ssh_get_authentication_socket();
+       if (sock < 0)
+               return NULL;
++      if (options.hpn_disabled) 
+       c = channel_new("authentication agent connection",
+           SSH_CHANNEL_OPEN, sock, sock, -1,
+-          CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
++                  CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
++                  "authentication agent connection", 1);
++       else
++      c = channel_new("authentication agent connection",
++          SSH_CHANNEL_OPEN, sock, sock, -1,
++                   options.hpn_buffer_size, options.hpn_buffer_size, 0,
+           "authentication agent connection", 1);
+       c->force_drain = 1;
+       return c;
+@@ -1740,10 +1752,18 @@ client_request_tun_fwd(int tun_mode, int
+               return -1;
+       }
++      if(options.hpn_disabled)
++      c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
++                              CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
++                              0, "tun", 1);
++      else
+       c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
+-          CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
++                              options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
++                              0, "tun", 1);
+       c->datagram = 1;
++
++
+ #if defined(SSH_TUN_FILTER)
+       if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
+               channel_register_filter(c->self, sys_tun_infilter,
+diff -NupwB openssh-5.2p1-canonical/compat.c openssh-5.2p1-hpn13v6/compat.c
+--- openssh-5.2p1-canonical/compat.c   2008-11-03 03:20:14.000000000 -0500
++++ openssh-5.2p1-hpn13v6/compat.c     2009-05-14 12:36:10.000000000 -0400
+@@ -170,6 +170,15 @@ 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;
++                                      debug("Remote is NON-HPN aware");
++                              }
++                      }
+                       return;
+               }
+       }
+diff -NupwB openssh-5.2p1-canonical/compat.h openssh-5.2p1-hpn13v6/compat.h
+--- openssh-5.2p1-canonical/compat.h   2008-11-03 03:20:14.000000000 -0500
++++ openssh-5.2p1-hpn13v6/compat.h     2009-05-14 12:36:10.000000000 -0400
+@@ -58,6 +58,7 @@
+ #define SSH_OLD_FORWARD_ADDR  0x01000000
+ #define SSH_BUG_RFWD_ADDR     0x02000000
+ #define SSH_NEW_OPENSSH               0x04000000
++#define SSH_BUG_LARGEWINDOW     0x08000000
+ void     enable_compat13(void);
+ void     enable_compat20(void);
+Common subdirectories: openssh-5.2p1-canonical/contrib and openssh-5.2p1-hpn13v6/contrib
+diff -NupwB openssh-5.2p1-canonical/HPN-README openssh-5.2p1-hpn13v6/HPN-README
+--- openssh-5.2p1-canonical/HPN-README 1969-12-31 19:00:00.000000000 -0500
++++ openssh-5.2p1-hpn13v6/HPN-README   2009-05-14 12:36:10.000000000 -0400
+@@ -0,0 +1,128 @@
++Notes:
++
++MULTI-THREADED CIPHER:
++The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
++on hosts with multiple cores to use more than one processing core during encryption. 
++Tests have show significant throughput performance increases when using MTR-AES-CTR up 
++to and including a full gigabit per second on quad core systems. It should be possible to 
++achieve full line rate on dual core systems but OS and data management overhead makes this
++more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single 
++thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal 
++performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. 
++The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
++nomenclature. 
++Use examples:         ssh -caes128-ctr you@host.com
++              scp -oCipher=aes256-ctr file you@host.com:~/file
++
++NONE CIPHER:
++To use the NONE option you must have the NoneEnabled switch set on the server and
++you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
++feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not 
++spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
++be disabled. 
++
++The performance increase will only be as good as the network and TCP stack tuning
++on the reciever side of the connection allows. As a rule of thumb a user will need 
++at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
++HPN-SSH home page describes this in greater detail. 
++
++http://www.psc.edu/networking/projects/hpn-ssh
++
++BUFFER SIZES:
++
++If HPN is disabled the receive buffer size will be set to the 
++OpenSSH default of 64K.
++
++If an HPN system connects to a nonHPN system the receive buffer will
++be set to the HPNBufferSize value. The default is 2MB but user adjustable.
++
++If an HPN to HPN connection is established a number of different things might
++happen based on the user options and conditions. 
++
++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set 
++HPN Buffer Size = up to 64MB 
++This is the default state. The HPN buffer size will grow to a maximum of 64MB 
++as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is 
++geared towards 10GigE transcontinental connections. 
++
++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
++HPN Buffer Size = TCP receive buffer value. 
++Users on non-autotuning systesm should disable TCPRcvBufPoll in the 
++ssh_cofig and sshd_config
++
++Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
++HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. 
++This would be the system defined TCP receive buffer (RWIN).
++
++Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
++HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
++Generally there is no need to set both.
++
++Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
++HPN Buffer Size = grows to HPNBufferSize
++The buffer will grow up to the maximum size specified here. 
++
++Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
++HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
++Generally there is no need to set both of these, especially on autotuning 
++systems. However, if the users wishes to override the autotuning this would be 
++one way to do it.
++
++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
++HPN Buffer Size = TCPRcvBuf. 
++This will override autotuning and set the TCP recieve buffer to the user defined 
++value.
++
++
++HPN Specific Configuration options
++
++TcpRcvBuf=[int]KB client
++      set the TCP socket receive buffer to n Kilobytes. It can be set up to the 
++maximum socket size allowed by the system. This is useful in situations where 
++the tcp receive window is set low but the maximum buffer size is set 
++higher (as is typical). This works on a per TCP connection basis. You can also 
++use this to artifically limit the transfer rate of the connection. In these 
++cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. 
++Default is the current system wide tcp receive buffer size.
++
++TcpRcvBufPoll=[yes/no] client/server
++      enable of disable the polling of the tcp receive buffer through the life 
++of the connection. You would want to make sure that this option is enabled 
++for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) 
++default is yes.
++
++NoneEnabled=[yes/no] client/server
++      enable or disable the use of the None cipher. Care must always be used 
++when enabling this as it will allow users to send data in the clear. However, 
++it is important to note that authentication information remains encrypted 
++even if this option is enabled. Set to no by default.
++
++NoneSwitch=[yes/no] client
++     Switch the encryption cipher being used to the None cipher after
++authentication takes place. NoneEnabled must be enabled on both the client
++and server side of the connection. When the connection switches to the NONE
++cipher a warning is sent to STDERR. The connection attempt will fail with an
++error if a client requests a NoneSwitch from the server that does not explicitly
++have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
++interactive (shell) sessions and it will fail silently. Set to no by default.
++
++HPNDisabled=[yes/no] client/server
++     In some situations, such as transfers on a local area network, the impact 
++of the HPN code produces a net decrease in performance. In these cases it is 
++helpful to disable the HPN functionality. By default HPNDisabled is set to no. 
++
++HPNBufferSize=[int]KB client/server
++     This is the default buffer size the HPN functionality uses when interacting
++with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
++option as applied to the internal SSH flow control. This value can range from 
++1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
++problems depending on the length of the network path. The default size of this buffer
++is 2MB.
++
++
++Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
++         The majority of the actual coding for versions up to HPN12v1 was performed
++         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was 
++       implemented by Ben Bennet (ben@psc.edu). This work was financed, in part,
++         by Cisco System, Inc., the National Library of Medicine, 
++       and the National Science Foundation. 
+diff -NupwB openssh-5.2p1-canonical/kex.c openssh-5.2p1-hpn13v6/kex.c
+--- openssh-5.2p1-canonical/kex.c      2008-11-03 03:19:12.000000000 -0500
++++ openssh-5.2p1-hpn13v6/kex.c        2009-05-14 12:36:10.000000000 -0400
+@@ -48,6 +48,7 @@
+ #include "match.h"
+ #include "dispatch.h"
+ #include "monitor.h"
++#include "canohost.h"
+ #define KEX_COOKIE_LEN        16
+@@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
+ static void kex_choose_conf(Kex *);
+ /* put algorithm proposal into buffer */
+-static void
++/* used in sshconnect.c as well as kex.c */
++void
+ kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
+ {
+       u_int i;
+@@ -376,6 +378,13 @@ kex_choose_conf(Kex *kex)
+       int nenc, nmac, ncomp;
+       u_int mode, ctos, need;
+       int first_kex_follows, type;
++      int log_flag = 0;
++
++      int auth_flag;
++
++      auth_flag = packet_authentication_state();
++
++      debug ("AUTH STATE IS %d", auth_flag);
+       my   = kex_buf2prop(&kex->my, NULL);
+       peer = kex_buf2prop(&kex->peer, &first_kex_follows);
+@@ -400,11 +409,34 @@ kex_choose_conf(Kex *kex)
+               choose_enc (&newkeys->enc,  cprop[nenc],  sprop[nenc]);
+               choose_mac (&newkeys->mac,  cprop[nmac],  sprop[nmac]);
+               choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
++              debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
++              if (strcmp(newkeys->enc.name, "none") == 0) {
++                              debug("Requesting NONE. Authflag is %d", auth_flag);                    
++                      if (auth_flag == 1) {
++                              debug("None requested post authentication.");
++                      } else {
++                              fatal("Pre-authentication none cipher requests are not allowed.");
++                      }
++              } 
+               debug("kex: %s %s %s %s",
+                   ctos ? "client->server" : "server->client",
+                   newkeys->enc.name,
+                   newkeys->mac.name,
+                   newkeys->comp.name);
++              /* client starts withctos = 0 && log flag = 0 and no log*/
++              /* 2nd client pass ctos=1 and flag = 1 so no log*/
++              /* server starts with ctos =1 && log_flag = 0 so log */
++              /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
++              /* -cjr*/
++              if (ctos && !log_flag) {
++                      logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
++                            get_remote_ipaddr(),
++                            get_remote_port(),
++                            newkeys->enc.name,
++                            newkeys->mac.name,
++                            newkeys->comp.name);
++              }
++              log_flag = 1;
+       }
+       choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
+       choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
+diff -NupwB openssh-5.2p1-canonical/kex.h openssh-5.2p1-hpn13v6/kex.h
+--- openssh-5.2p1-canonical/kex.h      2007-06-11 00:01:42.000000000 -0400
++++ openssh-5.2p1-hpn13v6/kex.h        2009-05-14 12:36:10.000000000 -0400
+@@ -127,6 +127,8 @@ struct Kex {
+       void    (*kex[KEX_MAX])(Kex *);
+ };
++void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
++
+ Kex   *kex_setup(char *[PROPOSAL_MAX]);
+ void   kex_finish(Kex *);
+diff -NupwB openssh-5.2p1-canonical/Makefile.in openssh-5.2p1-hpn13v6/Makefile.in
+--- openssh-5.2p1-canonical/Makefile.in        2008-11-05 00:20:46.000000000 -0500
++++ openssh-5.2p1-hpn13v6/Makefile.in  2009-05-14 12:36:10.000000000 -0400
+@@ -43,7 +43,7 @@ CC=@CC@
+ LD=@LD@
+ CFLAGS=@CFLAGS@
+ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
+-LIBS=@LIBS@
++LIBS=@LIBS@ -lpthread
+ SSHDLIBS=@SSHDLIBS@
+ LIBEDIT=@LIBEDIT@
+ AR=@AR@
+@@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
+ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+       canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
+-      cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
++      cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
+       compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
+       log.o match.o md-sha256.o moduli.o nchan.o packet.o \
+       readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
+diff -NupwB openssh-5.2p1-canonical/myproposal.h openssh-5.2p1-hpn13v6/myproposal.h
+--- openssh-5.2p1-canonical/myproposal.h       2009-01-28 00:33:31.000000000 -0500
++++ openssh-5.2p1-hpn13v6/myproposal.h 2009-05-14 12:36:10.000000000 -0400
+@@ -47,6 +47,8 @@
+       "arcfour256,arcfour128," \
+       "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
+       "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
++#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
++      ",none"
+ #define       KEX_DEFAULT_MAC \
+       "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
+       "hmac-ripemd160@openssh.com," \
+Common subdirectories: openssh-5.2p1-canonical/openbsd-compat and openssh-5.2p1-hpn13v6/openbsd-compat
+diff -NupwB openssh-5.2p1-canonical/packet.c openssh-5.2p1-hpn13v6/packet.c
+--- openssh-5.2p1-canonical/packet.c   2009-02-14 00:35:01.000000000 -0500
++++ openssh-5.2p1-hpn13v6/packet.c     2009-05-14 12:36:10.000000000 -0400
+@@ -775,7 +775,7 @@ packet_enable_delayed_compress(void)
+ /*
+  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
+  */
+-static void
++static int
+ packet_send2_wrapped(void)
+ {
+       u_char type, *cp, *macbuf = NULL;
+@@ -888,11 +888,13 @@ packet_send2_wrapped(void)
+               set_newkeys(MODE_OUT);
+       else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
+               packet_enable_delayed_compress();
++      return(packet_length);
+ }
+-static void
++static int
+ packet_send2(void)
+ {
++        static int packet_length = 0;
+       static int rekeying = 0;
+       struct packet *p;
+       u_char type, *cp;
+@@ -910,7 +912,7 @@ packet_send2(void)
+                       memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
+                       buffer_init(&outgoing_packet);
+                       TAILQ_INSERT_TAIL(&outgoing, p, next);
+-                      return;
++                      return(sizeof(Buffer));
+               }
+       }
+@@ -918,7 +920,7 @@ packet_send2(void)
+       if (type == SSH2_MSG_KEXINIT)
+               rekeying = 1;
+-      packet_send2_wrapped();
++      packet_length = packet_send2_wrapped();
+       /* after a NEWKEYS message we can send the complete queue */
+       if (type == SSH2_MSG_NEWKEYS) {
+@@ -931,19 +933,22 @@ packet_send2(void)
+                           sizeof(Buffer));
+                       TAILQ_REMOVE(&outgoing, p, next);
+                       xfree(p);
+-                      packet_send2_wrapped();
++                      packet_length += packet_send2_wrapped();
+               }
+       }
++      return(packet_length);
+ }
+-void
++int
+ packet_send(void)
+ {
++  int packet_len = 0;
+       if (compat20)
+-              packet_send2();
++              packet_len = packet_send2();
+       else
+               packet_send1();
+       DBG(debug("packet_send done"));
++      return(packet_len);
+ }
+ /*
+@@ -1544,23 +1549,25 @@ packet_disconnect(const char *fmt,...)
+ /* Checks if there is any buffered output, and tries to write some of the output. */
+-void
++int
+ packet_write_poll(void)
+ {
+-      int len = buffer_len(&output);
++      int len = 0;
++      len = buffer_len(&output);
+       if (len > 0) {
+               len = write(connection_out, buffer_ptr(&output), len);
+               if (len == -1) {
+                       if (errno == EINTR || errno == EAGAIN ||
+                           errno == EWOULDBLOCK)
+-                              return;
++                              return (0);
+                       fatal("Write failed: %.100s", strerror(errno));
+               }
+               if (len == 0)
+                       fatal("Write connection closed");
+               buffer_consume(&output, len);
+       }
++      return(len);
+ }
+@@ -1569,16 +1576,17 @@ packet_write_poll(void)
+  * written.
+  */
+-void
++int
+ packet_write_wait(void)
+ {
+       fd_set *setp;
+       int ret, ms_remain;
+       struct timeval start, timeout, *timeoutp = NULL;
++      u_int bytes_sent = 0;
+       setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
+           sizeof(fd_mask));
+-      packet_write_poll();
++      bytes_sent += packet_write_poll();
+       while (packet_have_data_to_write()) {
+               memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
+                   sizeof(fd_mask));
+@@ -1612,7 +1620,7 @@ packet_write_wait(void)
+                           "waiting to write", get_remote_ipaddr());
+                       cleanup_exit(255);
+               }
+-              packet_write_poll();
++              bytes_sent += packet_write_poll();
+       }
+       xfree(setp);
+ }
+@@ -1736,12 +1744,24 @@ packet_send_ignore(int nbytes)
+       }
+ }
++int rekey_requested = 0;
++void
++packet_request_rekeying(void)
++{
++      rekey_requested = 1;
++}
++
+ #define MAX_PACKETS   (1U<<31)
+ int
+ packet_need_rekeying(void)
+ {
+       if (datafellows & SSH_BUG_NOREKEY)
+               return 0;
++      if (rekey_requested == 1)
++      {
++              rekey_requested = 0;
++              return 1;
++      }
+       return
+           (p_send.packets > MAX_PACKETS) ||
+           (p_read.packets > MAX_PACKETS) ||
+@@ -1766,3 +1786,9 @@ packet_set_authenticated(void)
+ {
+       after_authentication = 1;
+ }
++
++int
++packet_authentication_state(void)
++{
++      return(after_authentication);
++}
+diff -NupwB openssh-5.2p1-canonical/packet.h openssh-5.2p1-hpn13v6/packet.h
+--- openssh-5.2p1-canonical/packet.h   2008-07-11 03:36:48.000000000 -0400
++++ openssh-5.2p1-hpn13v6/packet.h     2009-05-14 12:36:10.000000000 -0400
+@@ -20,6 +20,9 @@
+ #include <openssl/bn.h>
++void
++packet_request_rekeying(void);
++
+ void     packet_set_connection(int, int);
+ void     packet_set_timeout(int, int);
+ void     packet_set_nonblocking(void);
+@@ -35,6 +38,7 @@ void     packet_set_interactive(int);
+ int      packet_is_interactive(void);
+ void     packet_set_server(void);
+ void     packet_set_authenticated(void);
++int    packet_authentication_state(void);
+ void     packet_start(u_char);
+ void     packet_put_char(int ch);
+@@ -44,7 +48,7 @@ void     packet_put_bignum2(BIGNUM * val
+ void     packet_put_string(const void *buf, u_int len);
+ void     packet_put_cstring(const char *str);
+ void     packet_put_raw(const void *buf, u_int len);
+-void     packet_send(void);
++int      packet_send(void);
+ int      packet_read(void);
+ void     packet_read_expect(int type);
+@@ -73,8 +77,8 @@ void  packet_set_state(int, u_int32_t, u
+ int    packet_get_ssh1_cipher(void);
+ void   packet_set_iv(int, u_char *);
+-void     packet_write_poll(void);
+-void     packet_write_wait(void);
++int      packet_write_poll(void);
++int      packet_write_wait(void);
+ int      packet_have_data_to_write(void);
+ int      packet_not_very_much_data_to_write(void);
+diff -NupwB openssh-5.2p1-canonical/progressmeter.c openssh-5.2p1-hpn13v6/progressmeter.c
+--- openssh-5.2p1-canonical/progressmeter.c    2006-08-04 22:39:40.000000000 -0400
++++ openssh-5.2p1-hpn13v6/progressmeter.c      2009-05-14 12:36:10.000000000 -0400
+@@ -68,6 +68,8 @@ static time_t last_update;   /* last progr
+ static char *file;            /* name of the file being transferred */
+ static off_t end_pos;         /* ending position of transfer */
+ static off_t cur_pos;         /* transfer position as of last refresh */
++static off_t last_pos;
++static off_t max_delta_pos = 0;
+ static volatile off_t *counter;       /* progress counter */
+ static long stalled;          /* how long we have been stalled */
+ static int bytes_per_second;  /* current speed in bytes per second */
+@@ -128,12 +130,17 @@ refresh_progress_meter(void)
+       int hours, minutes, seconds;
+       int i, len;
+       int file_len;
++      off_t delta_pos;
+       transferred = *counter - cur_pos;
+       cur_pos = *counter;
+       now = time(NULL);
+       bytes_left = end_pos - cur_pos;
++      delta_pos = cur_pos - last_pos;
++      if (delta_pos > max_delta_pos) 
++              max_delta_pos = delta_pos;
++
+       if (bytes_left > 0)
+               elapsed = now - last_update;
+       else {
+@@ -158,7 +165,7 @@ refresh_progress_meter(void)
+       /* filename */
+       buf[0] = '\0';
+-      file_len = win_size - 35;
++      file_len = win_size - 45;
+       if (file_len > 0) {
+               len = snprintf(buf, file_len + 1, "\r%s", file);
+               if (len < 0)
+@@ -175,7 +182,8 @@ refresh_progress_meter(void)
+               percent = ((float)cur_pos / end_pos) * 100;
+       else
+               percent = 100;
+-      snprintf(buf + strlen(buf), win_size - strlen(buf),
++
++      snprintf(buf + strlen(buf), win_size - strlen(buf-8),
+           " %3d%% ", percent);
+       /* amount transferred */
+@@ -188,6 +196,15 @@ refresh_progress_meter(void)
+           (off_t)bytes_per_second);
+       strlcat(buf, "/s ", win_size);
++      /* instantaneous rate */
++      if (bytes_left > 0)
++              format_rate(buf + strlen(buf), win_size - strlen(buf),
++                          delta_pos);
++      else
++              format_rate(buf + strlen(buf), win_size - strlen(buf),
++                          max_delta_pos);
++      strlcat(buf, "/s ", win_size);
++
+       /* ETA */
+       if (!transferred)
+               stalled += elapsed;
+@@ -224,6 +241,7 @@ refresh_progress_meter(void)
+       atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
+       last_update = now;
++      last_pos = cur_pos;
+ }
+ /*ARGSUSED*/
+diff -NupwB openssh-5.2p1-canonical/readconf.c openssh-5.2p1-hpn13v6/readconf.c
+--- openssh-5.2p1-canonical/readconf.c 2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/readconf.c   2009-05-14 12:36:10.000000000 -0400
+@@ -131,6 +131,8 @@ typedef enum {
+       oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+       oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+       oVisualHostKey, oZeroKnowledgePasswordAuthentication,
++      oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
++      oHPNBufferSize,
+       oDeprecated, oUnsupported
+ } OpCodes;
+@@ -234,6 +236,12 @@ static struct {
+ #else
+       { "zeroknowledgepasswordauthentication", oUnsupported },
+ #endif
++      { "noneenabled", oNoneEnabled },
++      { "tcprcvbufpoll", oTcpRcvBufPoll },
++      { "tcprcvbuf", oTcpRcvBuf },
++      { "noneswitch", oNoneSwitch },
++      { "hpndisabled", oHPNDisabled },
++      { "hpnbuffersize", oHPNBufferSize },
+       { NULL, oBadOption }
+ };
+@@ -465,6 +473,37 @@ parse_flag:
+               intptr = &options->check_host_ip;
+               goto parse_flag;
++      case oNoneEnabled:
++              intptr = &options->none_enabled;
++              goto parse_flag;
++ 
++      /* we check to see if the command comes from the */
++      /* command line or not. If it does then enable it */
++      /* otherwise fail. NONE should never be a default configuration */
++      case oNoneSwitch:
++              if(strcmp(filename,"command-line")==0)
++              {               
++                  intptr = &options->none_switch;
++                  goto parse_flag;
++              } else {
++                  error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
++                  error("Continuing...");
++                  debug("NoneSwitch directive found in %.200s.", filename);
++                  return 0;
++              }
++
++      case oHPNDisabled:
++              intptr = &options->hpn_disabled;
++              goto parse_flag;
++
++      case oHPNBufferSize:
++              intptr = &options->hpn_buffer_size;
++              goto parse_int;
++
++      case oTcpRcvBufPoll:
++              intptr = &options->tcp_rcv_buf_poll;
++              goto parse_flag;
++
+       case oVerifyHostKeyDNS:
+               intptr = &options->verify_host_key_dns;
+               goto parse_yesnoask;
+@@ -643,6 +682,10 @@ parse_int:
+               intptr = &options->connection_attempts;
+               goto parse_int;
++      case oTcpRcvBuf:
++              intptr = &options->tcp_rcv_buf;
++              goto parse_int;
++
+       case oCipher:
+               intptr = &options->cipher;
+               arg = strdelim(&s);
+@@ -1065,6 +1108,12 @@ initialize_options(Options * options)
+       options->permit_local_command = -1;
+       options->visual_host_key = -1;
+       options->zero_knowledge_password_authentication = -1;
++      options->none_switch = -1;
++      options->none_enabled = -1;
++      options->hpn_disabled = -1;
++      options->hpn_buffer_size = -1;
++      options->tcp_rcv_buf_poll = -1;
++      options->tcp_rcv_buf = -1;
+ }
+ /*
+@@ -1187,6 +1236,29 @@ fill_default_options(Options * options)
+               options->server_alive_interval = 0;
+       if (options->server_alive_count_max == -1)
+               options->server_alive_count_max = 3;
++      if (options->none_switch == -1)
++              options->none_switch = 0;
++      if (options->hpn_disabled == -1)
++              options->hpn_disabled = 0;
++      if (options->hpn_buffer_size > -1)
++      {
++        /* if a user tries to set the size to 0 set it to 1KB */
++              if (options->hpn_buffer_size == 0)
++              options->hpn_buffer_size = 1024;
++              /*limit the buffer to 64MB*/
++              if (options->hpn_buffer_size > 65536)
++              {
++                      options->hpn_buffer_size = 65536*1024;
++                      debug("User requested buffer larger than 64MB. Request reverted to 64MB");
++              }
++              debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
++      }
++      if (options->tcp_rcv_buf == 0)
++              options->tcp_rcv_buf = 1;
++      if (options->tcp_rcv_buf > -1) 
++              options->tcp_rcv_buf *=1024;
++      if (options->tcp_rcv_buf_poll == -1)
++              options->tcp_rcv_buf_poll = 1;
+       if (options->control_master == -1)
+               options->control_master = 0;
+       if (options->hash_known_hosts == -1)
+diff -NupwB openssh-5.2p1-canonical/readconf.c.orig openssh-5.2p1-hpn13v6/readconf.c.orig
+--- openssh-5.2p1-canonical/readconf.c.orig    1969-12-31 19:00:00.000000000 -0500
++++ openssh-5.2p1-hpn13v6/readconf.c.orig      2009-02-14 00:28:21.000000000 -0500
+@@ -0,0 +1,1310 @@
++/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
++/*
++ * Author: Tatu Ylonen <ylo@cs.hut.fi>
++ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
++ *                    All rights reserved
++ * Functions for reading the configuration files.
++ *
++ * As far as I am concerned, the code I have written for this software
++ * can be used freely for any purpose.  Any derived versions of this
++ * software must be clearly marked as such, and if the derived work is
++ * incompatible with the protocol description in the RFC file, it must be
++ * called by a name other than "ssh" or "Secure Shell".
++ */
++
++#include "includes.h"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/socket.h>
++
++#include <netinet/in.h>
++
++#include <ctype.h>
++#include <errno.h>
++#include <netdb.h>
++#include <signal.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "xmalloc.h"
++#include "ssh.h"
++#include "compat.h"
++#include "cipher.h"
++#include "pathnames.h"
++#include "log.h"
++#include "key.h"
++#include "readconf.h"
++#include "match.h"
++#include "misc.h"
++#include "buffer.h"
++#include "kex.h"
++#include "mac.h"
++
++/* Format of the configuration file:
++
++   # Configuration data is parsed as follows:
++   #  1. command line options
++   #  2. user-specific file
++   #  3. system-wide file
++   # Any configuration value is only changed the first time it is set.
++   # Thus, host-specific definitions should be at the beginning of the
++   # configuration file, and defaults at the end.
++
++   # Host-specific declarations.  These may override anything above.  A single
++   # host may match multiple declarations; these are processed in the order
++   # that they are given in.
++
++   Host *.ngs.fi ngs.fi
++     User foo
++
++   Host fake.com
++     HostName another.host.name.real.org
++     User blaah
++     Port 34289
++     ForwardX11 no
++     ForwardAgent no
++
++   Host books.com
++     RemoteForward 9999 shadows.cs.hut.fi:9999
++     Cipher 3des
++
++   Host fascist.blob.com
++     Port 23123
++     User tylonen
++     PasswordAuthentication no
++
++   Host puukko.hut.fi
++     User t35124p
++     ProxyCommand ssh-proxy %h %p
++
++   Host *.fr
++     PublicKeyAuthentication no
++
++   Host *.su
++     Cipher none
++     PasswordAuthentication no
++
++   Host vpn.fake.com
++     Tunnel yes
++     TunnelDevice 3
++
++   # Defaults for various options
++   Host *
++     ForwardAgent no
++     ForwardX11 no
++     PasswordAuthentication yes
++     RSAAuthentication yes
++     RhostsRSAAuthentication yes
++     StrictHostKeyChecking yes
++     TcpKeepAlive no
++     IdentityFile ~/.ssh/identity
++     Port 22
++     EscapeChar ~
++
++*/
++
++/* Keyword tokens. */
++
++typedef enum {
++      oBadOption,
++      oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
++      oExitOnForwardFailure,
++      oPasswordAuthentication, oRSAAuthentication,
++      oChallengeResponseAuthentication, oXAuthLocation,
++      oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
++      oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
++      oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
++      oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
++      oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
++      oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
++      oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
++      oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
++      oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
++      oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
++      oClearAllForwardings, oNoHostAuthenticationForLocalhost,
++      oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
++      oAddressFamily, oGssAuthentication, oGssDelegateCreds,
++      oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
++      oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
++      oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
++      oVisualHostKey, oZeroKnowledgePasswordAuthentication,
++      oDeprecated, oUnsupported
++} OpCodes;
++
++/* Textual representations of the tokens. */
++
++static struct {
++      const char *name;
++      OpCodes opcode;
++} keywords[] = {
++      { "forwardagent", oForwardAgent },
++      { "forwardx11", oForwardX11 },
++      { "forwardx11trusted", oForwardX11Trusted },
++      { "exitonforwardfailure", oExitOnForwardFailure },
++      { "xauthlocation", oXAuthLocation },
++      { "gatewayports", oGatewayPorts },
++      { "useprivilegedport", oUsePrivilegedPort },
++      { "rhostsauthentication", oDeprecated },
++      { "passwordauthentication", oPasswordAuthentication },
++      { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
++      { "kbdinteractivedevices", oKbdInteractiveDevices },
++      { "rsaauthentication", oRSAAuthentication },
++      { "pubkeyauthentication", oPubkeyAuthentication },
++      { "dsaauthentication", oPubkeyAuthentication },             /* alias */
++      { "rhostsrsaauthentication", oRhostsRSAAuthentication },
++      { "hostbasedauthentication", oHostbasedAuthentication },
++      { "challengeresponseauthentication", oChallengeResponseAuthentication },
++      { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
++      { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
++      { "kerberosauthentication", oUnsupported },
++      { "kerberostgtpassing", oUnsupported },
++      { "afstokenpassing", oUnsupported },
++#if defined(GSSAPI)
++      { "gssapiauthentication", oGssAuthentication },
++      { "gssapidelegatecredentials", oGssDelegateCreds },
++#else
++      { "gssapiauthentication", oUnsupported },
++      { "gssapidelegatecredentials", oUnsupported },
++#endif
++      { "fallbacktorsh", oDeprecated },
++      { "usersh", oDeprecated },
++      { "identityfile", oIdentityFile },
++      { "identityfile2", oIdentityFile },                     /* obsolete */
++      { "identitiesonly", oIdentitiesOnly },
++      { "hostname", oHostName },
++      { "hostkeyalias", oHostKeyAlias },
++      { "proxycommand", oProxyCommand },
++      { "port", oPort },
++      { "cipher", oCipher },
++      { "ciphers", oCiphers },
++      { "macs", oMacs },
++      { "protocol", oProtocol },
++      { "remoteforward", oRemoteForward },
++      { "localforward", oLocalForward },
++      { "user", oUser },
++      { "host", oHost },
++      { "escapechar", oEscapeChar },
++      { "globalknownhostsfile", oGlobalKnownHostsFile },
++      { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
++      { "userknownhostsfile", oUserKnownHostsFile },
++      { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
++      { "connectionattempts", oConnectionAttempts },
++      { "batchmode", oBatchMode },
++      { "checkhostip", oCheckHostIP },
++      { "stricthostkeychecking", oStrictHostKeyChecking },
++      { "compression", oCompression },
++      { "compressionlevel", oCompressionLevel },
++      { "tcpkeepalive", oTCPKeepAlive },
++      { "keepalive", oTCPKeepAlive },                         /* obsolete */
++      { "numberofpasswordprompts", oNumberOfPasswordPrompts },
++      { "loglevel", oLogLevel },
++      { "dynamicforward", oDynamicForward },
++      { "preferredauthentications", oPreferredAuthentications },
++      { "hostkeyalgorithms", oHostKeyAlgorithms },
++      { "bindaddress", oBindAddress },
++#ifdef SMARTCARD
++      { "smartcarddevice", oSmartcardDevice },
++#else
++      { "smartcarddevice", oUnsupported },
++#endif
++      { "clearallforwardings", oClearAllForwardings },
++      { "enablesshkeysign", oEnableSSHKeysign },
++      { "verifyhostkeydns", oVerifyHostKeyDNS },
++      { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
++      { "rekeylimit", oRekeyLimit },
++      { "connecttimeout", oConnectTimeout },
++      { "addressfamily", oAddressFamily },
++      { "serveraliveinterval", oServerAliveInterval },
++      { "serveralivecountmax", oServerAliveCountMax },
++      { "sendenv", oSendEnv },
++      { "controlpath", oControlPath },
++      { "controlmaster", oControlMaster },
++      { "hashknownhosts", oHashKnownHosts },
++      { "tunnel", oTunnel },
++      { "tunneldevice", oTunnelDevice },
++      { "localcommand", oLocalCommand },
++      { "permitlocalcommand", oPermitLocalCommand },
++      { "visualhostkey", oVisualHostKey },
++#ifdef JPAKE
++      { "zeroknowledgepasswordauthentication",
++          oZeroKnowledgePasswordAuthentication },
++#else
++      { "zeroknowledgepasswordauthentication", oUnsupported },
++#endif
++
++      { NULL, oBadOption }
++};
++
++/*
++ * Adds a local TCP/IP port forward to options.  Never returns if there is an
++ * error.
++ */
++
++void
++add_local_forward(Options *options, const Forward *newfwd)
++{
++      Forward *fwd;
++#ifndef NO_IPPORT_RESERVED_CONCEPT
++      extern uid_t original_real_uid;
++      if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
++              fatal("Privileged ports can only be forwarded by root.");
++#endif
++      if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
++              fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
++      fwd = &options->local_forwards[options->num_local_forwards++];
++
++      fwd->listen_host = newfwd->listen_host;
++      fwd->listen_port = newfwd->listen_port;
++      fwd->connect_host = newfwd->connect_host;
++      fwd->connect_port = newfwd->connect_port;
++}
++
++/*
++ * Adds a remote TCP/IP port forward to options.  Never returns if there is
++ * an error.
++ */
++
++void
++add_remote_forward(Options *options, const Forward *newfwd)
++{
++      Forward *fwd;
++      if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
++              fatal("Too many remote forwards (max %d).",
++                  SSH_MAX_FORWARDS_PER_DIRECTION);
++      fwd = &options->remote_forwards[options->num_remote_forwards++];
++
++      fwd->listen_host = newfwd->listen_host;
++      fwd->listen_port = newfwd->listen_port;
++      fwd->connect_host = newfwd->connect_host;
++      fwd->connect_port = newfwd->connect_port;
++}
++
++static void
++clear_forwardings(Options *options)
++{
++      int i;
++
++      for (i = 0; i < options->num_local_forwards; i++) {
++              if (options->local_forwards[i].listen_host != NULL)
++                      xfree(options->local_forwards[i].listen_host);
++              xfree(options->local_forwards[i].connect_host);
++      }
++      options->num_local_forwards = 0;
++      for (i = 0; i < options->num_remote_forwards; i++) {
++              if (options->remote_forwards[i].listen_host != NULL)
++                      xfree(options->remote_forwards[i].listen_host);
++              xfree(options->remote_forwards[i].connect_host);
++      }
++      options->num_remote_forwards = 0;
++      options->tun_open = SSH_TUNMODE_NO;
++}
++
++/*
++ * Returns the number of the token pointed to by cp or oBadOption.
++ */
++
++static OpCodes
++parse_token(const char *cp, const char *filename, int linenum)
++{
++      u_int i;
++
++      for (i = 0; keywords[i].name; i++)
++              if (strcasecmp(cp, keywords[i].name) == 0)
++                      return keywords[i].opcode;
++
++      error("%s: line %d: Bad configuration option: %s",
++          filename, linenum, cp);
++      return oBadOption;
++}
++
++/*
++ * Processes a single option line as used in the configuration files. This
++ * only sets those values that have not already been set.
++ */
++#define WHITESPACE " \t\r\n"
++
++int
++process_config_line(Options *options, const char *host,
++                  char *line, const char *filename, int linenum,
++                  int *activep)
++{
++      char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
++      int opcode, *intptr, value, value2, scale;
++      LogLevel *log_level_ptr;
++      long long orig, val64;
++      size_t len;
++      Forward fwd;
++
++      /* Strip trailing whitespace */
++      for (len = strlen(line) - 1; len > 0; len--) {
++              if (strchr(WHITESPACE, line[len]) == NULL)
++                      break;
++              line[len] = '\0';
++      }
++
++      s = line;
++      /* Get the keyword. (Each line is supposed to begin with a keyword). */
++      if ((keyword = strdelim(&s)) == NULL)
++              return 0;
++      /* Ignore leading whitespace. */
++      if (*keyword == '\0')
++              keyword = strdelim(&s);
++      if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
++              return 0;
++
++      opcode = parse_token(keyword, filename, linenum);
++
++      switch (opcode) {
++      case oBadOption:
++              /* don't panic, but count bad options */
++              return -1;
++              /* NOTREACHED */
++      case oConnectTimeout:
++              intptr = &options->connection_timeout;
++parse_time:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%s line %d: missing time value.",
++                          filename, linenum);
++              if ((value = convtime(arg)) == -1)
++                      fatal("%s line %d: invalid time value.",
++                          filename, linenum);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oForwardAgent:
++              intptr = &options->forward_agent;
++parse_flag:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
++              value = 0;      /* To avoid compiler warning... */
++              if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++                      value = 1;
++              else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++                      value = 0;
++              else
++                      fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oForwardX11:
++              intptr = &options->forward_x11;
++              goto parse_flag;
++
++      case oForwardX11Trusted:
++              intptr = &options->forward_x11_trusted;
++              goto parse_flag;
++
++      case oGatewayPorts:
++              intptr = &options->gateway_ports;
++              goto parse_flag;
++
++      case oExitOnForwardFailure:
++              intptr = &options->exit_on_forward_failure;
++              goto parse_flag;
++
++      case oUsePrivilegedPort:
++              intptr = &options->use_privileged_port;
++              goto parse_flag;
++
++      case oPasswordAuthentication:
++              intptr = &options->password_authentication;
++              goto parse_flag;
++
++      case oZeroKnowledgePasswordAuthentication:
++              intptr = &options->zero_knowledge_password_authentication;
++              goto parse_flag;
++
++      case oKbdInteractiveAuthentication:
++              intptr = &options->kbd_interactive_authentication;
++              goto parse_flag;
++
++      case oKbdInteractiveDevices:
++              charptr = &options->kbd_interactive_devices;
++              goto parse_string;
++
++      case oPubkeyAuthentication:
++              intptr = &options->pubkey_authentication;
++              goto parse_flag;
++
++      case oRSAAuthentication:
++              intptr = &options->rsa_authentication;
++              goto parse_flag;
++
++      case oRhostsRSAAuthentication:
++              intptr = &options->rhosts_rsa_authentication;
++              goto parse_flag;
++
++      case oHostbasedAuthentication:
++              intptr = &options->hostbased_authentication;
++              goto parse_flag;
++
++      case oChallengeResponseAuthentication:
++              intptr = &options->challenge_response_authentication;
++              goto parse_flag;
++
++      case oGssAuthentication:
++              intptr = &options->gss_authentication;
++              goto parse_flag;
++
++      case oGssDelegateCreds:
++              intptr = &options->gss_deleg_creds;
++              goto parse_flag;
++
++      case oBatchMode:
++              intptr = &options->batch_mode;
++              goto parse_flag;
++
++      case oCheckHostIP:
++              intptr = &options->check_host_ip;
++              goto parse_flag;
++
++      case oVerifyHostKeyDNS:
++              intptr = &options->verify_host_key_dns;
++              goto parse_yesnoask;
++
++      case oStrictHostKeyChecking:
++              intptr = &options->strict_host_key_checking;
++parse_yesnoask:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing yes/no/ask argument.",
++                          filename, linenum);
++              value = 0;      /* To avoid compiler warning... */
++              if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++                      value = 1;
++              else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++                      value = 0;
++              else if (strcmp(arg, "ask") == 0)
++                      value = 2;
++              else
++                      fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oCompression:
++              intptr = &options->compression;
++              goto parse_flag;
++
++      case oTCPKeepAlive:
++              intptr = &options->tcp_keep_alive;
++              goto parse_flag;
++
++      case oNoHostAuthenticationForLocalhost:
++              intptr = &options->no_host_authentication_for_localhost;
++              goto parse_flag;
++
++      case oNumberOfPasswordPrompts:
++              intptr = &options->number_of_password_prompts;
++              goto parse_int;
++
++      case oCompressionLevel:
++              intptr = &options->compression_level;
++              goto parse_int;
++
++      case oRekeyLimit:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (arg[0] < '0' || arg[0] > '9')
++                      fatal("%.200s line %d: Bad number.", filename, linenum);
++              orig = val64 = strtoll(arg, &endofnumber, 10);
++              if (arg == endofnumber)
++                      fatal("%.200s line %d: Bad number.", filename, linenum);
++              switch (toupper(*endofnumber)) {
++              case '\0':
++                      scale = 1;
++                      break;
++              case 'K':
++                      scale = 1<<10;
++                      break;
++              case 'M':
++                      scale = 1<<20;
++                      break;
++              case 'G':
++                      scale = 1<<30;
++                      break;
++              default:
++                      fatal("%.200s line %d: Invalid RekeyLimit suffix",
++                          filename, linenum);
++              }
++              val64 *= scale;
++              /* detect integer wrap and too-large limits */
++              if ((val64 / scale) != orig || val64 > UINT_MAX)
++                      fatal("%.200s line %d: RekeyLimit too large",
++                          filename, linenum);
++              if (val64 < 16)
++                      fatal("%.200s line %d: RekeyLimit too small",
++                          filename, linenum);
++              if (*activep && options->rekey_limit == -1)
++                      options->rekey_limit = (u_int32_t)val64;
++              break;
++
++      case oIdentityFile:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (*activep) {
++                      intptr = &options->num_identity_files;
++                      if (*intptr >= SSH_MAX_IDENTITY_FILES)
++                              fatal("%.200s line %d: Too many identity files specified (max %d).",
++                                  filename, linenum, SSH_MAX_IDENTITY_FILES);
++                      charptr = &options->identity_files[*intptr];
++                      *charptr = xstrdup(arg);
++                      *intptr = *intptr + 1;
++              }
++              break;
++
++      case oXAuthLocation:
++              charptr=&options->xauth_location;
++              goto parse_string;
++
++      case oUser:
++              charptr = &options->user;
++parse_string:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (*activep && *charptr == NULL)
++                      *charptr = xstrdup(arg);
++              break;
++
++      case oGlobalKnownHostsFile:
++              charptr = &options->system_hostfile;
++              goto parse_string;
++
++      case oUserKnownHostsFile:
++              charptr = &options->user_hostfile;
++              goto parse_string;
++
++      case oGlobalKnownHostsFile2:
++              charptr = &options->system_hostfile2;
++              goto parse_string;
++
++      case oUserKnownHostsFile2:
++              charptr = &options->user_hostfile2;
++              goto parse_string;
++
++      case oHostName:
++              charptr = &options->hostname;
++              goto parse_string;
++
++      case oHostKeyAlias:
++              charptr = &options->host_key_alias;
++              goto parse_string;
++
++      case oPreferredAuthentications:
++              charptr = &options->preferred_authentications;
++              goto parse_string;
++
++      case oBindAddress:
++              charptr = &options->bind_address;
++              goto parse_string;
++
++      case oSmartcardDevice:
++              charptr = &options->smartcard_device;
++              goto parse_string;
++
++      case oProxyCommand:
++              charptr = &options->proxy_command;
++parse_command:
++              if (s == NULL)
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              len = strspn(s, WHITESPACE "=");
++              if (*activep && *charptr == NULL)
++                      *charptr = xstrdup(s + len);
++              return 0;
++
++      case oPort:
++              intptr = &options->port;
++parse_int:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (arg[0] < '0' || arg[0] > '9')
++                      fatal("%.200s line %d: Bad number.", filename, linenum);
++
++              /* Octal, decimal, or hex format? */
++              value = strtol(arg, &endofnumber, 0);
++              if (arg == endofnumber)
++                      fatal("%.200s line %d: Bad number.", filename, linenum);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oConnectionAttempts:
++              intptr = &options->connection_attempts;
++              goto parse_int;
++
++      case oCipher:
++              intptr = &options->cipher;
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              value = cipher_number(arg);
++              if (value == -1)
++                      fatal("%.200s line %d: Bad cipher '%s'.",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oCiphers:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (!ciphers_valid(arg))
++                      fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && options->ciphers == NULL)
++                      options->ciphers = xstrdup(arg);
++              break;
++
++      case oMacs:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (!mac_valid(arg))
++                      fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && options->macs == NULL)
++                      options->macs = xstrdup(arg);
++              break;
++
++      case oHostKeyAlgorithms:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (!key_names_valid2(arg))
++                      fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && options->hostkeyalgorithms == NULL)
++                      options->hostkeyalgorithms = xstrdup(arg);
++              break;
++
++      case oProtocol:
++              intptr = &options->protocol;
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              value = proto_spec(arg);
++              if (value == SSH_PROTO_UNKNOWN)
++                      fatal("%.200s line %d: Bad protocol spec '%s'.",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && *intptr == SSH_PROTO_UNKNOWN)
++                      *intptr = value;
++              break;
++
++      case oLogLevel:
++              log_level_ptr = &options->log_level;
++              arg = strdelim(&s);
++              value = log_level_number(arg);
++              if (value == SYSLOG_LEVEL_NOT_SET)
++                      fatal("%.200s line %d: unsupported log level '%s'",
++                          filename, linenum, arg ? arg : "<NONE>");
++              if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
++                      *log_level_ptr = (LogLevel) value;
++              break;
++
++      case oLocalForward:
++      case oRemoteForward:
++      case oDynamicForward:
++              arg = strdelim(&s);
++              if (arg == NULL || *arg == '\0')
++                      fatal("%.200s line %d: Missing port argument.",
++                          filename, linenum);
++
++              if (opcode == oLocalForward ||
++                  opcode == oRemoteForward) {
++                      arg2 = strdelim(&s);
++                      if (arg2 == NULL || *arg2 == '\0')
++                              fatal("%.200s line %d: Missing target argument.",
++                                  filename, linenum);
++
++                      /* construct a string for parse_forward */
++                      snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
++              } else if (opcode == oDynamicForward) {
++                      strlcpy(fwdarg, arg, sizeof(fwdarg));
++              }
++
++              if (parse_forward(&fwd, fwdarg,
++                  opcode == oDynamicForward ? 1 : 0,
++                  opcode == oRemoteForward ? 1 : 0) == 0)
++                      fatal("%.200s line %d: Bad forwarding specification.",
++                          filename, linenum);
++
++              if (*activep) {
++                      if (opcode == oLocalForward ||
++                          opcode == oDynamicForward)
++                              add_local_forward(options, &fwd);
++                      else if (opcode == oRemoteForward)
++                              add_remote_forward(options, &fwd);
++              }
++              break;
++
++      case oClearAllForwardings:
++              intptr = &options->clear_forwardings;
++              goto parse_flag;
++
++      case oHost:
++              *activep = 0;
++              while ((arg = strdelim(&s)) != NULL && *arg != '\0')
++                      if (match_pattern(host, arg)) {
++                              debug("Applying options for %.100s", arg);
++                              *activep = 1;
++                              break;
++                      }
++              /* Avoid garbage check below, as strdelim is done. */
++              return 0;
++
++      case oEscapeChar:
++              intptr = &options->escape_char;
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              if (arg[0] == '^' && arg[2] == 0 &&
++                  (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
++                      value = (u_char) arg[1] & 31;
++              else if (strlen(arg) == 1)
++                      value = (u_char) arg[0];
++              else if (strcmp(arg, "none") == 0)
++                      value = SSH_ESCAPECHAR_NONE;
++              else {
++                      fatal("%.200s line %d: Bad escape character.",
++                          filename, linenum);
++                      /* NOTREACHED */
++                      value = 0;      /* Avoid compiler warning. */
++              }
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oAddressFamily:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%s line %d: missing address family.",
++                          filename, linenum);
++              intptr = &options->address_family;
++              if (strcasecmp(arg, "inet") == 0)
++                      value = AF_INET;
++              else if (strcasecmp(arg, "inet6") == 0)
++                      value = AF_INET6;
++              else if (strcasecmp(arg, "any") == 0)
++                      value = AF_UNSPEC;
++              else
++                      fatal("Unsupported AddressFamily \"%s\"", arg);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oEnableSSHKeysign:
++              intptr = &options->enable_ssh_keysign;
++              goto parse_flag;
++
++      case oIdentitiesOnly:
++              intptr = &options->identities_only;
++              goto parse_flag;
++
++      case oServerAliveInterval:
++              intptr = &options->server_alive_interval;
++              goto parse_time;
++
++      case oServerAliveCountMax:
++              intptr = &options->server_alive_count_max;
++              goto parse_int;
++
++      case oSendEnv:
++              while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
++                      if (strchr(arg, '=') != NULL)
++                              fatal("%s line %d: Invalid environment name.",
++                                  filename, linenum);
++                      if (!*activep)
++                              continue;
++                      if (options->num_send_env >= MAX_SEND_ENV)
++                              fatal("%s line %d: too many send env.",
++                                  filename, linenum);
++                      options->send_env[options->num_send_env++] =
++                          xstrdup(arg);
++              }
++              break;
++
++      case oControlPath:
++              charptr = &options->control_path;
++              goto parse_string;
++
++      case oControlMaster:
++              intptr = &options->control_master;
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing ControlMaster argument.",
++                          filename, linenum);
++              value = 0;      /* To avoid compiler warning... */
++              if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++                      value = SSHCTL_MASTER_YES;
++              else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++                      value = SSHCTL_MASTER_NO;
++              else if (strcmp(arg, "auto") == 0)
++                      value = SSHCTL_MASTER_AUTO;
++              else if (strcmp(arg, "ask") == 0)
++                      value = SSHCTL_MASTER_ASK;
++              else if (strcmp(arg, "autoask") == 0)
++                      value = SSHCTL_MASTER_AUTO_ASK;
++              else
++                      fatal("%.200s line %d: Bad ControlMaster argument.",
++                          filename, linenum);
++              if (*activep && *intptr == -1)
++                      *intptr = value;
++              break;
++
++      case oHashKnownHosts:
++              intptr = &options->hash_known_hosts;
++              goto parse_flag;
++
++      case oTunnel:
++              intptr = &options->tun_open;
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%s line %d: Missing yes/point-to-point/"
++                          "ethernet/no argument.", filename, linenum);
++              value = 0;      /* silence compiler */
++              if (strcasecmp(arg, "ethernet") == 0)
++                      value = SSH_TUNMODE_ETHERNET;
++              else if (strcasecmp(arg, "point-to-point") == 0)
++                      value = SSH_TUNMODE_POINTOPOINT;
++              else if (strcasecmp(arg, "yes") == 0)
++                      value = SSH_TUNMODE_DEFAULT;
++              else if (strcasecmp(arg, "no") == 0)
++                      value = SSH_TUNMODE_NO;
++              else
++                      fatal("%s line %d: Bad yes/point-to-point/ethernet/"
++                          "no argument: %s", filename, linenum, arg);
++              if (*activep)
++                      *intptr = value;
++              break;
++
++      case oTunnelDevice:
++              arg = strdelim(&s);
++              if (!arg || *arg == '\0')
++                      fatal("%.200s line %d: Missing argument.", filename, linenum);
++              value = a2tun(arg, &value2);
++              if (value == SSH_TUNID_ERR)
++                      fatal("%.200s line %d: Bad tun device.", filename, linenum);
++              if (*activep) {
++                      options->tun_local = value;
++                      options->tun_remote = value2;
++              }
++              break;
++
++      case oLocalCommand:
++              charptr = &options->local_command;
++              goto parse_command;
++
++      case oPermitLocalCommand:
++              intptr = &options->permit_local_command;
++              goto parse_flag;
++
++      case oVisualHostKey:
++              intptr = &options->visual_host_key;
++              goto parse_flag;
++
++      case oDeprecated:
++              debug("%s line %d: Deprecated option \"%s\"",
++                  filename, linenum, keyword);
++              return 0;
++
++      case oUnsupported:
++              error("%s line %d: Unsupported option \"%s\"",
++                  filename, linenum, keyword);
++              return 0;
++
++      default:
++              fatal("process_config_line: Unimplemented opcode %d", opcode);
++      }
++
++      /* Check that there is no garbage at end of line. */
++      if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
++              fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
++                  filename, linenum, arg);
++      }
++      return 0;
++}
++
++
++/*
++ * Reads the config file and modifies the options accordingly.  Options
++ * should already be initialized before this call.  This never returns if
++ * there is an error.  If the file does not exist, this returns 0.
++ */
++
++int
++read_config_file(const char *filename, const char *host, Options *options,
++    int checkperm)
++{
++      FILE *f;
++      char line[1024];
++      int active, linenum;
++      int bad_options = 0;
++
++      if ((f = fopen(filename, "r")) == NULL)
++              return 0;
++
++      if (checkperm) {
++              struct stat sb;
++
++              if (fstat(fileno(f), &sb) == -1)
++                      fatal("fstat %s: %s", filename, strerror(errno));
++              if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
++                  (sb.st_mode & 022) != 0))
++                      fatal("Bad owner or permissions on %s", filename);
++      }
++
++      debug("Reading configuration data %.200s", filename);
++
++      /*
++       * Mark that we are now processing the options.  This flag is turned
++       * on/off by Host specifications.
++       */
++      active = 1;
++      linenum = 0;
++      while (fgets(line, sizeof(line), f)) {
++              /* Update line number counter. */
++              linenum++;
++              if (process_config_line(options, host, line, filename, linenum, &active) != 0)
++                      bad_options++;
++      }
++      fclose(f);
++      if (bad_options > 0)
++              fatal("%s: terminating, %d bad configuration options",
++                  filename, bad_options);
++      return 1;
++}
++
++/*
++ * Initializes options to special values that indicate that they have not yet
++ * been set.  Read_config_file will only set options with this value. Options
++ * are processed in the following order: command line, user config file,
++ * system config file.  Last, fill_default_options is called.
++ */
++
++void
++initialize_options(Options * options)
++{
++      memset(options, 'X', sizeof(*options));
++      options->forward_agent = -1;
++      options->forward_x11 = -1;
++      options->forward_x11_trusted = -1;
++      options->exit_on_forward_failure = -1;
++      options->xauth_location = NULL;
++      options->gateway_ports = -1;
++      options->use_privileged_port = -1;
++      options->rsa_authentication = -1;
++      options->pubkey_authentication = -1;
++      options->challenge_response_authentication = -1;
++      options->gss_authentication = -1;
++      options->gss_deleg_creds = -1;
++      options->password_authentication = -1;
++      options->kbd_interactive_authentication = -1;
++      options->kbd_interactive_devices = NULL;
++      options->rhosts_rsa_authentication = -1;
++      options->hostbased_authentication = -1;
++      options->batch_mode = -1;
++      options->check_host_ip = -1;
++      options->strict_host_key_checking = -1;
++      options->compression = -1;
++      options->tcp_keep_alive = -1;
++      options->compression_level = -1;
++      options->port = -1;
++      options->address_family = -1;
++      options->connection_attempts = -1;
++      options->connection_timeout = -1;
++      options->number_of_password_prompts = -1;
++      options->cipher = -1;
++      options->ciphers = NULL;
++      options->macs = NULL;
++      options->hostkeyalgorithms = NULL;
++      options->protocol = SSH_PROTO_UNKNOWN;
++      options->num_identity_files = 0;
++      options->hostname = NULL;
++      options->host_key_alias = NULL;
++      options->proxy_command = NULL;
++      options->user = NULL;
++      options->escape_char = -1;
++      options->system_hostfile = NULL;
++      options->user_hostfile = NULL;
++      options->system_hostfile2 = NULL;
++      options->user_hostfile2 = NULL;
++      options->num_local_forwards = 0;
++      options->num_remote_forwards = 0;
++      options->clear_forwardings = -1;
++      options->log_level = SYSLOG_LEVEL_NOT_SET;
++      options->preferred_authentications = NULL;
++      options->bind_address = NULL;
++      options->smartcard_device = NULL;
++      options->enable_ssh_keysign = - 1;
++      options->no_host_authentication_for_localhost = - 1;
++      options->identities_only = - 1;
++      options->rekey_limit = - 1;
++      options->verify_host_key_dns = -1;
++      options->server_alive_interval = -1;
++      options->server_alive_count_max = -1;
++      options->num_send_env = 0;
++      options->control_path = NULL;
++      options->control_master = -1;
++      options->hash_known_hosts = -1;
++      options->tun_open = -1;
++      options->tun_local = -1;
++      options->tun_remote = -1;
++      options->local_command = NULL;
++      options->permit_local_command = -1;
++      options->visual_host_key = -1;
++      options->zero_knowledge_password_authentication = -1;
++}
++
++/*
++ * Called after processing other sources of option data, this fills those
++ * options for which no value has been specified with their default values.
++ */
++
++void
++fill_default_options(Options * options)
++{
++      int len;
++
++      if (options->forward_agent == -1)
++              options->forward_agent = 0;
++      if (options->forward_x11 == -1)
++              options->forward_x11 = 0;
++      if (options->forward_x11_trusted == -1)
++              options->forward_x11_trusted = 0;
++      if (options->exit_on_forward_failure == -1)
++              options->exit_on_forward_failure = 0;
++      if (options->xauth_location == NULL)
++              options->xauth_location = _PATH_XAUTH;
++      if (options->gateway_ports == -1)
++              options->gateway_ports = 0;
++      if (options->use_privileged_port == -1)
++              options->use_privileged_port = 0;
++      if (options->rsa_authentication == -1)
++              options->rsa_authentication = 1;
++      if (options->pubkey_authentication == -1)
++              options->pubkey_authentication = 1;
++      if (options->challenge_response_authentication == -1)
++              options->challenge_response_authentication = 1;
++      if (options->gss_authentication == -1)
++              options->gss_authentication = 0;
++      if (options->gss_deleg_creds == -1)
++              options->gss_deleg_creds = 0;
++      if (options->password_authentication == -1)
++              options->password_authentication = 1;
++      if (options->kbd_interactive_authentication == -1)
++              options->kbd_interactive_authentication = 1;
++      if (options->rhosts_rsa_authentication == -1)
++              options->rhosts_rsa_authentication = 0;
++      if (options->hostbased_authentication == -1)
++              options->hostbased_authentication = 0;
++      if (options->batch_mode == -1)
++              options->batch_mode = 0;
++      if (options->check_host_ip == -1)
++              options->check_host_ip = 1;
++      if (options->strict_host_key_checking == -1)
++              options->strict_host_key_checking = 2;  /* 2 is default */
++      if (options->compression == -1)
++              options->compression = 0;
++      if (options->tcp_keep_alive == -1)
++              options->tcp_keep_alive = 1;
++      if (options->compression_level == -1)
++              options->compression_level = 6;
++      if (options->port == -1)
++              options->port = 0;      /* Filled in ssh_connect. */
++      if (options->address_family == -1)
++              options->address_family = AF_UNSPEC;
++      if (options->connection_attempts == -1)
++              options->connection_attempts = 1;
++      if (options->number_of_password_prompts == -1)
++              options->number_of_password_prompts = 3;
++      /* Selected in ssh_login(). */
++      if (options->cipher == -1)
++              options->cipher = SSH_CIPHER_NOT_SET;
++      /* options->ciphers, default set in myproposals.h */
++      /* options->macs, default set in myproposals.h */
++      /* options->hostkeyalgorithms, default set in myproposals.h */
++      if (options->protocol == SSH_PROTO_UNKNOWN)
++              options->protocol = SSH_PROTO_1|SSH_PROTO_2;
++      if (options->num_identity_files == 0) {
++              if (options->protocol & SSH_PROTO_1) {
++                      len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
++                      options->identity_files[options->num_identity_files] =
++                          xmalloc(len);
++                      snprintf(options->identity_files[options->num_identity_files++],
++                          len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
++              }
++              if (options->protocol & SSH_PROTO_2) {
++                      len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
++                      options->identity_files[options->num_identity_files] =
++                          xmalloc(len);
++                      snprintf(options->identity_files[options->num_identity_files++],
++                          len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
++
++                      len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
++                      options->identity_files[options->num_identity_files] =
++                          xmalloc(len);
++                      snprintf(options->identity_files[options->num_identity_files++],
++                          len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
++              }
++      }
++      if (options->escape_char == -1)
++              options->escape_char = '~';
++      if (options->system_hostfile == NULL)
++              options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
++      if (options->user_hostfile == NULL)
++              options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
++      if (options->system_hostfile2 == NULL)
++              options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
++      if (options->user_hostfile2 == NULL)
++              options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
++      if (options->log_level == SYSLOG_LEVEL_NOT_SET)
++              options->log_level = SYSLOG_LEVEL_INFO;
++      if (options->clear_forwardings == 1)
++              clear_forwardings(options);
++      if (options->no_host_authentication_for_localhost == - 1)
++              options->no_host_authentication_for_localhost = 0;
++      if (options->identities_only == -1)
++              options->identities_only = 0;
++      if (options->enable_ssh_keysign == -1)
++              options->enable_ssh_keysign = 0;
++      if (options->rekey_limit == -1)
++              options->rekey_limit = 0;
++      if (options->verify_host_key_dns == -1)
++              options->verify_host_key_dns = 0;
++      if (options->server_alive_interval == -1)
++              options->server_alive_interval = 0;
++      if (options->server_alive_count_max == -1)
++              options->server_alive_count_max = 3;
++      if (options->control_master == -1)
++              options->control_master = 0;
++      if (options->hash_known_hosts == -1)
++              options->hash_known_hosts = 0;
++      if (options->tun_open == -1)
++              options->tun_open = SSH_TUNMODE_NO;
++      if (options->tun_local == -1)
++              options->tun_local = SSH_TUNID_ANY;
++      if (options->tun_remote == -1)
++              options->tun_remote = SSH_TUNID_ANY;
++      if (options->permit_local_command == -1)
++              options->permit_local_command = 0;
++      if (options->visual_host_key == -1)
++              options->visual_host_key = 0;
++      if (options->zero_knowledge_password_authentication == -1)
++              options->zero_knowledge_password_authentication = 0;
++      /* options->local_command should not be set by default */
++      /* options->proxy_command should not be set by default */
++      /* options->user will be set in the main program if appropriate */
++      /* options->hostname will be set in the main program if appropriate */
++      /* options->host_key_alias should not be set by default */
++      /* options->preferred_authentications will be set in ssh */
++}
++
++/*
++ * parse_forward
++ * parses a string containing a port forwarding specification of the form:
++ *   dynamicfwd == 0
++ *    [listenhost:]listenport:connecthost:connectport
++ *   dynamicfwd == 1
++ *    [listenhost:]listenport
++ * returns number of arguments parsed or zero on error
++ */
++int
++parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
++{
++      int i;
++      char *p, *cp, *fwdarg[4];
++
++      memset(fwd, '\0', sizeof(*fwd));
++
++      cp = p = xstrdup(fwdspec);
++
++      /* skip leading spaces */
++      while (isspace(*cp))
++              cp++;
++
++      for (i = 0; i < 4; ++i)
++              if ((fwdarg[i] = hpdelim(&cp)) == NULL)
++                      break;
++
++      /* Check for trailing garbage */
++      if (cp != NULL)
++              i = 0;  /* failure */
++
++      switch (i) {
++      case 1:
++              fwd->listen_host = NULL;
++              fwd->listen_port = a2port(fwdarg[0]);
++              fwd->connect_host = xstrdup("socks");
++              break;
++
++      case 2:
++              fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
++              fwd->listen_port = a2port(fwdarg[1]);
++              fwd->connect_host = xstrdup("socks");
++              break;
++
++      case 3:
++              fwd->listen_host = NULL;
++              fwd->listen_port = a2port(fwdarg[0]);
++              fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
++              fwd->connect_port = a2port(fwdarg[2]);
++              break;
++
++      case 4:
++              fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
++              fwd->listen_port = a2port(fwdarg[1]);
++              fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
++              fwd->connect_port = a2port(fwdarg[3]);
++              break;
++      default:
++              i = 0; /* failure */
++      }
++
++      xfree(p);
++
++      if (dynamicfwd) {
++              if (!(i == 1 || i == 2))
++                      goto fail_free;
++      } else {
++              if (!(i == 3 || i == 4))
++                      goto fail_free;
++              if (fwd->connect_port <= 0)
++                      goto fail_free;
++      }
++
++      if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
++              goto fail_free;
++
++      if (fwd->connect_host != NULL &&
++          strlen(fwd->connect_host) >= NI_MAXHOST)
++              goto fail_free;
++      if (fwd->listen_host != NULL &&
++          strlen(fwd->listen_host) >= NI_MAXHOST)
++              goto fail_free;
++
++
++      return (i);
++
++ fail_free:
++      if (fwd->connect_host != NULL) {
++              xfree(fwd->connect_host);
++              fwd->connect_host = NULL;
++      }
++      if (fwd->listen_host != NULL) {
++              xfree(fwd->listen_host);
++              fwd->listen_host = NULL;
++      }
++      return (0);
++}
+diff -NupwB openssh-5.2p1-canonical/readconf.h openssh-5.2p1-hpn13v6/readconf.h
+--- openssh-5.2p1-canonical/readconf.h 2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/readconf.h   2009-05-14 12:36:10.000000000 -0400
+@@ -57,6 +57,11 @@ 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 */
++      int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
++      int     hpn_disabled;    /* Switch to disable HPN buffer management */
++      int     hpn_buffer_size; /* User definable size for HPN buffer window */
++
+       LogLevel log_level;     /* Level for logging. */
+       int     port;           /* Port to connect. */
+@@ -102,6 +107,8 @@ typedef struct {
+       int     enable_ssh_keysign;
+       int64_t rekey_limit;
++      int     none_switch;    /* Use none cipher */
++      int     none_enabled;   /* Allow none to be used */
+       int     no_host_authentication_for_localhost;
+       int     identities_only;
+       int     server_alive_interval;
+diff -NupwB openssh-5.2p1-canonical/readconf.h.orig openssh-5.2p1-hpn13v6/readconf.h.orig
+--- openssh-5.2p1-canonical/readconf.h.orig    1969-12-31 19:00:00.000000000 -0500
++++ openssh-5.2p1-hpn13v6/readconf.h.orig      2009-02-14 00:28:21.000000000 -0500
+@@ -0,0 +1,145 @@
++/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
++
++/*
++ * Author: Tatu Ylonen <ylo@cs.hut.fi>
++ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
++ *                    All rights reserved
++ * Functions for reading the configuration file.
++ *
++ * As far as I am concerned, the code I have written for this software
++ * can be used freely for any purpose.  Any derived versions of this
++ * software must be clearly marked as such, and if the derived work is
++ * incompatible with the protocol description in the RFC file, it must be
++ * called by a name other than "ssh" or "Secure Shell".
++ */
++
++#ifndef READCONF_H
++#define READCONF_H
++
++/* Data structure for representing a forwarding request. */
++
++typedef struct {
++      char     *listen_host;          /* Host (address) to listen on. */
++      int       listen_port;          /* Port to forward. */
++      char     *connect_host;         /* Host to connect. */
++      int       connect_port;         /* Port to connect on connect_host. */
++}       Forward;
++/* Data structure for representing option data. */
++
++#define MAX_SEND_ENV  256
++
++typedef struct {
++      int     forward_agent;  /* Forward authentication agent. */
++      int     forward_x11;    /* Forward X11 display. */
++      int     forward_x11_trusted;    /* Trust Forward X11 display. */
++      int     exit_on_forward_failure;        /* Exit if bind(2) fails for -L/-R */
++      char   *xauth_location; /* Location for xauth program */
++      int     gateway_ports;  /* Allow remote connects to forwarded ports. */
++      int     use_privileged_port;    /* Don't use privileged port if false. */
++      int     rhosts_rsa_authentication;      /* Try rhosts with RSA
++                                               * authentication. */
++      int     rsa_authentication;     /* Try RSA authentication. */
++      int     pubkey_authentication;  /* Try ssh2 pubkey authentication. */
++      int     hostbased_authentication;       /* ssh2's rhosts_rsa */
++      int     challenge_response_authentication;
++                                      /* Try S/Key or TIS, authentication. */
++      int     gss_authentication;     /* Try GSS authentication */
++      int     gss_deleg_creds;        /* Delegate GSS credentials */
++      int     password_authentication;        /* Try password
++                                               * authentication. */
++      int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
++      char    *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
++      int     zero_knowledge_password_authentication; /* Try jpake */
++      int     batch_mode;     /* Batch mode: do not ask for passwords. */
++      int     check_host_ip;  /* Also keep track of keys for IP address */
++      int     strict_host_key_checking;       /* Strict host key checking. */
++      int     compression;    /* Compress packets in both directions. */
++      int     compression_level;      /* Compression level 1 (fast) to 9
++                                       * (best). */
++      int     tcp_keep_alive; /* Set SO_KEEPALIVE. */
++      LogLevel log_level;     /* Level for logging. */
++
++      int     port;           /* Port to connect. */
++      int     address_family;
++      int     connection_attempts;    /* Max attempts (seconds) before
++                                       * giving up */
++      int     connection_timeout;     /* Max time (seconds) before
++                                       * aborting connection attempt */
++      int     number_of_password_prompts;     /* Max number of password
++                                               * prompts. */
++      int     cipher;         /* Cipher to use. */
++      char   *ciphers;        /* SSH2 ciphers in order of preference. */
++      char   *macs;           /* SSH2 macs in order of preference. */
++      char   *hostkeyalgorithms;      /* SSH2 server key types in order of preference. */
++      int     protocol;       /* Protocol in order of preference. */
++      char   *hostname;       /* Real host to connect. */
++      char   *host_key_alias; /* hostname alias for .ssh/known_hosts */
++      char   *proxy_command;  /* Proxy command for connecting the host. */
++      char   *user;           /* User to log in as. */
++      int     escape_char;    /* Escape character; -2 = none */
++
++      char   *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
++      char   *user_hostfile;  /* Path for $HOME/.ssh/known_hosts. */
++      char   *system_hostfile2;
++      char   *user_hostfile2;
++      char   *preferred_authentications;
++      char   *bind_address;   /* local socket address for connection to sshd */
++      char   *smartcard_device; /* Smartcard reader device */
++      int     verify_host_key_dns;    /* Verify host key using DNS */
++
++      int     num_identity_files;     /* Number of files for RSA/DSA identities. */
++      char   *identity_files[SSH_MAX_IDENTITY_FILES];
++      Key    *identity_keys[SSH_MAX_IDENTITY_FILES];
++
++      /* Local TCP/IP forward requests. */
++      int     num_local_forwards;
++      Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
++
++      /* Remote TCP/IP forward requests. */
++      int     num_remote_forwards;
++      Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
++      int     clear_forwardings;
++
++      int     enable_ssh_keysign;
++      int64_t rekey_limit;
++      int     no_host_authentication_for_localhost;
++      int     identities_only;
++      int     server_alive_interval;
++      int     server_alive_count_max;
++
++      int     num_send_env;
++      char   *send_env[MAX_SEND_ENV];
++
++      char    *control_path;
++      int     control_master;
++
++      int     hash_known_hosts;
++
++      int     tun_open;       /* tun(4) */
++      int     tun_local;      /* force tun device (optional) */
++      int     tun_remote;     /* force tun device (optional) */
++
++      char    *local_command;
++      int     permit_local_command;
++      int     visual_host_key;
++
++}       Options;
++
++#define SSHCTL_MASTER_NO      0
++#define SSHCTL_MASTER_YES     1
++#define SSHCTL_MASTER_AUTO    2
++#define SSHCTL_MASTER_ASK     3
++#define SSHCTL_MASTER_AUTO_ASK        4
++
++void     initialize_options(Options *);
++void     fill_default_options(Options *);
++int    read_config_file(const char *, const char *, Options *, int);
++int    parse_forward(Forward *, const char *, int, int);
++
++int
++process_config_line(Options *, const char *, char *, const char *, int, int *);
++
++void   add_local_forward(Options *, const Forward *);
++void   add_remote_forward(Options *, const Forward *);
++
++#endif                                /* READCONF_H */
+Common subdirectories: openssh-5.2p1-canonical/regress and openssh-5.2p1-hpn13v6/regress
+Common subdirectories: openssh-5.2p1-canonical/scard and openssh-5.2p1-hpn13v6/scard
+diff -NupwB openssh-5.2p1-canonical/scp.c openssh-5.2p1-hpn13v6/scp.c
+--- openssh-5.2p1-canonical/scp.c      2008-11-03 03:23:45.000000000 -0500
++++ openssh-5.2p1-hpn13v6/scp.c        2009-05-14 12:36:10.000000000 -0400
+@@ -632,7 +632,7 @@ source(int argc, char **argv)
+       off_t i, statbytes;
+       size_t amt;
+       int fd = -1, haderr, indx;
+-      char *last, *name, buf[2048], encname[MAXPATHLEN];
++      char *last, *name, buf[16384], encname[MAXPATHLEN];
+       int len;
+       for (indx = 0; indx < argc; ++indx) {
+@@ -868,7 +868,7 @@ sink(int argc, char **argv)
+       mode_t mode, omode, mask;
+       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]
+diff -NupwB openssh-5.2p1-canonical/servconf.c openssh-5.2p1-hpn13v6/servconf.c
+--- openssh-5.2p1-canonical/servconf.c 2009-01-28 00:31:23.000000000 -0500
++++ openssh-5.2p1-hpn13v6/servconf.c   2009-05-14 12:36:10.000000000 -0400
+@@ -128,11 +128,20 @@ initialize_server_options(ServerOptions 
+       options->adm_forced_command = NULL;
+       options->chroot_directory = NULL;
+       options->zero_knowledge_password_authentication = -1;
++      options->none_enabled = -1;
++      options->tcp_rcv_buf_poll = -1;
++      options->hpn_disabled = -1;
++      options->hpn_buffer_size = -1;
+ }
+ void
+ fill_default_server_options(ServerOptions *options)
+ {
++      /* needed for hpn socket tests */
++      int sock;
++      int socksize;
++      int socksizelen = sizeof(int);
++
+       /* Portable-specific options */
+       if (options->use_pam == -1)
+               options->use_pam = 0;
+@@ -262,6 +271,42 @@ fill_default_server_options(ServerOption
+       if (options->zero_knowledge_password_authentication == -1)
+               options->zero_knowledge_password_authentication = 0;
++      if (options->hpn_disabled == -1) 
++              options->hpn_disabled = 0;
++
++      if (options->hpn_buffer_size == -1) {
++              /* option not explicitly set. Now we have to figure out */
++              /* what value to use */
++              if (options->hpn_disabled == 1) {
++                      options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
++              } else {
++                      /* get the current RCV size and set it to that */
++                      /*create a socket but don't connect it */
++                      /* we use that the get the rcv socket size */
++                      sock = socket(AF_INET, SOCK_STREAM, 0);
++                      getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
++                                 &socksize, &socksizelen);
++                      close(sock);
++                      options->hpn_buffer_size = socksize;
++                      debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
++                      
++              } 
++      } else {
++              /* we have to do this incase the user sets both values in a contradictory */
++              /* manner. hpn_disabled overrrides hpn_buffer_size*/
++              if (options->hpn_disabled <= 0) {
++                      if (options->hpn_buffer_size == 0)
++                              options->hpn_buffer_size = 1;
++                      /* limit the maximum buffer to 64MB */
++                      if (options->hpn_buffer_size > 64*1024) {
++                              options->hpn_buffer_size = 64*1024*1024;
++                      } else {
++                              options->hpn_buffer_size *= 1024;
++                      }
++              } else
++                      options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
++      }
++
+       /* Turn privilege separation on by default */
+       if (use_privsep == -1)
+               use_privsep = 1;
+@@ -306,6 +351,7 @@ typedef enum {
+       sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
+       sUsePrivilegeSeparation, sAllowAgentForwarding,
+       sZeroKnowledgePasswordAuthentication,
++      sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
+       sDeprecated, sUnsupported
+ } ServerOpCodes;
+@@ -424,6 +470,10 @@ static struct {
+       { "permitopen", sPermitOpen, SSHCFG_ALL },
+       { "forcecommand", sForceCommand, SSHCFG_ALL },
+       { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
++      { "noneenabled", sNoneEnabled },
++      { "hpndisabled", sHPNDisabled },
++      { "hpnbuffersize", sHPNBufferSize },
++      { "tcprcvbufpoll", sTcpRcvBufPoll },
+       { NULL, sBadOption, 0 }
+ };
+@@ -450,6 +500,7 @@ parse_token(const char *cp, const char *
+       for (i = 0; keywords[i].name; i++)
+               if (strcasecmp(cp, keywords[i].name) == 0) {
++                      debug ("Config token is %s", keywords[i].name);
+                       *flags = keywords[i].flags;
+                       return keywords[i].opcode;
+               }
+@@ -847,6 +898,22 @@ process_server_config_line(ServerOptions
+                       *intptr = value;
+               break;
++      case sNoneEnabled:
++              intptr = &options->none_enabled;
++              goto parse_flag;
++
++      case sTcpRcvBufPoll:
++              intptr = &options->tcp_rcv_buf_poll;
++              goto parse_flag;
++
++      case sHPNDisabled:
++              intptr = &options->hpn_disabled;
++              goto parse_flag;
++
++      case sHPNBufferSize:
++              intptr = &options->hpn_buffer_size;
++              goto parse_int;
++
+       case sIgnoreUserKnownHosts:
+               intptr = &options->ignore_user_known_hosts;
+               goto parse_flag;
+diff -NupwB openssh-5.2p1-canonical/servconf.h openssh-5.2p1-hpn13v6/servconf.h
+--- openssh-5.2p1-canonical/servconf.h 2009-01-28 00:31:23.000000000 -0500
++++ openssh-5.2p1-hpn13v6/servconf.h   2009-05-14 12:36:10.000000000 -0400
+@@ -145,6 +145,10 @@ typedef struct {
+       char   *adm_forced_command;
+       int     use_pam;                /* Enable auth via PAM */
++        int     none_enabled;           /* enable NONE cipher switch */
++        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
++      int     hpn_disabled;           /* disable hpn functionality. false by default */
++      int     hpn_buffer_size;        /* set the hpn buffer size - default 3MB */
+       int     permit_tun;
+diff -NupwB openssh-5.2p1-canonical/serverloop.c openssh-5.2p1-hpn13v6/serverloop.c
+--- openssh-5.2p1-canonical/serverloop.c       2009-02-14 00:33:09.000000000 -0500
++++ openssh-5.2p1-hpn13v6/serverloop.c 2009-05-14 12:36:10.000000000 -0400
+@@ -93,10 +93,10 @@ static int fdin;           /* Descriptor for stdi
+ static int fdout;             /* Descriptor for stdout (for reading);
+                                  May be same number as fdin. */
+ static int fderr;             /* Descriptor for stderr.  May be -1. */
+-static long stdin_bytes = 0;  /* Number of bytes written to stdin. */
+-static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
+-static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
+-static long fdout_bytes = 0;  /* Number of stdout bytes read from program. */
++static u_long stdin_bytes = 0;        /* Number of bytes written to stdin. */
++static u_long stdout_bytes = 0;       /* Number of stdout bytes sent to client. */
++static u_long stderr_bytes = 0;       /* Number of stderr bytes sent to client. */
++static u_long fdout_bytes = 0;        /* Number of stdout bytes read from program. */
+ static int stdin_eof = 0;     /* EOF message received from client. */
+ static int fdout_eof = 0;     /* EOF encountered reading from fdout. */
+ static int fderr_eof = 0;     /* EOF encountered readung from fderr. */
+@@ -121,6 +121,20 @@ static volatile sig_atomic_t received_si
+ static void server_init_dispatch(void);
+ /*
++ * Returns current time in seconds from Jan 1, 1970 with the maximum
++ * available resolution.
++ */
++
++static double
++get_current_time(void)
++{
++      struct timeval tv;
++      gettimeofday(&tv, NULL);
++      return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
++}
++
++
++/*
+  * we write to this pipe if a SIGCHLD is caught in order to avoid
+  * the race between select() and child_terminated
+  */
+@@ -410,6 +424,7 @@ process_input(fd_set *readset)
+               } else {
+                       /* Buffer any received data. */
+                       packet_process_incoming(buf, len);
++                      fdout_bytes += len;
+               }
+       }
+       if (compat20)
+@@ -432,6 +447,7 @@ process_input(fd_set *readset)
+               } else {
+                       buffer_append(&stdout_buffer, buf, len);
+                       fdout_bytes += len;
++                      debug ("FD out now: %ld", fdout_bytes);
+               }
+       }
+       /* Read and buffer any available stderr data from the program. */
+@@ -499,7 +515,7 @@ process_output(fd_set *writeset)
+       }
+       /* Send any buffered packet data to the client. */
+       if (FD_ISSET(connection_out, writeset))
+-              packet_write_poll();
++              stdin_bytes += packet_write_poll();
+ }
+ /*
+@@ -816,8 +832,10 @@ server_loop2(Authctxt *authctxt)
+ {
+       fd_set *readset = NULL, *writeset = NULL;
+       int rekeying = 0, max_fd, nalloc = 0;
++      double start_time, total_time;
+       debug("Entering interactive session for SSH2.");
++      start_time = get_current_time();
+       mysignal(SIGCHLD, sigchld_handler);
+       child_terminated = 0;
+@@ -879,6 +897,11 @@ server_loop2(Authctxt *authctxt)
+       /* free remaining sessions, e.g. remove wtmp entries */
+       session_destroy_all(NULL);
++      total_time = get_current_time() - start_time;
++      logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
++            get_remote_ipaddr(), get_remote_port(),
++            stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
++            fdout_bytes / total_time);
+ }
+ static void
+@@ -994,8 +1017,12 @@ server_request_tun(void)
+       sock = tun_open(tun, mode);
+       if (sock < 0)
+               goto done;
++      if (options.hpn_disabled)
+       c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
+           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
++      else
++              c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
++                  options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
+       c->datagram = 1;
+ #if defined(SSH_TUN_FILTER)
+       if (mode == SSH_TUNMODE_POINTOPOINT)
+@@ -1031,6 +1058,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 ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled))
++              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 -NupwB openssh-5.2p1-canonical/session.c openssh-5.2p1-hpn13v6/session.c
+--- openssh-5.2p1-canonical/session.c  2009-01-28 00:29:49.000000000 -0500
++++ openssh-5.2p1-hpn13v6/session.c    2009-05-14 12:36:10.000000000 -0400
+@@ -230,6 +230,7 @@ auth_input_request_forwarding(struct pas
+       }
+       /* Allocate a channel for the authentication agent socket. */
++      /* this shouldn't matter if its hpn or not - cjr */
+       nc = channel_new("auth socket",
+           SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
+           CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
+@@ -2301,10 +2302,16 @@ session_set_fds(Session *s, int fdin, in
+        */
+       if (s->chanid == -1)
+               fatal("no channel for session %d", s->self);
++      if (options.hpn_disabled)
+       channel_set_fds(s->chanid,
+           fdout, fdin, fderr,
+           fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+           1, is_tty, CHAN_SES_WINDOW_DEFAULT);
++      else 
++              channel_set_fds(s->chanid,
++                  fdout, fdin, fderr,
++                  fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
++                  1, is_tty, options.hpn_buffer_size);
+ }
+ /*
+diff -NupwB openssh-5.2p1-canonical/sftp.1 openssh-5.2p1-hpn13v6/sftp.1
+--- openssh-5.2p1-canonical/sftp.1     2009-01-28 00:14:09.000000000 -0500
++++ openssh-5.2p1-hpn13v6/sftp.1       2009-05-14 12:36:10.000000000 -0400
+@@ -203,7 +203,8 @@ This option may be useful in debugging t
+ Specify how many requests may be outstanding at any one time.
+ Increasing this may slightly improve file transfer speed
+ but will increase memory usage.
+-The default is 64 outstanding requests.
++The default is 256 outstanding requests providing for 8MB 
++of outstanding data with a 32KB buffer.
+ .It Fl S Ar program
+ Name of the
+ .Ar program
+diff -NupwB openssh-5.2p1-canonical/sftp.c openssh-5.2p1-hpn13v6/sftp.c
+--- openssh-5.2p1-canonical/sftp.c     2009-02-14 00:26:19.000000000 -0500
++++ openssh-5.2p1-hpn13v6/sftp.c       2009-05-14 12:36:10.000000000 -0400
+@@ -75,7 +75,7 @@ int batchmode = 0;
+ size_t copy_buffer_len = 32768;
+ /* Number of concurrent outstanding requests */
+-size_t num_requests = 64;
++size_t num_requests = 256;
+ /* PID of ssh transport process */
+ static pid_t sshpid = -1;
+diff -NupwB openssh-5.2p1-canonical/ssh.c openssh-5.2p1-hpn13v6/ssh.c
+--- openssh-5.2p1-canonical/ssh.c      2009-02-14 00:28:21.000000000 -0500
++++ openssh-5.2p1-hpn13v6/ssh.c        2009-05-14 12:36:10.000000000 -0400
+@@ -492,9 +492,6 @@ main(int ac, char **av)
+                       no_shell_flag = 1;
+                       no_tty_flag = 1;
+                       break;
+-              case 'T':
+-                      no_tty_flag = 1;
+-                      break;
+               case 'o':
+                       dummy = 1;
+                       line = xstrdup(optarg);
+@@ -503,6 +500,13 @@ main(int ac, char **av)
+                               exit(255);
+                       xfree(line);
+                       break;
++              case 'T':
++                      no_tty_flag = 1;
++                      /* ensure that the user doesn't try to backdoor a */
++                      /* null cipher switch on an interactive session */
++                      /* so explicitly disable it no matter what */
++                      options.none_switch=0;
++                      break;
+               case 's':
+                       subsystem_flag = 1;
+                       break;
+@@ -1142,6 +1146,9 @@ ssh_session2_open(void)
+ {
+       Channel *c;
+       int window, packetmax, in, out, err;
++      int sock;
++      int socksize;
++      int socksizelen = sizeof(int);
+       if (stdin_null_flag) {
+               in = open(_PATH_DEVNULL, O_RDONLY);
+@@ -1162,9 +1169,75 @@ ssh_session2_open(void)
+       if (!isatty(err))
+               set_nonblock(err);
+-      window = CHAN_SES_WINDOW_DEFAULT;
++      /* we need to check to see if what they want to do about buffer */
++      /* sizes here. In a hpn to nonhpn connection we want to limit */
++      /* the window size to something reasonable in case the far side */
++      /* has the large window bug. In hpn to hpn connection we want to */
++      /* use the max window size but allow the user to override it */
++      /* lastly if they disabled hpn then use the ssh std window size */
++
++      /* so why don't we just do a getsockopt() here and set the */
++      /* ssh window to that? In the case of a autotuning receive */
++      /* window the window would get stuck at the initial buffer */
++      /* size generally less than 96k. Therefore we need to set the */
++      /* maximum ssh window size to the maximum hpn buffer size */
++      /* unless the user has specifically set the tcprcvbufpoll */
++      /* to no. In which case we *can* just set the window to the */
++      /* minimum of the hpn buffer size and tcp receive buffer size */
++      
++      if (tty_flag)
++              options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
++      else
++              options.hpn_buffer_size = 2*1024*1024;
++
++      if (datafellows & SSH_BUG_LARGEWINDOW) 
++      {
++              debug("HPN to Non-HPN Connection");
++      } 
++      else 
++      {
++              if (options.tcp_rcv_buf_poll <= 0) 
++              {
++                      sock = socket(AF_INET, SOCK_STREAM, 0);
++                      getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
++                                 &socksize, &socksizelen);
++                      close(sock);
++                      debug("socksize %d", socksize);
++                      options.hpn_buffer_size = socksize;
++                      debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
++              } 
++              else
++              {
++                      if (options.tcp_rcv_buf > 0) 
++                      {
++                              /*create a socket but don't connect it */
++                              /* we use that the get the rcv socket size */
++                              sock = socket(AF_INET, SOCK_STREAM, 0);
++                              /* if they are using the tcp_rcv_buf option */
++                              /* attempt to set the buffer size to that */
++                              if (options.tcp_rcv_buf) 
++                                      setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
++                                                 sizeof(options.tcp_rcv_buf));
++                              getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
++                                         &socksize, &socksizelen);
++                              close(sock);
++                              debug("socksize %d", socksize);
++                              options.hpn_buffer_size = socksize;
++                              debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
++                      }
++              }
++              
++      }
++
++      debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
++
++      window = options.hpn_buffer_size;
++
++      channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
++
+       packetmax = CHAN_SES_PACKET_DEFAULT;
+       if (tty_flag) {
++              window = 4*CHAN_SES_PACKET_DEFAULT;
+               window >>= 1;
+               packetmax >>= 1;
+       }
+@@ -1172,7 +1245,10 @@ ssh_session2_open(void)
+           "session", SSH_CHANNEL_OPENING, in, out, err,
+           window, packetmax, CHAN_EXTENDED_WRITE,
+           "client-session", /*nonblock*/0);
+-
++      if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
++              c->dynamic_window = 1;
++              debug ("Enabled Dynamic Window Scaling\n");
++      }
+       debug3("ssh_session2_open: channel_new: %d", c->self);
+       channel_send_open(c->self);
+diff -NupwB openssh-5.2p1-canonical/sshconnect2.c openssh-5.2p1-hpn13v6/sshconnect2.c
+--- openssh-5.2p1-canonical/sshconnect2.c      2008-11-05 00:20:47.000000000 -0500
++++ openssh-5.2p1-hpn13v6/sshconnect2.c        2009-05-14 12:36:10.000000000 -0400
+@@ -78,6 +78,12 @@
+ extern char *client_version_string;
+ extern char *server_version_string;
+ extern Options options;
++extern Kex *xxx_kex;
++
++/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
++/* if it is set then prevent the switch to the null cipher */
++
++extern int tty_flag;
+ /*
+  * SSH2 key exchange
+@@ -350,6 +356,28 @@ ssh_userauth2(const char *local_user, co
+       pubkey_cleanup(&authctxt);
+       dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
++      /* if the user wants to use the none cipher do it */
++      /* post authentication and only if the right conditions are met */
++      /* both of the NONE commands must be true and there must be no */
++      /* tty allocated */
++      if ((options.none_switch == 1) && (options.none_enabled == 1)) 
++      {
++              if (!tty_flag) /* no null on tty sessions */
++              {
++                      debug("Requesting none rekeying...");
++                      myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
++                      myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
++                      kex_prop2buf(&xxx_kex->my,myproposal);
++                      packet_request_rekeying();
++                      fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
++              }
++              else
++              {
++                      /* requested NONE cipher when in a tty */
++                      debug("Cannot switch to NONE cipher with tty allocated");
++                      fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
++              }
++      }
+       debug("Authentication succeeded (%s).", authctxt.method->name);
+ }
+diff -NupwB openssh-5.2p1-canonical/sshconnect.c openssh-5.2p1-hpn13v6/sshconnect.c
+--- openssh-5.2p1-canonical/sshconnect.c       2009-02-01 06:19:54.000000000 -0500
++++ openssh-5.2p1-hpn13v6/sshconnect.c 2009-05-14 12:36:10.000000000 -0400
+@@ -165,6 +165,31 @@ ssh_proxy_connect(const char *host, u_sh
+ }
+ /*
++ * Set TCP receive buffer if requested.
++ * Note: tuning needs to happen after the socket is
++ * created but before the connection happens
++ * so winscale is negotiated properly -cjr
++ */
++static void
++ssh_set_socket_recvbuf(int sock)
++{
++      void *buf = (void *)&options.tcp_rcv_buf;
++      int sz = sizeof(options.tcp_rcv_buf);
++      int socksize;
++      int socksizelen = sizeof(int);
++
++      debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
++      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
++        getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
++        debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
++      }
++      else
++              error("Couldn't set socket receive buffer to %d: %.100s",
++                  options.tcp_rcv_buf, strerror(errno));
++}
++
++
++/*
+  * Creates a (possibly privileged) socket for use as the ssh connection.
+  */
+ static int
+@@ -187,12 +212,18 @@ ssh_create_socket(int privileged, struct
+                           strerror(errno));
+               else
+                       debug("Allocated local port %d.", p);
++
++              if (options.tcp_rcv_buf > 0)
++                      ssh_set_socket_recvbuf(sock);           
+               return sock;
+       }
+       sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+       if (sock < 0)
+               error("socket: %.100s", strerror(errno));
++      if (options.tcp_rcv_buf > 0)
++              ssh_set_socket_recvbuf(sock);
++      
+       /* Bind the socket to an alternative local IP address */
+       if (options.bind_address == NULL)
+               return sock;
+@@ -536,7 +567,7 @@ ssh_exchange_identification(int timeout_
+       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
+           compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
+           compat20 ? PROTOCOL_MINOR_2 : minor1,
+-          SSH_VERSION, compat20 ? "\r\n" : "\n");
++          SSH_RELEASE, compat20 ? "\r\n" : "\n");
+       if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
+               fatal("write: %.100s", strerror(errno));
+       client_version_string = xstrdup(buf);
+diff -NupwB openssh-5.2p1-canonical/sshd.c openssh-5.2p1-hpn13v6/sshd.c
+--- openssh-5.2p1-canonical/sshd.c     2009-01-28 00:31:23.000000000 -0500
++++ openssh-5.2p1-hpn13v6/sshd.c       2009-05-14 12:36:10.000000000 -0400
+@@ -136,6 +136,9 @@ int deny_severity;
+ #define REEXEC_CONFIG_PASS_FD         (STDERR_FILENO + 3)
+ #define REEXEC_MIN_FREE_FD            (STDERR_FILENO + 4)
++int myflag = 0;
++
++
+ extern char *__progname;
+ /* Server configuration options. */
+@@ -415,7 +418,7 @@ sshd_exchange_identification(int sock_in
+               minor = PROTOCOL_MINOR_1;
+       }
+       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
+-          SSH_VERSION, newline);
++          SSH_RELEASE, newline);
+       server_version_string = xstrdup(buf);
+       /* Send our protocol version identification. */
+@@ -466,6 +469,9 @@ sshd_exchange_identification(int sock_in
+       }
+       debug("Client protocol version %d.%d; client software version %.100s",
+           remote_major, remote_minor, remote_version);
++      logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
++            get_remote_ipaddr(), get_remote_port(),
++          remote_major, remote_minor, remote_version);
+       compat_datafellows(remote_version);
+@@ -944,6 +950,8 @@ server_listen(void)
+       int ret, listen_sock, on = 1;
+       struct addrinfo *ai;
+       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
++      int socksize;
++      int socksizelen = sizeof(int);
+       for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
+               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+@@ -990,6 +998,11 @@ server_listen(void)
+               debug("Bind to port %s on %s.", strport, ntop);
++              getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
++                                 &socksize, &socksizelen);
++              debug("Server TCP RWIN socket size: %d", socksize);
++              debug("HPN Buffer Size: %d", options.hpn_buffer_size);
++
+               /* Bind the socket to the desired port. */
+               if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+                       error("Bind to port %s on %s failed: %.200s.",
+@@ -1817,6 +1830,9 @@ main(int ac, char **av)
+       /* Log the connection. */
+       verbose("Connection from %.500s port %d", remote_ip, remote_port);
++      /* set the HPN options for the child */
++      channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
++
+       /*
+        * We don't want to listen forever unless the other side
+        * successfully authenticates itself.  So we set up an alarm which is
+@@ -2171,9 +2187,15 @@ do_ssh2_kex(void)
+ {
+       Kex *kex;
++      myflag++;
++      debug ("MYFLAG IS %d", myflag);
+       if (options.ciphers != NULL) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
++      } else if (options.none_enabled == 1) {
++              debug ("WARNING: None cipher enabled");
++              myproposal[PROPOSAL_ENC_ALGS_CTOS] =
++              myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
+       }
+       myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+           compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
+diff -NupwB openssh-5.2p1-canonical/sshd_config openssh-5.2p1-hpn13v6/sshd_config
+--- openssh-5.2p1-canonical/sshd_config        2008-07-02 08:35:43.000000000 -0400
++++ openssh-5.2p1-hpn13v6/sshd_config  2009-05-14 12:36:10.000000000 -0400
+@@ -112,6 +112,20 @@ Protocol 2
+ # override default of no subsystems
+ Subsystem     sftp    /usr/libexec/sftp-server
++# the following are HPN related configuration options
++# tcp receive buffer polling. disable in non autotuning kernels
++#TcpRcvBufPoll yes
++ 
++# allow the use of the none cipher
++#NoneEnabled no
++
++# disable hpn performance boosts. 
++#HPNDisabled no
++
++# buffer size for hpn to non-hpn connections
++#HPNBufferSize 2048
++
++
+ # Example of overriding settings on a per-user basis
+ #Match User anoncvs
+ #     X11Forwarding no
+diff -NupwB openssh-5.2p1-canonical/version.h openssh-5.2p1-hpn13v6/version.h
+--- openssh-5.2p1-canonical/version.h  2009-02-22 19:09:26.000000000 -0500
++++ openssh-5.2p1-hpn13v6/version.h    2009-05-14 12:42:05.000000000 -0400
+@@ -3,4 +3,5 @@
+ #define SSH_VERSION   "OpenSSH_5.2"
+ #define SSH_PORTABLE  "p1"
+-#define SSH_RELEASE   SSH_VERSION SSH_PORTABLE
++#define SSH_HPN         "-hpn13v6"
++#define SSH_RELEASE   SSH_VERSION SSH_PORTABLE SSH_HPN
index c9ea239139614d6e1573232dfdd51e594d085453..f345a1cb0deb209ac3ddf1fdbba786c9751bf6fd 100644 (file)
@@ -44,8 +44,8 @@ Patch4:               %{name}-lpk.patch
 Patch5:                %{name}-config.patch
 Patch7:                %{name}-selinux.patch
 # High Performance SSH/SCP - HPN-SSH - http://www.psc.edu/networking/projects/hpn-ssh/
-# http://www.psc.edu/networking/projects/hpn-ssh/openssh-4.9p1-hpn13v2.diff.gz
-Patch9:                %{name}-5.0p1-hpn13v4.diff
+# http://www.psc.edu/networking/projects/hpn-ssh/openssh-5.2p1-hpn13v6.diff.gz
+Patch9:                %{name}-5.2p1-hpn13v6.diff
 Patch10:       %{name}-include.patch
 Patch11:       %{name}-chroot.patch
 Patch12:       http://people.debian.org/~cjwatson/%{name}-blacklist.diff
@@ -91,22 +91,13 @@ all patented algorithms to seperate libraries (OpenSSL).
 This package includes the core files necessary for both the OpenSSH
 client and server. To make this package useful, you should also
 install openssh-clients, openssh-server, or both.
-%if %{with hpn} || %{with hpn_none}
+%if %{with hpn}
 This release includes High Performance SSH/SCP patches from
 http://www.psc.edu/networking/projects/hpn-ssh/ which are supposed
 to increase throughput on fast connections with high RTT (20-150 msec).
 See the website for '-w' values for your connection and /proc/sys TCP
 values. BTW. in a LAN you have got generally RTT < 1 msec.
 %endif
-%if %{with hpn_none}
-It also includes an undocumented '-z' option which switches
-the cipher to none after authentication is completed. Data is
-still secured from tampering and corruption in transit through
-the use of the Message Authentication Code (MAC).
-This option will significantly reduce the number of cpu cycles used
-by the SSH/SCP process. This may allow some users to see significant
-improvement in (sniffable) data tranfer rates.
-%endif
 
 %description -l de.UTF-8
 OpenSSH (Secure Shell) stellt den Zugang zu anderen Rechnern her. Es
@@ -155,7 +146,7 @@ pomiędzy dwoma hostami.
 Ten pakiet zawiera podstawowe pliki potrzebne zarówno po stronie
 klienta jak i serwera OpenSSH. Aby był użyteczny, trzeba zainstalować
 co najmniej jeden z pakietów: openssh-clients lub openssh-server.
-%if %{with hpn} || %{with hpn_none}
+%if %{with hpn}
 Ta wersja zawiera łaty z projektu High Performance SSH/SCP
 http://www.psc.edu/networking/projects/hpn-ssh/, które mają na celu
 zwiększenie przepustowości transmisji dla szybkich połączeń
@@ -163,15 +154,6 @@ z dużym RTT (20-150 msec). Na stronie projektu znaleźć można
 odpowednie dla danego połączenia wartości parametru '-w' oraz
 opcje /proc/sys dla TCP. Nawiasem mówiąc w sieciach LAN RTT < 1 msec.
 %endif
-%if %{with hpn_none}
-Obsługiwana jest również nieudokumentowana opcja '-z' odpowiedzialna
-za wyłączenie szyfrowania danych po zakończeniu procesu uwierzytelniania.
-Dane są zabezpieczone przed modyfikacją lub uszkodzeniem przez
-stosowanie Message Authentication Code (MAC).
-Opcja ta znacznie redukuje liczbę cykli procesora zużywanych przez
-procesy SSH/SCP. W wybranych zastosowaniach może ona wpłynąć
-na wyraźne przyspieszenie (podsłuchiwalnej) transmisji danych.
-%endif
 
 %description -l pt.UTF-8
 OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o
@@ -328,10 +310,10 @@ Requires(postun): /usr/sbin/userdel
 Requires(pre): /bin/id
 Requires(pre): /usr/sbin/useradd
 Requires:      %{name} = %{epoch}:%{version}-%{release}
-Suggests:      /bin/login
 Requires:      pam >= 0.99.7.1
 Requires:      rc-scripts >= 0.4.1.23
 Requires:      util-linux
+Suggests:      /bin/login
 Provides:      ssh-server
 Provides:      user(sshd)
 
@@ -468,8 +450,8 @@ Requires:   openldap-servers
 This package contains OpenSSH LDAP Public Key schema for openldap.
 
 %description -n openldap-schema-openssh-lpk -l pl.UTF-8
-Ten pakiet zawiera schemat klucza publicznego LDAP dla OpenSSH
-dla openldap-a.
+Ten pakiet zawiera schemat klucza publicznego LDAP dla OpenSSH dla
+openldap-a.
 
 %prep
 %setup -q
This page took 2.128935 seconds and 4 git commands to generate.