]> git.pld-linux.org Git - packages/openssh.git/blob - openssh-4.9p1-hpn13v2.diff
- raw
[packages/openssh.git] / openssh-4.9p1-hpn13v2.diff
1 diff -NupwB openssh-4.9p1/auth2.c openssh-4.9p1-hpn13/auth2.c
2 --- openssh-4.9p1/auth2.c       2007-10-26 00:26:16.000000000 -0400
3 +++ openssh-4.9p1-hpn13/auth2.c 2008-04-01 13:03:59.000000000 -0400
4 @@ -44,6 +44,7 @@
5  #include "dispatch.h"
6  #include "pathnames.h"
7  #include "buffer.h"
8 +#include "canohost.h"
9  
10  #ifdef GSSAPI
11  #include "ssh-gss.h"
12 @@ -67,6 +68,9 @@ extern Authmethod method_hostbased;
13  extern Authmethod method_gssapi;
14  #endif
15  
16 +static int log_flag = 0;
17 +
18 +
19  Authmethod *authmethods[] = {
20         &method_none,
21         &method_pubkey,
22 @@ -150,6 +154,11 @@ input_userauth_request(int type, u_int32
23         service = packet_get_string(NULL);
24         method = packet_get_string(NULL);
25         debug("userauth-request for user %s service %s method %s", user, service, method);
26 +       if (!log_flag) {
27 +               logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
28 +                     get_remote_ipaddr(), get_remote_port(), user);
29 +               log_flag = 1;
30 +       }
31         debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
32  
33         if ((style = strchr(user, ':')) != NULL)
34 diff -NupwB openssh-4.9p1/buffer.c openssh-4.9p1-hpn13/buffer.c
35 --- openssh-4.9p1/buffer.c      2006-08-04 22:39:39.000000000 -0400
36 +++ openssh-4.9p1-hpn13/buffer.c        2008-04-01 13:03:59.000000000 -0400
37 @@ -127,7 +127,9 @@ restart:
38  
39         /* Increase the size of the buffer and retry. */
40         newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
41 -       if (newlen > BUFFER_MAX_LEN)
42 +       /* need it to be slightly larger than the MAX LEN for this */
43 +       /* still investigating *why* but this works for now -cjr */
44 +       if (newlen > (BUFFER_MAX_LEN_HPN + BUFFER_MAX_LEN)) 
45                 fatal("buffer_append_space: alloc %u not supported",
46                     newlen);
47         buffer->buf = xrealloc(buffer->buf, 1, newlen);
48 diff -NupwB openssh-4.9p1/buffer.h openssh-4.9p1-hpn13/buffer.h
49 --- openssh-4.9p1/buffer.h      2006-08-04 22:39:39.000000000 -0400
50 +++ openssh-4.9p1-hpn13/buffer.h        2008-04-01 13:03:59.000000000 -0400
51 @@ -16,6 +16,9 @@
52  #ifndef BUFFER_H
53  #define BUFFER_H
54  
55 +/* move the following to a more appropriate place and name */
56 +#define BUFFER_MAX_LEN_HPN          0x4000000  /* 64MB */
57 +
58  typedef struct {
59         u_char  *buf;           /* Buffer for data. */
60         u_int    alloc;         /* Number of bytes allocated for data. */
61 diff -NupwB openssh-4.9p1/channels.c openssh-4.9p1-hpn13/channels.c
62 --- openssh-4.9p1/channels.c    2008-02-10 06:25:24.000000000 -0500
63 +++ openssh-4.9p1-hpn13/channels.c      2008-04-01 13:03:59.000000000 -0400
64 @@ -311,6 +311,7 @@ channel_new(char *ctype, int type, int r
65         c->local_window_max = window;
66         c->local_consumed = 0;
67         c->local_maxpacket = maxpack;
68 +       c->dynamic_window = 0;
69         c->remote_id = -1;
70         c->remote_name = xstrdup(remote_name);
71         c->remote_window = 0;
72 @@ -765,11 +766,35 @@ channel_pre_open_13(Channel *c, fd_set *
73                 FD_SET(c->sock, writeset);
74  }
75  
76 +int channel_tcpwinsz () {
77 +        u_int32_t tcpwinsz = 0;
78 +        socklen_t optsz = sizeof(tcpwinsz);
79 +       int ret = -1;
80 +
81 +       /* if we aren't on a socket return 128KB*/
82 +       if(!packet_connection_is_on_socket()) 
83 +           return(128*1024);
84 +       ret = getsockopt(packet_get_connection_in(),
85 +                        SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
86 +       /* return no more than 64MB */
87 +       if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
88 +           tcpwinsz = BUFFER_MAX_LEN_HPN;
89 +       debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
90 +              packet_get_connection_in());
91 +       return(tcpwinsz);
92 +}
93 +
94  static void
95  channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
96  {
97         u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
98  
99 +        /* check buffer limits */
100 +       if ((!c->tcpwinsz) || (c->dynamic_window > 0))
101 +           c->tcpwinsz = channel_tcpwinsz();
102 +       
103 +       limit = MIN(limit, 2 * c->tcpwinsz);
104 +       
105         if (c->istate == CHAN_INPUT_OPEN &&
106             limit > 0 &&
107             buffer_len(&c->input) < limit &&
108 @@ -1661,14 +1686,21 @@ channel_check_window(Channel *c)
109             c->local_maxpacket*3) ||
110             c->local_window < c->local_window_max/2) &&
111             c->local_consumed > 0) {
112 +               u_int addition = 0;
113 +               /* adjust max window size if we are in a dynamic environment */
114 +               if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
115 +                       /* grow the window somewhat aggressively to maintain pressure */
116 +                       addition = 1.5*(c->tcpwinsz - c->local_window_max);
117 +                       c->local_window_max += addition;
118 +               }
119                 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
120                 packet_put_int(c->remote_id);
121 -               packet_put_int(c->local_consumed);
122 +               packet_put_int(c->local_consumed + addition);
123                 packet_send();
124                 debug2("channel %d: window %d sent adjust %d",
125                     c->self, c->local_window,
126                     c->local_consumed);
127 -               c->local_window += c->local_consumed;
128 +               c->local_window += c->local_consumed + addition;
129                 c->local_consumed = 0;
130         }
131         return 1;
132 @@ -1871,11 +1903,12 @@ channel_after_select(fd_set *readset, fd
133  
134  
135  /* If there is data to send to the connection, enqueue some of it now. */
136 -void
137 +int
138  channel_output_poll(void)
139  {
140         Channel *c;
141         u_int i, len;
142 +       int packet_length = 0;
143  
144         for (i = 0; i < channels_alloc; i++) {
145                 c = channels[i];
146 @@ -1915,7 +1948,7 @@ channel_output_poll(void)
147                                         packet_start(SSH2_MSG_CHANNEL_DATA);
148                                         packet_put_int(c->remote_id);
149                                         packet_put_string(data, dlen);
150 -                                       packet_send();
151 +                                       packet_length = packet_send();
152                                         c->remote_window -= dlen + 4;
153                                         xfree(data);
154                                 }
155 @@ -1945,7 +1978,7 @@ channel_output_poll(void)
156                                     SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
157                                 packet_put_int(c->remote_id);
158                                 packet_put_string(buffer_ptr(&c->input), len);
159 -                               packet_send();
160 +                               packet_length = packet_send();
161                                 buffer_consume(&c->input, len);
162                                 c->remote_window -= len;
163                         }
164 @@ -1980,12 +2013,13 @@ channel_output_poll(void)
165                         packet_put_int(c->remote_id);
166                         packet_put_int(SSH2_EXTENDED_DATA_STDERR);
167                         packet_put_string(buffer_ptr(&c->extended), len);
168 -                       packet_send();
169 +                       packet_length = packet_send();
170                         buffer_consume(&c->extended, len);
171                         c->remote_window -= len;
172                         debug2("channel %d: sent ext data %d", c->self, len);
173                 }
174         }
175 +       return (packet_length);
176  }
177  
178  
179 @@ -2342,7 +2376,8 @@ channel_set_af(int af)
180  
181  static int
182  channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
183 -    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
184 +    const char *host_to_connect, u_short port_to_connect, int gateway_ports, 
185 +    int hpn_disabled, int hpn_buffer_size)
186  {
187         Channel *c;
188         int sock, r, success = 0, wildcard = 0, is_client;
189 @@ -2456,9 +2491,15 @@ channel_setup_fwd_listener(int type, con
190                         continue;
191                 }
192                 /* Allocate a channel number for the socket. */
193 +               /* explicitly test for hpn disabled option. if true use smaller window size */
194 +               if (hpn_disabled)
195                 c = channel_new("port listener", type, sock, sock, -1,
196                     CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
197                     0, "port listener", 1);
198 +               else
199 +                       c = channel_new("port listener", type, sock, sock, -1,
200 +                         hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
201 +                         0, "port listener", 1); 
202                 strlcpy(c->path, host, sizeof(c->path));
203                 c->host_port = port_to_connect;
204                 c->listening_port = listen_port;
205 @@ -2495,20 +2536,22 @@ channel_cancel_rport_listener(const char
206  /* protocol local port fwd, used by ssh (and sshd in v1) */
207  int
208  channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
209 -    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
210 +    const char *host_to_connect, u_short port_to_connect, int gateway_ports, 
211 +    int hpn_disabled, int hpn_buffer_size)
212  {
213         return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
214             listen_host, listen_port, host_to_connect, port_to_connect,
215 -           gateway_ports);
216 +           gateway_ports, hpn_disabled, hpn_buffer_size);
217  }
218  
219  /* protocol v2 remote port fwd, used by sshd */
220  int
221  channel_setup_remote_fwd_listener(const char *listen_address,
222 -    u_short listen_port, int gateway_ports)
223 +    u_short listen_port, int gateway_ports, int hpn_disabled, int hpn_buffer_size)
224  {
225         return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
226 -           listen_address, listen_port, NULL, 0, gateway_ports);
227 +           listen_address, listen_port, NULL, 0, gateway_ports, 
228 +           hpn_disabled, hpn_buffer_size);
229  }
230  
231  /*
232 @@ -2623,7 +2666,8 @@ channel_request_rforward_cancel(const ch
233   * message if there was an error).
234   */
235  int
236 -channel_input_port_forward_request(int is_root, int gateway_ports)
237 +channel_input_port_forward_request(int is_root, int gateway_ports,
238 +                                  int hpn_disabled, int hpn_buffer_size)
239  {
240         u_short port, host_port;
241         int success = 0;
242 @@ -2649,7 +2693,7 @@ channel_input_port_forward_request(int i
243  
244         /* Initiate forwarding */
245         success = channel_setup_local_fwd_listener(NULL, port, hostname,
246 -           host_port, gateway_ports);
247 +           host_port, gateway_ports, hpn_disabled, hpn_buffer_size);
248  
249         /* Free the argument string. */
250         xfree(hostname);
251 @@ -2853,7 +2897,8 @@ channel_send_window_changes(void)
252   */
253  int
254  x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
255 -    int single_connection, u_int *display_numberp, int **chanids)
256 +    int single_connection, u_int *display_numberp, int **chanids, 
257 +    int hpn_disabled, int hpn_buffer_size)
258  {
259         Channel *nc = NULL;
260         int display_number, sock;
261 @@ -2950,10 +2995,17 @@ x11_create_display_inet(int x11_display_
262         *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
263         for (n = 0; n < num_socks; n++) {
264                 sock = socks[n];
265 +               /* Is this really necassary? */
266 +               if (hpn_disabled) 
267                 nc = channel_new("x11 listener",
268                     SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
269                     CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
270                     0, "X11 inet listener", 1);
271 +               else 
272 +                       nc = channel_new("x11 listener",
273 +                           SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
274 +                           hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
275 +                           0, "X11 inet listener", 1);
276                 nc->single_connection = single_connection;
277                 (*chanids)[n] = nc->self;
278         }
279 diff -NupwB openssh-4.9p1/channels.h openssh-4.9p1-hpn13/channels.h
280 --- openssh-4.9p1/channels.h    2007-06-12 09:38:54.000000000 -0400
281 +++ openssh-4.9p1-hpn13/channels.h      2008-04-01 13:03:59.000000000 -0400
282 @@ -98,8 +98,10 @@ struct Channel {
283         u_int   local_window_max;
284         u_int   local_consumed;
285         u_int   local_maxpacket;
286 +       int     dynamic_window;
287         int     extended_usage;
288         int     single_connection;
289 +       u_int   tcpwinsz;       
290  
291         char   *ctype;          /* type */
292  
293 @@ -122,9 +124,11 @@ struct Channel {
294  
295  /* default window/packet sizes for tcp/x11-fwd-channel */
296  #define CHAN_SES_PACKET_DEFAULT        (32*1024)
297 -#define CHAN_SES_WINDOW_DEFAULT        (64*CHAN_SES_PACKET_DEFAULT)
298 +#define CHAN_SES_WINDOW_DEFAULT        (4*CHAN_SES_PACKET_DEFAULT)
299 +
300  #define CHAN_TCP_PACKET_DEFAULT        (32*1024)
301 -#define CHAN_TCP_WINDOW_DEFAULT        (64*CHAN_TCP_PACKET_DEFAULT)
302 +#define CHAN_TCP_WINDOW_DEFAULT        (4*CHAN_TCP_PACKET_DEFAULT)
303 +
304  #define CHAN_X11_PACKET_DEFAULT        (16*1024)
305  #define CHAN_X11_WINDOW_DEFAULT        (4*CHAN_X11_PACKET_DEFAULT)
306  
307 @@ -193,7 +197,7 @@ void         channel_input_window_adjust(int, u
308  
309  void    channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
310  void     channel_after_select(fd_set *, fd_set *);
311 -void     channel_output_poll(void);
312 +int      channel_output_poll(void);
313  
314  int      channel_not_very_much_buffered_data(void);
315  void     channel_close_all(void);
316 @@ -208,21 +212,21 @@ void       channel_add_permitted_opens(char *
317  int     channel_add_adm_permitted_opens(char *, int);
318  void    channel_clear_permitted_opens(void);
319  void    channel_clear_adm_permitted_opens(void);
320 -int      channel_input_port_forward_request(int, int);
321 +int      channel_input_port_forward_request(int, int, int, int);
322  int     channel_connect_to(const char *, u_short);
323  int     channel_connect_by_listen_address(u_short);
324  int     channel_request_remote_forwarding(const char *, u_short,
325              const char *, u_short);
326  int     channel_setup_local_fwd_listener(const char *, u_short,
327 -            const char *, u_short, int);
328 +            const char *, u_short, int, int, int);
329  void    channel_request_rforward_cancel(const char *host, u_short port);
330 -int     channel_setup_remote_fwd_listener(const char *, u_short, int);
331 +int     channel_setup_remote_fwd_listener(const char *, u_short, int, int, int);
332  int     channel_cancel_rport_listener(const char *, u_short);
333  
334  /* x11 forwarding */
335  
336  int     x11_connect_display(void);
337 -int     x11_create_display_inet(int, int, int, u_int *, int **);
338 +int     x11_create_display_inet(int, int, int, u_int *, int **, int, int);
339  void     x11_input_open(int, u_int32_t, void *);
340  void    x11_request_forwarding_with_spoofing(int, const char *, const char *,
341             const char *);
342 diff -NupwB openssh-4.9p1/cipher.c openssh-4.9p1-hpn13/cipher.c
343 --- openssh-4.9p1/cipher.c      2006-08-04 22:39:39.000000000 -0400
344 +++ openssh-4.9p1-hpn13/cipher.c        2008-04-01 13:03:59.000000000 -0400
345 @@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi
346  extern const EVP_CIPHER *evp_ssh1_3des(void);
347  extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
348  extern const EVP_CIPHER *evp_aes_128_ctr(void);
349 +extern const EVP_CIPHER *evp_aes_ctr_mt(void);
350  extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
351  
352  struct Cipher {
353 @@ -81,9 +82,9 @@ struct Cipher {
354         { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
355         { "rijndael-cbc@lysator.liu.se",
356                                 SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
357 -       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
358 -       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
359 -       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
360 +       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_ctr_mt },
361 +       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_ctr_mt },
362 +       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_ctr_mt },
363  #ifdef USE_CIPHER_ACSS
364         { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
365  #endif
366 @@ -156,7 +157,8 @@ ciphers_valid(const char *names)
367         for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
368             (p = strsep(&cp, CIPHER_SEP))) {
369                 c = cipher_by_name(p);
370 -               if (c == NULL || c->number != SSH_CIPHER_SSH2) {
371 +               if (c == NULL || (c->number != SSH_CIPHER_SSH2 && 
372 +c->number != SSH_CIPHER_NONE)) {
373                         debug("bad cipher %s [%s]", p, names);
374                         xfree(cipher_list);
375                         return 0;
376 @@ -330,6 +332,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
377         int evplen;
378  
379         switch (c->number) {
380 +       case SSH_CIPHER_NONE:
381         case SSH_CIPHER_SSH2:
382         case SSH_CIPHER_DES:
383         case SSH_CIPHER_BLOWFISH:
384 @@ -364,6 +367,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
385         int evplen = 0;
386  
387         switch (c->number) {
388 +       case SSH_CIPHER_NONE:
389         case SSH_CIPHER_SSH2:
390         case SSH_CIPHER_DES:
391         case SSH_CIPHER_BLOWFISH:
392 diff -NupwB openssh-4.9p1/cipher-ctr-mt.c openssh-4.9p1-hpn13/cipher-ctr-mt.c
393 --- openssh-4.9p1/cipher-ctr-mt.c       1969-12-31 19:00:00.000000000 -0500
394 +++ openssh-4.9p1-hpn13/cipher-ctr-mt.c 2008-04-01 13:03:59.000000000 -0400
395 @@ -0,0 +1,473 @@
396 +/*
397 + * OpenSSH Multi-threaded AES-CTR Cipher
398 + *
399 + * Author: Benjamin Bennett <ben@psc.edu>
400 + * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
401 + *
402 + * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
403 + * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
404 + *
405 + * Permission to use, copy, modify, and distribute this software for any
406 + * purpose with or without fee is hereby granted, provided that the above
407 + * copyright notice and this permission notice appear in all copies.
408 + *
409 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
410 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
411 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
412 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
413 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
414 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
415 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
416 + */
417 +#include "includes.h"
418 +
419 +#include <sys/types.h>
420 +
421 +#include <stdarg.h>
422 +#include <string.h>
423 +
424 +#include <openssl/evp.h>
425 +
426 +#include "xmalloc.h"
427 +#include "log.h"
428 +
429 +/* compatibility with old or broken OpenSSL versions */
430 +#include "openbsd-compat/openssl-compat.h"
431 +
432 +#ifndef USE_BUILTIN_RIJNDAEL
433 +#include <openssl/aes.h>
434 +#endif
435 +
436 +#include <pthread.h>
437 +
438 +/*-------------------- TUNABLES --------------------*/
439 +/* Number of pregen threads to use */
440 +#define CIPHER_THREADS 2
441 +
442 +/* Number of keystream queues */
443 +#define NUMKQ          (CIPHER_THREADS + 2)
444 +
445 +/* Length of a keystream queue */
446 +#define KQLEN          4096
447 +
448 +/* Processor cacheline length */
449 +#define CACHELINE_LEN  64
450 +
451 +/* Collect thread stats and print at cancellation when in debug mode */
452 +// #define CIPHER_THREAD_STATS
453 +
454 +/* Use single-byte XOR instead of 8-byte XOR */
455 +// #define CIPHER_BYTE_XOR
456 +/*-------------------- END TUNABLES --------------------*/
457 +
458 +
459 +const EVP_CIPHER *evp_aes_ctr_mt(void);
460 +
461 +#ifdef CIPHER_THREAD_STATS
462 +/*
463 + * Struct to collect thread stats
464 + */
465 +struct thread_stats {
466 +       u_int   fills;
467 +       u_int   skips;
468 +       u_int   waits;
469 +       u_int   drains;
470 +};
471 +
472 +/*
473 + * Debug print the thread stats
474 + * Use with pthread_cleanup_push for displaying at thread cancellation
475 + */
476 +static void
477 +thread_loop_stats(void *x)
478 +{
479 +       struct thread_stats *s = x;
480 +
481 +       debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
482 +                       s->fills, s->skips, s->waits);
483 +}
484 +
485 + #define STATS_STRUCT(s)       struct thread_stats s
486 + #define STATS_INIT(s)         { memset(&s, 0, sizeof(s)); }
487 + #define STATS_FILL(s)         { s.fills++; }
488 + #define STATS_SKIP(s)         { s.skips++; }
489 + #define STATS_WAIT(s)         { s.waits++; }
490 + #define STATS_DRAIN(s)                { s.drains++; }
491 +#else
492 + #define STATS_STRUCT(s)
493 + #define STATS_INIT(s)
494 + #define STATS_FILL(s)
495 + #define STATS_SKIP(s)
496 + #define STATS_WAIT(s)
497 + #define STATS_DRAIN(s)
498 +#endif
499 +
500 +/* Keystream Queue state */
501 +enum {
502 +       KQINIT,
503 +       KQEMPTY,
504 +       KQFILLING,
505 +       KQFULL,
506 +       KQDRAINING
507 +};
508 +
509 +/* Keystream Queue struct */
510 +struct kq {
511 +       u_char          keys[KQLEN][AES_BLOCK_SIZE];
512 +       u_char          ctr[AES_BLOCK_SIZE];
513 +       u_char          pad0[CACHELINE_LEN];
514 +       volatile int    qstate;
515 +       pthread_mutex_t lock;
516 +       pthread_cond_t  cond;
517 +       u_char          pad1[CACHELINE_LEN];
518 +};
519 +
520 +/* Context struct */
521 +struct ssh_aes_ctr_ctx
522 +{
523 +       struct kq       q[NUMKQ];
524 +       AES_KEY         aes_ctx;
525 +       STATS_STRUCT(stats);
526 +       u_char          aes_counter[AES_BLOCK_SIZE];
527 +       pthread_t       tid[CIPHER_THREADS];
528 +       int             state;
529 +       int             qidx;
530 +       int             ridx;
531 +};
532 +
533 +/* <friedl>
534 + * increment counter 'ctr',
535 + * the counter is of size 'len' bytes and stored in network-byte-order.
536 + * (LSB at ctr[len-1], MSB at ctr[0])
537 + */
538 +static void
539 +ssh_ctr_inc(u_char *ctr, u_int len)
540 +{
541 +       int i;
542 +
543 +       for (i = len - 1; i >= 0; i--)
544 +               if (++ctr[i])   /* continue on overflow */
545 +                       return;
546 +}
547 +
548 +/*
549 + * Add num to counter 'ctr'
550 + */
551 +static void
552 +ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
553 +{
554 +       int i;
555 +       uint16_t n;
556 +
557 +       for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
558 +               n = ctr[i] + (num & 0xff) + n;
559 +               num >>= 8;
560 +               ctr[i] = n & 0xff;
561 +               n >>= 8;
562 +       }
563 +}
564 +
565 +/*
566 + * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
567 + */
568 +static void
569 +thread_loop_cleanup(void *x)
570 +{
571 +       pthread_mutex_unlock((pthread_mutex_t *)x);
572 +}
573 +
574 +/*
575 + * The life of a pregen thread:
576 + *    Find empty keystream queues and fill them using their counter.
577 + *    When done, update counter for the next fill.
578 + */
579 +static void *
580 +thread_loop(void *x)
581 +{
582 +       AES_KEY key;
583 +       STATS_STRUCT(stats);
584 +       struct ssh_aes_ctr_ctx *c = x;
585 +       struct kq *q;
586 +       int i;
587 +       int qidx;
588 +
589 +       /* Threads stats on cancellation */
590 +       STATS_INIT(stats);
591 +#ifdef CIPHER_THREAD_STATS
592 +       pthread_cleanup_push(thread_loop_stats, &stats);
593 +#endif
594 +
595 +       /* Thread local copy of AES key */
596 +       memcpy(&key, &c->aes_ctx, sizeof(key));
597 +
598 +       /*
599 +        * Handle the special case of startup, one thread must fill
600 +        * the first KQ then mark it as draining. Lock held throughout.
601 +        */
602 +       if (pthread_equal(pthread_self(), c->tid[0])) {
603 +               q = &c->q[0];
604 +               pthread_mutex_lock(&q->lock);
605 +               if (q->qstate == KQINIT) {
606 +                       for (i = 0; i < KQLEN; i++) {
607 +                               AES_encrypt(q->ctr, q->keys[i], &key);
608 +                               ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
609 +                       }
610 +                       ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
611 +                       q->qstate = KQDRAINING;
612 +                       STATS_FILL(stats);
613 +                       pthread_cond_broadcast(&q->cond);
614 +               }
615 +               pthread_mutex_unlock(&q->lock);
616 +       }
617 +       else 
618 +               STATS_SKIP(stats);
619 +
620 +       /*
621 +        * Normal case is to find empty queues and fill them, skipping over
622 +        * queues already filled by other threads and stopping to wait for
623 +        * a draining queue to become empty.
624 +        *
625 +        * Multiple threads may be waiting on a draining queue and awoken
626 +        * when empty.  The first thread to wake will mark it as filling,
627 +        * others will move on to fill, skip, or wait on the next queue.
628 +        */
629 +       for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
630 +               /* Check if I was cancelled, also checked in cond_wait */
631 +               pthread_testcancel();
632 +
633 +               /* Lock queue and block if its draining */
634 +               q = &c->q[qidx];
635 +               pthread_mutex_lock(&q->lock);
636 +               pthread_cleanup_push(thread_loop_cleanup, &q->lock);
637 +               while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
638 +                       STATS_WAIT(stats);
639 +                       pthread_cond_wait(&q->cond, &q->lock);
640 +               }
641 +               pthread_cleanup_pop(0);
642 +
643 +               /* If filling or full, somebody else got it, skip */
644 +               if (q->qstate != KQEMPTY) {
645 +                       pthread_mutex_unlock(&q->lock);
646 +                       STATS_SKIP(stats);
647 +                       continue;
648 +               }
649 +
650 +               /*
651 +                * Empty, let's fill it.
652 +                * Queue lock is relinquished while we do this so others
653 +                * can see that it's being filled.
654 +                */
655 +               q->qstate = KQFILLING;
656 +               pthread_mutex_unlock(&q->lock);
657 +               for (i = 0; i < KQLEN; i++) {
658 +                       AES_encrypt(q->ctr, q->keys[i], &key);
659 +                       ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
660 +               }
661 +
662 +               /* Re-lock, mark full and signal consumer */
663 +               pthread_mutex_lock(&q->lock);
664 +               ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
665 +               q->qstate = KQFULL;
666 +               STATS_FILL(stats);
667 +               pthread_cond_signal(&q->cond);
668 +               pthread_mutex_unlock(&q->lock);
669 +       }
670 +
671 +#ifdef CIPHER_THREAD_STATS
672 +       /* Stats */
673 +       pthread_cleanup_pop(1);
674 +#endif
675 +
676 +       return NULL;
677 +}
678 +
679 +static int
680 +ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
681 +    u_int len)
682 +{
683 +       struct ssh_aes_ctr_ctx *c;
684 +       struct kq *q, *oldq;
685 +       int ridx;
686 +       u_char *buf;
687 +
688 +       if (len == 0)
689 +               return (1);
690 +       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
691 +               return (0);
692 +
693 +       q = &c->q[c->qidx];
694 +       ridx = c->ridx;
695 +
696 +       /* src already padded to block multiple */
697 +       while (len > 0) {
698 +               buf = q->keys[ridx];
699 +
700 +#ifdef CIPHER_BYTE_XOR
701 +               dest[0] = src[0] ^ buf[0];
702 +               dest[1] = src[1] ^ buf[1];
703 +               dest[2] = src[2] ^ buf[2];
704 +               dest[3] = src[3] ^ buf[3];
705 +               dest[4] = src[4] ^ buf[4];
706 +               dest[5] = src[5] ^ buf[5];
707 +               dest[6] = src[6] ^ buf[6];
708 +               dest[7] = src[7] ^ buf[7];
709 +               dest[8] = src[8] ^ buf[8];
710 +               dest[9] = src[9] ^ buf[9];
711 +               dest[10] = src[10] ^ buf[10];
712 +               dest[11] = src[11] ^ buf[11];
713 +               dest[12] = src[12] ^ buf[12];
714 +               dest[13] = src[13] ^ buf[13];
715 +               dest[14] = src[14] ^ buf[14];
716 +               dest[15] = src[15] ^ buf[15];
717 +#else
718 +               *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
719 +               *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
720 +                                               *(uint64_t *)(buf + 8);
721 +#endif
722 +
723 +               dest += 16;
724 +               src += 16;
725 +               len -= 16;
726 +               ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
727 +
728 +               /* Increment read index, switch queues on rollover */
729 +               if ((ridx = (ridx + 1) % KQLEN) == 0) {
730 +                       oldq = q;
731 +
732 +                       /* Mark next queue draining, may need to wait */
733 +                       c->qidx = (c->qidx + 1) % NUMKQ;
734 +                       q = &c->q[c->qidx];
735 +                       pthread_mutex_lock(&q->lock);
736 +                       while (q->qstate != KQFULL) {
737 +                               STATS_WAIT(c->stats);
738 +                               pthread_cond_wait(&q->cond, &q->lock);
739 +                       }
740 +                       q->qstate = KQDRAINING;
741 +                       pthread_mutex_unlock(&q->lock);
742 +
743 +                       /* Mark consumed queue empty and signal producers */
744 +                       pthread_mutex_lock(&oldq->lock);
745 +                       oldq->qstate = KQEMPTY;
746 +                       STATS_DRAIN(c->stats);
747 +                       pthread_cond_broadcast(&oldq->cond);
748 +                       pthread_mutex_unlock(&oldq->lock);
749 +               }
750 +       }
751 +       c->ridx = ridx;
752 +       return (1);
753 +}
754 +
755 +#define HAVE_NONE       0
756 +#define HAVE_KEY        1
757 +#define HAVE_IV         2
758 +static int
759 +ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
760 +    int enc)
761 +{
762 +       struct ssh_aes_ctr_ctx *c;
763 +       int i;
764 +
765 +       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
766 +               c = xmalloc(sizeof(*c));
767 +
768 +               c->state = HAVE_NONE;
769 +               for (i = 0; i < NUMKQ; i++) {
770 +                       pthread_mutex_init(&c->q[i].lock, NULL);
771 +                       pthread_cond_init(&c->q[i].cond, NULL);
772 +               }
773 +
774 +               STATS_INIT(c->stats);
775 +               
776 +               EVP_CIPHER_CTX_set_app_data(ctx, c);
777 +       }
778 +
779 +       if (c->state == (HAVE_KEY | HAVE_IV)) {
780 +               /* Cancel pregen threads */
781 +               for (i = 0; i < CIPHER_THREADS; i++)
782 +                       pthread_cancel(c->tid[i]);
783 +               for (i = 0; i < CIPHER_THREADS; i++)
784 +                       pthread_join(c->tid[i], NULL);
785 +               /* Start over getting key & iv */
786 +               c->state = HAVE_NONE;
787 +       }
788 +
789 +       if (key != NULL) {
790 +               AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
791 +                   &c->aes_ctx);
792 +               c->state |= HAVE_KEY;
793 +       }
794 +
795 +       if (iv != NULL) {
796 +               memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
797 +               c->state |= HAVE_IV;
798 +       }
799 +
800 +       if (c->state == (HAVE_KEY | HAVE_IV)) {
801 +               /* Clear queues */
802 +               memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
803 +               c->q[0].qstate = KQINIT;
804 +               for (i = 1; i < NUMKQ; i++) {
805 +                       memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
806 +                       ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
807 +                       c->q[i].qstate = KQEMPTY;
808 +               }
809 +               c->qidx = 0;
810 +               c->ridx = 0;
811 +
812 +               /* Start threads */
813 +               for (i = 0; i < CIPHER_THREADS; i++) {
814 +                       pthread_create(&c->tid[i], NULL, thread_loop, c);
815 +               }
816 +               pthread_mutex_lock(&c->q[0].lock);
817 +               while (c->q[0].qstate != KQDRAINING)
818 +                       pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
819 +               pthread_mutex_unlock(&c->q[0].lock);
820 +               
821 +       }
822 +       return (1);
823 +}
824 +
825 +static int
826 +ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
827 +{
828 +       struct ssh_aes_ctr_ctx *c;
829 +       int i;
830 +
831 +       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
832 +#ifdef CIPHER_THREAD_STATS
833 +               debug("main thread: %u drains, %u waits", c->stats.drains,
834 +                               c->stats.waits);
835 +#endif
836 +               /* Cancel pregen threads */
837 +               for (i = 0; i < CIPHER_THREADS; i++)
838 +                       pthread_cancel(c->tid[i]);
839 +               for (i = 0; i < CIPHER_THREADS; i++)
840 +                       pthread_join(c->tid[i], NULL);
841 +
842 +               memset(c, 0, sizeof(*c));
843 +               xfree(c);
844 +               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
845 +       }
846 +       return (1);
847 +}
848 +
849 +/* <friedl> */
850 +const EVP_CIPHER *
851 +evp_aes_ctr_mt(void)
852 +{
853 +       static EVP_CIPHER aes_ctr;
854 +
855 +       memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
856 +       aes_ctr.nid = NID_undef;
857 +       aes_ctr.block_size = AES_BLOCK_SIZE;
858 +       aes_ctr.iv_len = AES_BLOCK_SIZE;
859 +       aes_ctr.key_len = 16;
860 +       aes_ctr.init = ssh_aes_ctr_init;
861 +       aes_ctr.cleanup = ssh_aes_ctr_cleanup;
862 +       aes_ctr.do_cipher = ssh_aes_ctr;
863 +#ifndef SSH_OLD_EVP
864 +       aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
865 +           EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
866 +#endif
867 +       return (&aes_ctr);
868 +}
869 diff -NupwB openssh-4.9p1/clientloop.c openssh-4.9p1-hpn13/clientloop.c
870 --- openssh-4.9p1/clientloop.c  2008-03-07 02:33:30.000000000 -0500
871 +++ openssh-4.9p1-hpn13/clientloop.c    2008-04-01 13:17:11.000000000 -0400
872 @@ -923,13 +923,16 @@ client_process_control(fd_set *readset)
873  
874         set_nonblock(client_fd);
875  
876 +       if (options.hpn_disabled) 
877         window = CHAN_SES_WINDOW_DEFAULT;
878 +       else
879 +         window = options.hpn_buffer_size;
880 +
881         packetmax = CHAN_SES_PACKET_DEFAULT;
882         if (cctx->want_tty) {
883                 window >>= 1;
884                 packetmax >>= 1;
885         }
886 -       
887         c = channel_new("session", SSH_CHANNEL_OPENING,
888             new_fd[0], new_fd[1], new_fd[2], window, packetmax,
889             CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
890 @@ -1034,7 +1037,8 @@ process_cmdline(void)
891                 if (local) {
892                         if (channel_setup_local_fwd_listener(fwd.listen_host,
893                             fwd.listen_port, fwd.connect_host,
894 -                           fwd.connect_port, options.gateway_ports) < 0) {
895 +                           fwd.connect_port, options.gateway_ports, 
896 +                           options.hpn_disabled, options.hpn_buffer_size) < 0) {
897                                 logit("Port forwarding failed.");
898                                 goto out;
899                         }
900 @@ -1737,9 +1741,15 @@ client_request_forwarded_tcpip(const cha
901                 xfree(listen_address);
902                 return NULL;
903         }
904 +       if (options.hpn_disabled) 
905         c = channel_new("forwarded-tcpip",
906             SSH_CHANNEL_CONNECTING, sock, sock, -1,
907 -           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
908 +                   CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
909 +                   originator_address, 1);
910 +       else
911 +               c = channel_new("forwarded-tcpip",
912 +                   SSH_CHANNEL_CONNECTING, sock, sock, -1,
913 +                   options.hpn_buffer_size, options.hpn_buffer_size, 0,
914             originator_address, 1);
915         xfree(originator_address);
916         xfree(listen_address);
917 @@ -1774,9 +1784,15 @@ client_request_x11(const char *request_t
918         sock = x11_connect_display();
919         if (sock < 0)
920                 return NULL;
921 +       /* again is this really necessary for X11? */
922 +       if (options.hpn_disabled) 
923         c = channel_new("x11",
924             SSH_CHANNEL_X11_OPEN, sock, sock, -1,
925             CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
926 +       else 
927 +               c = channel_new("x11",
928 +                   SSH_CHANNEL_X11_OPEN, sock, sock, -1,
929 +                   options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
930         c->force_drain = 1;
931         return c;
932  }
933 @@ -1795,9 +1811,15 @@ client_request_agent(const char *request
934         sock = ssh_get_authentication_socket();
935         if (sock < 0)
936                 return NULL;
937 +       if (options.hpn_disabled) 
938 +               c = channel_new("authentication agent connection",
939 +                   SSH_CHANNEL_OPEN, sock, sock, -1,
940 +                   CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
941 +                   "authentication agent connection", 1);
942 +       else
943         c = channel_new("authentication agent connection",
944             SSH_CHANNEL_OPEN, sock, sock, -1,
945 -           CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
946 +                   options.hpn_buffer_size, options.hpn_buffer_size, 0,
947             "authentication agent connection", 1);
948         c->force_drain = 1;
949         return c;
950 @@ -1825,10 +1847,18 @@ client_request_tun_fwd(int tun_mode, int
951                 return -1;
952         }
953  
954 +       if(options.hpn_disabled)
955         c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
956 -           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
957 +                               CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
958 +                               0, "tun", 1);
959 +       else
960 +       c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
961 +                               options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
962 +                               0, "tun", 1);
963         c->datagram = 1;
964  
965 +
966 +
967  #if defined(SSH_TUN_FILTER)
968         if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
969                 channel_register_filter(c->self, sys_tun_infilter,
970 diff -NupwB openssh-4.9p1/compat.c openssh-4.9p1-hpn13/compat.c
971 --- openssh-4.9p1/compat.c      2007-01-05 00:26:46.000000000 -0500
972 +++ openssh-4.9p1-hpn13/compat.c        2008-04-01 13:03:59.000000000 -0400
973 @@ -169,6 +169,15 @@ compat_datafellows(const char *version)
974                     strlen(check[i].pat), 0) == 1) {
975                         debug("match: %s pat %s", version, check[i].pat);
976                         datafellows = check[i].bugs;
977 +                       /* Check to see if the remote side is OpenSSH and not HPN */
978 +                       if(strstr(version,"OpenSSH") != NULL)
979 +                       {
980 +                               if (strstr(version,"hpn") == NULL)
981 +                               {
982 +                                       datafellows |= SSH_BUG_LARGEWINDOW;
983 +                                       debug("Remote is NON-HPN aware");
984 +                               }
985 +                       }
986                         return;
987                 }
988         }
989 diff -NupwB openssh-4.9p1/compat.h openssh-4.9p1-hpn13/compat.h
990 --- openssh-4.9p1/compat.h      2007-01-05 00:26:46.000000000 -0500
991 +++ openssh-4.9p1-hpn13/compat.h        2008-04-01 13:03:59.000000000 -0400
992 @@ -57,6 +57,7 @@
993  #define SSH_BUG_FIRSTKEX       0x00800000
994  #define SSH_OLD_FORWARD_ADDR   0x01000000
995  #define SSH_BUG_RFWD_ADDR      0x02000000
996 +#define SSH_BUG_LARGEWINDOW     0x04000000
997  
998  void     enable_compat13(void);
999  void     enable_compat20(void);
1000 Common subdirectories: openssh-4.9p1/contrib and openssh-4.9p1-hpn13/contrib
1001 diff -NupwB openssh-4.9p1/HPN-README openssh-4.9p1-hpn13/HPN-README
1002 --- openssh-4.9p1/HPN-README    1969-12-31 19:00:00.000000000 -0500
1003 +++ openssh-4.9p1-hpn13/HPN-README      2008-04-01 13:37:46.000000000 -0400
1004 @@ -0,0 +1,128 @@
1005 +Notes:
1006 +
1007 +MULTI-THREADED CIPHER:
1008 +The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
1009 +on hosts with multiple cores to use more than one processing core during encryption. 
1010 +Tests have show significant throughput performance increases when using MTR-AES-CTR up 
1011 +to and including a full gigabit per second on quad core systems. It should be possible to 
1012 +achieve full line rate on dual core systems but OS and data management overhead makes this
1013 +more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single 
1014 +thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal 
1015 +performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. 
1016 +The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
1017 +nomenclature. 
1018 +Use examples:  ssh -caes128-ctr you@host.com
1019 +               scp -oCipher=aes256-ctr file you@host.com:~/file
1020 +
1021 +NONE CIPHER:
1022 +To use the NONE option you must have the NoneEnabled switch set on the server and
1023 +you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
1024 +feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not 
1025 +spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
1026 +be disabled. 
1027 +
1028 +The performance increase will only be as good as the network and TCP stack tuning
1029 +on the reciever side of the connection allows. As a rule of thumb a user will need 
1030 +at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
1031 +HPN-SSH home page describes this in greater detail. 
1032 +
1033 +http://www.psc.edu/networking/projects/hpn-ssh
1034 +
1035 +BUFFER SIZES:
1036 +
1037 +If HPN is disabled the receive buffer size will be set to the 
1038 +OpenSSH default of 64K.
1039 +
1040 +If an HPN system connects to a nonHPN system the receive buffer will
1041 +be set to the HPNBufferSize value. The default is 2MB but user adjustable.
1042 +
1043 +If an HPN to HPN connection is established a number of different things might
1044 +happen based on the user options and conditions. 
1045 +
1046 +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set 
1047 +HPN Buffer Size = up to 64MB 
1048 +This is the default state. The HPN buffer size will grow to a maximum of 64MB 
1049 +as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is 
1050 +geared towards 10GigE transcontinental connections. 
1051 +
1052 +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
1053 +HPN Buffer Size = TCP receive buffer value. 
1054 +Users on non-autotuning systesm should disable TCPRcvBufPoll in the 
1055 +ssh_cofig and sshd_config
1056 +
1057 +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
1058 +HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. 
1059 +This would be the system defined TCP receive buffer (RWIN).
1060 +
1061 +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
1062 +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
1063 +Generally there is no need to set both.
1064 +
1065 +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
1066 +HPN Buffer Size = grows to HPNBufferSize
1067 +The buffer will grow up to the maximum size specified here. 
1068 +
1069 +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
1070 +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
1071 +Generally there is no need to set both of these, especially on autotuning 
1072 +systems. However, if the users wishes to override the autotuning this would be 
1073 +one way to do it.
1074 +
1075 +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
1076 +HPN Buffer Size = TCPRcvBuf. 
1077 +This will override autotuning and set the TCP recieve buffer to the user defined 
1078 +value.
1079 +
1080 +
1081 +HPN Specific Configuration options
1082 +
1083 +TcpRcvBuf=[int]KB client
1084 +      set the TCP socket receive buffer to n Kilobytes. It can be set up to the 
1085 +maximum socket size allowed by the system. This is useful in situations where 
1086 +the tcp receive window is set low but the maximum buffer size is set 
1087 +higher (as is typical). This works on a per TCP connection basis. You can also 
1088 +use this to artifically limit the transfer rate of the connection. In these 
1089 +cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. 
1090 +Default is the current system wide tcp receive buffer size.
1091 +
1092 +TcpRcvBufPoll=[yes/no] client/server
1093 +      enable of disable the polling of the tcp receive buffer through the life 
1094 +of the connection. You would want to make sure that this option is enabled 
1095 +for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) 
1096 +default is yes.
1097 +
1098 +NoneEnabled=[yes/no] client/server
1099 +      enable or disable the use of the None cipher. Care must always be used 
1100 +when enabling this as it will allow users to send data in the clear. However, 
1101 +it is important to note that authentication information remains encrypted 
1102 +even if this option is enabled. Set to no by default.
1103 +
1104 +NoneSwitch=[yes/no] client
1105 +     Switch the encryption cipher being used to the None cipher after
1106 +authentication takes place. NoneEnabled must be enabled on both the client
1107 +and server side of the connection. When the connection switches to the NONE
1108 +cipher a warning is sent to STDERR. The connection attempt will fail with an
1109 +error if a client requests a NoneSwitch from the server that does not explicitly
1110 +have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
1111 +interactive (shell) sessions and it will fail silently. Set to no by default.
1112 +
1113 +HPNDisabled=[yes/no] client/server
1114 +     In some situations, such as transfers on a local area network, the impact 
1115 +of the HPN code produces a net decrease in performance. In these cases it is 
1116 +helpful to disable the HPN functionality. By default HPNDisabled is set to no. 
1117 +
1118 +HPNBufferSize=[int]KB client/server
1119 +     This is the default buffer size the HPN functionality uses when interacting
1120 +with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
1121 +option as applied to the internal SSH flow control. This value can range from 
1122 +1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
1123 +problems depending on the length of the network path. The default size of this buffer
1124 +is 2MB.
1125 +
1126 +
1127 +Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
1128 +         The majority of the actual coding for versions up to HPN12v1 was performed
1129 +         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was 
1130 +        implemented by Ben Bennet (ben@psc.edu). This work was financed, in part,
1131 +         by Cisco System, Inc., the National Library of Medicine, 
1132 +        and the National Science Foundation. 
1133 diff -NupwB openssh-4.9p1/kex.c openssh-4.9p1-hpn13/kex.c
1134 --- openssh-4.9p1/kex.c 2007-06-05 04:30:18.000000000 -0400
1135 +++ openssh-4.9p1-hpn13/kex.c   2008-04-01 13:03:59.000000000 -0400
1136 @@ -48,6 +48,7 @@
1137  #include "match.h"
1138  #include "dispatch.h"
1139  #include "monitor.h"
1140 +#include "canohost.h"
1141  
1142  #define KEX_COOKIE_LEN 16
1143  
1144 @@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
1145  static void kex_choose_conf(Kex *);
1146  
1147  /* put algorithm proposal into buffer */
1148 -static void
1149 +/* used in sshconnect.c as well as kex.c */
1150 +void
1151  kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
1152  {
1153         u_int i;
1154 @@ -376,6 +378,13 @@ kex_choose_conf(Kex *kex)
1155         int nenc, nmac, ncomp;
1156         u_int mode, ctos, need;
1157         int first_kex_follows, type;
1158 +       int log_flag = 0;
1159 +
1160 +       int auth_flag;
1161 +
1162 +       auth_flag = packet_authentication_state();
1163 +
1164 +       debug ("AUTH STATE IS %d", auth_flag);
1165  
1166         my   = kex_buf2prop(&kex->my, NULL);
1167         peer = kex_buf2prop(&kex->peer, &first_kex_follows);
1168 @@ -400,11 +409,34 @@ kex_choose_conf(Kex *kex)
1169                 choose_enc (&newkeys->enc,  cprop[nenc],  sprop[nenc]);
1170                 choose_mac (&newkeys->mac,  cprop[nmac],  sprop[nmac]);
1171                 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
1172 +               debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
1173 +               if (strcmp(newkeys->enc.name, "none") == 0) {
1174 +                               debug("Requesting NONE. Authflag is %d", auth_flag);                    
1175 +                       if (auth_flag == 1) {
1176 +                               debug("None requested post authentication.");
1177 +                       } else {
1178 +                               fatal("Pre-authentication none cipher requests are not allowed.");
1179 +                       }
1180 +               } 
1181                 debug("kex: %s %s %s %s",
1182                     ctos ? "client->server" : "server->client",
1183                     newkeys->enc.name,
1184                     newkeys->mac.name,
1185                     newkeys->comp.name);
1186 +               /* client starts withctos = 0 && log flag = 0 and no log*/
1187 +               /* 2nd client pass ctos=1 and flag = 1 so no log*/
1188 +               /* server starts with ctos =1 && log_flag = 0 so log */
1189 +               /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
1190 +               /* -cjr*/
1191 +               if (ctos && !log_flag) {
1192 +                       logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
1193 +                             get_remote_ipaddr(),
1194 +                             get_remote_port(),
1195 +                             newkeys->enc.name,
1196 +                             newkeys->mac.name,
1197 +                             newkeys->comp.name);
1198 +               }
1199 +               log_flag = 1;
1200         }
1201         choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
1202         choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
1203 diff -NupwB openssh-4.9p1/kex.h openssh-4.9p1-hpn13/kex.h
1204 --- openssh-4.9p1/kex.h 2007-06-11 00:01:42.000000000 -0400
1205 +++ openssh-4.9p1-hpn13/kex.h   2008-04-01 13:03:59.000000000 -0400
1206 @@ -127,6 +127,8 @@ struct Kex {
1207         void    (*kex[KEX_MAX])(Kex *);
1208  };
1209  
1210 +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
1211 +
1212  Kex    *kex_setup(char *[PROPOSAL_MAX]);
1213  void    kex_finish(Kex *);
1214  
1215 diff -NupwB openssh-4.9p1/Makefile.in openssh-4.9p1-hpn13/Makefile.in
1216 --- openssh-4.9p1/Makefile.in   2008-03-12 21:41:31.000000000 -0400
1217 +++ openssh-4.9p1-hpn13/Makefile.in     2008-04-01 13:03:59.000000000 -0400
1218 @@ -43,7 +43,7 @@ CC=@CC@
1219  LD=@LD@
1220  CFLAGS=@CFLAGS@
1221  CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
1222 -LIBS=@LIBS@
1223 +LIBS=@LIBS@ -lpthread
1224  SSHDLIBS=@SSHDLIBS@
1225  LIBEDIT=@LIBEDIT@
1226  AR=@AR@
1227 @@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
1228  
1229  LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
1230         canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
1231 -       cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
1232 +       cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
1233         compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
1234         log.o match.o md-sha256.o moduli.o nchan.o packet.o \
1235         readpass.o rsa.o ttymodes.o xmalloc.o \
1236 diff -NupwB openssh-4.9p1/myproposal.h openssh-4.9p1-hpn13/myproposal.h
1237 --- openssh-4.9p1/myproposal.h  2007-06-11 00:01:42.000000000 -0400
1238 +++ openssh-4.9p1-hpn13/myproposal.h    2008-04-01 13:03:59.000000000 -0400
1239 @@ -46,6 +46,8 @@
1240         "arcfour128,arcfour256,arcfour," \
1241         "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
1242         "aes128-ctr,aes192-ctr,aes256-ctr"
1243 +#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
1244 +       ",none"
1245  #define        KEX_DEFAULT_MAC \
1246         "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
1247         "hmac-ripemd160@openssh.com," \
1248 Common subdirectories: openssh-4.9p1/openbsd-compat and openssh-4.9p1-hpn13/openbsd-compat
1249 diff -NupwB openssh-4.9p1/packet.c openssh-4.9p1-hpn13/packet.c
1250 --- openssh-4.9p1/packet.c      2008-03-07 02:33:30.000000000 -0500
1251 +++ openssh-4.9p1-hpn13/packet.c        2008-04-01 13:03:59.000000000 -0400
1252 @@ -712,7 +712,7 @@ packet_enable_delayed_compress(void)
1253  /*
1254   * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
1255   */
1256 -static void
1257 +static int
1258  packet_send2_wrapped(void)
1259  {
1260         u_char type, *cp, *macbuf = NULL;
1261 @@ -824,11 +824,13 @@ packet_send2_wrapped(void)
1262                 set_newkeys(MODE_OUT);
1263         else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
1264                 packet_enable_delayed_compress();
1265 +       return(packet_length);
1266  }
1267  
1268 -static void
1269 +static int
1270  packet_send2(void)
1271  {
1272 +        static int packet_length = 0;
1273         static int rekeying = 0;
1274         struct packet *p;
1275         u_char type, *cp;
1276 @@ -846,7 +848,7 @@ packet_send2(void)
1277                         memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
1278                         buffer_init(&outgoing_packet);
1279                         TAILQ_INSERT_TAIL(&outgoing, p, next);
1280 -                       return;
1281 +                       return(sizeof(Buffer));
1282                 }
1283         }
1284  
1285 @@ -854,7 +856,7 @@ packet_send2(void)
1286         if (type == SSH2_MSG_KEXINIT)
1287                 rekeying = 1;
1288  
1289 -       packet_send2_wrapped();
1290 +       packet_length = packet_send2_wrapped();
1291  
1292         /* after a NEWKEYS message we can send the complete queue */
1293         if (type == SSH2_MSG_NEWKEYS) {
1294 @@ -867,19 +869,22 @@ packet_send2(void)
1295                             sizeof(Buffer));
1296                         TAILQ_REMOVE(&outgoing, p, next);
1297                         xfree(p);
1298 -                       packet_send2_wrapped();
1299 +                       packet_length += packet_send2_wrapped();
1300                 }
1301         }
1302 +       return(packet_length);
1303  }
1304  
1305 -void
1306 +int
1307  packet_send(void)
1308  {
1309 +  int packet_len = 0;
1310         if (compat20)
1311 -               packet_send2();
1312 +               packet_len = packet_send2();
1313         else
1314                 packet_send1();
1315         DBG(debug("packet_send done"));
1316 +       return(packet_len);
1317  }
1318  
1319  /*
1320 @@ -1419,21 +1424,23 @@ packet_disconnect(const char *fmt,...)
1321  
1322  /* Checks if there is any buffered output, and tries to write some of the output. */
1323  
1324 -void
1325 +int
1326  packet_write_poll(void)
1327  {
1328 -       int len = buffer_len(&output);
1329 +       int len = 0;
1330 +       len = buffer_len(&output);
1331  
1332         if (len > 0) {
1333                 len = write(connection_out, buffer_ptr(&output), len);
1334                 if (len <= 0) {
1335                         if (errno == EAGAIN)
1336 -                               return;
1337 +                         return (0);
1338                         else
1339                                 fatal("Write failed: %.100s", strerror(errno));
1340                 }
1341                 buffer_consume(&output, len);
1342         }
1343 +       return(len);
1344  }
1345  
1346  /*
1347 @@ -1441,14 +1448,15 @@ packet_write_poll(void)
1348   * written.
1349   */
1350  
1351 -void
1352 +int
1353  packet_write_wait(void)
1354  {
1355         fd_set *setp;
1356 +       u_int bytes_sent = 0;
1357  
1358         setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
1359             sizeof(fd_mask));
1360 -       packet_write_poll();
1361 +       bytes_sent += packet_write_poll();
1362         while (packet_have_data_to_write()) {
1363                 memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1364                     sizeof(fd_mask));
1365 @@ -1456,9 +1464,10 @@ packet_write_wait(void)
1366                 while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
1367                     (errno == EAGAIN || errno == EINTR))
1368                         ;
1369 -               packet_write_poll();
1370 +               bytes_sent += packet_write_poll();
1371         }
1372         xfree(setp);
1373 +       return (bytes_sent);
1374  }
1375  
1376  /* Returns true if there is buffered data to write to the connection. */
1377 @@ -1580,12 +1589,24 @@ packet_send_ignore(int nbytes)
1378         }
1379  }
1380  
1381 +int rekey_requested = 0;
1382 +void
1383 +packet_request_rekeying(void)
1384 +{
1385 +       rekey_requested = 1;
1386 +}
1387 +
1388  #define MAX_PACKETS    (1U<<31)
1389  int
1390  packet_need_rekeying(void)
1391  {
1392         if (datafellows & SSH_BUG_NOREKEY)
1393                 return 0;
1394 +       if (rekey_requested == 1)
1395 +       {
1396 +               rekey_requested = 0;
1397 +               return 1;
1398 +       }
1399         return
1400             (p_send.packets > MAX_PACKETS) ||
1401             (p_read.packets > MAX_PACKETS) ||
1402 @@ -1610,3 +1631,9 @@ packet_set_authenticated(void)
1403  {
1404         after_authentication = 1;
1405  }
1406 +
1407 +int
1408 +packet_authentication_state(void)
1409 +{
1410 +       return(after_authentication);
1411 +}
1412 diff -NupwB openssh-4.9p1/packet.h openssh-4.9p1-hpn13/packet.h
1413 --- openssh-4.9p1/packet.h      2008-03-07 02:33:30.000000000 -0500
1414 +++ openssh-4.9p1-hpn13/packet.h        2008-04-01 13:03:59.000000000 -0400
1415 @@ -20,6 +20,9 @@
1416  
1417  #include <openssl/bn.h>
1418  
1419 +void
1420 +packet_request_rekeying(void);
1421 +
1422  void     packet_set_connection(int, int);
1423  void     packet_set_nonblocking(void);
1424  int      packet_get_connection_in(void);
1425 @@ -34,6 +37,7 @@ void     packet_set_interactive(int);
1426  int      packet_is_interactive(void);
1427  void     packet_set_server(void);
1428  void     packet_set_authenticated(void);
1429 +int     packet_authentication_state(void);
1430  
1431  void     packet_start(u_char);
1432  void     packet_put_char(int ch);
1433 @@ -43,7 +47,7 @@ void     packet_put_bignum2(BIGNUM * val
1434  void     packet_put_string(const void *buf, u_int len);
1435  void     packet_put_cstring(const char *str);
1436  void     packet_put_raw(const void *buf, u_int len);
1437 -void     packet_send(void);
1438 +int      packet_send(void);
1439  
1440  int      packet_read(void);
1441  void     packet_read_expect(int type);
1442 @@ -71,8 +75,8 @@ void   packet_set_state(int, u_int32_t, u
1443  int     packet_get_ssh1_cipher(void);
1444  void    packet_set_iv(int, u_char *);
1445  
1446 -void     packet_write_poll(void);
1447 -void     packet_write_wait(void);
1448 +int      packet_write_poll(void);
1449 +int      packet_write_wait(void);
1450  int      packet_have_data_to_write(void);
1451  int      packet_not_very_much_data_to_write(void);
1452  
1453 diff -NupwB openssh-4.9p1/progressmeter.c openssh-4.9p1-hpn13/progressmeter.c
1454 --- openssh-4.9p1/progressmeter.c       2006-08-04 22:39:40.000000000 -0400
1455 +++ openssh-4.9p1-hpn13/progressmeter.c 2008-04-01 14:31:59.000000000 -0400
1456 @@ -68,6 +68,8 @@ static time_t last_update;    /* last progr
1457  static char *file;             /* name of the file being transferred */
1458  static off_t end_pos;          /* ending position of transfer */
1459  static off_t cur_pos;          /* transfer position as of last refresh */
1460 +static off_t last_pos;
1461 +static off_t max_delta_pos = 0;
1462  static volatile off_t *counter;        /* progress counter */
1463  static long stalled;           /* how long we have been stalled */
1464  static int bytes_per_second;   /* current speed in bytes per second */
1465 @@ -128,12 +130,17 @@ refresh_progress_meter(void)
1466         int hours, minutes, seconds;
1467         int i, len;
1468         int file_len;
1469 +       off_t delta_pos;
1470  
1471         transferred = *counter - cur_pos;
1472         cur_pos = *counter;
1473         now = time(NULL);
1474         bytes_left = end_pos - cur_pos;
1475  
1476 +       delta_pos = cur_pos - last_pos;
1477 +       if (delta_pos > max_delta_pos) 
1478 +               max_delta_pos = delta_pos;
1479 +
1480         if (bytes_left > 0)
1481                 elapsed = now - last_update;
1482         else {
1483 @@ -158,7 +165,7 @@ refresh_progress_meter(void)
1484  
1485         /* filename */
1486         buf[0] = '\0';
1487 -       file_len = win_size - 35;
1488 +       file_len = win_size - 45;
1489         if (file_len > 0) {
1490                 len = snprintf(buf, file_len + 1, "\r%s", file);
1491                 if (len < 0)
1492 @@ -175,7 +182,8 @@ refresh_progress_meter(void)
1493                 percent = ((float)cur_pos / end_pos) * 100;
1494         else
1495                 percent = 100;
1496 -       snprintf(buf + strlen(buf), win_size - strlen(buf),
1497 +
1498 +       snprintf(buf + strlen(buf), win_size - strlen(buf-8),
1499             " %3d%% ", percent);
1500  
1501         /* amount transferred */
1502 @@ -188,6 +196,11 @@ refresh_progress_meter(void)
1503             (off_t)bytes_per_second);
1504         strlcat(buf, "/s ", win_size);
1505  
1506 +       /* instantaneous rate */
1507 +       format_rate(buf + strlen(buf), win_size - strlen(buf),
1508 +           delta_pos);
1509 +       strlcat(buf, "/s ", win_size);
1510 +
1511         /* ETA */
1512         if (!transferred)
1513                 stalled += elapsed;
1514 @@ -224,6 +237,7 @@ refresh_progress_meter(void)
1515  
1516         atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
1517         last_update = now;
1518 +       last_pos = cur_pos;
1519  }
1520  
1521  /*ARGSUSED*/
1522 @@ -270,6 +284,7 @@ void
1523  stop_progress_meter(void)
1524  {
1525         alarm(0);
1526 +       char lbuf[10];
1527  
1528         if (!can_output())
1529                 return;
1530 @@ -278,6 +293,8 @@ stop_progress_meter(void)
1531         if (cur_pos != end_pos)
1532                 refresh_progress_meter();
1533  
1534 +       format_rate(lbuf, sizeof(lbuf), max_delta_pos);
1535 +       printf("\nMax throughput: %s/s\n", lbuf);
1536         atomicio(vwrite, STDOUT_FILENO, "\n", 1);
1537  }
1538  
1539 diff -NupwB openssh-4.9p1/readconf.c openssh-4.9p1-hpn13/readconf.c
1540 --- openssh-4.9p1/readconf.c    2008-02-10 06:25:52.000000000 -0500
1541 +++ openssh-4.9p1-hpn13/readconf.c      2008-04-01 13:03:59.000000000 -0400
1542 @@ -130,6 +130,8 @@ typedef enum {
1543         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
1544         oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
1545         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
1546 +       oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
1547 +       oHPNBufferSize,
1548         oDeprecated, oUnsupported
1549  } OpCodes;
1550  
1551 @@ -226,6 +228,12 @@ static struct {
1552         { "tunneldevice", oTunnelDevice },
1553         { "localcommand", oLocalCommand },
1554         { "permitlocalcommand", oPermitLocalCommand },
1555 +        { "noneenabled", oNoneEnabled },
1556 +        { "tcprcvbufpoll", oTcpRcvBufPoll },
1557 +        { "tcprcvbuf", oTcpRcvBuf },
1558 +        { "noneswitch", oNoneSwitch },
1559 +       { "hpndisabled", oHPNDisabled },
1560 +       { "hpnbuffersize", oHPNBufferSize },
1561         { NULL, oBadOption }
1562  };
1563  
1564 @@ -454,6 +462,37 @@ parse_flag:
1565                 intptr = &options->check_host_ip;
1566                 goto parse_flag;
1567  
1568 +       case oNoneEnabled:
1569 +               intptr = &options->none_enabled;
1570 +               goto parse_flag;
1571
1572 +       /* we check to see if the command comes from the */
1573 +       /* command line or not. If it does then enable it */
1574 +       /* otherwise fail. NONE should never be a default configuration */
1575 +       case oNoneSwitch:
1576 +               if(strcmp(filename,"command-line")==0)
1577 +               {               
1578 +                   intptr = &options->none_switch;
1579 +                   goto parse_flag;
1580 +               } else {
1581 +                   error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
1582 +                   error("Continuing...");
1583 +                   debug("NoneSwitch directive found in %.200s.", filename);
1584 +                   return 0;
1585 +               }
1586 +
1587 +       case oHPNDisabled:
1588 +               intptr = &options->hpn_disabled;
1589 +               goto parse_flag;
1590 +
1591 +       case oHPNBufferSize:
1592 +               intptr = &options->hpn_buffer_size;
1593 +               goto parse_int;
1594 +
1595 +       case oTcpRcvBufPoll:
1596 +               intptr = &options->tcp_rcv_buf_poll;
1597 +               goto parse_flag;
1598 +
1599         case oVerifyHostKeyDNS:
1600                 intptr = &options->verify_host_key_dns;
1601                 goto parse_yesnoask;
1602 @@ -632,6 +671,10 @@ parse_int:
1603                 intptr = &options->connection_attempts;
1604                 goto parse_int;
1605  
1606 +       case oTcpRcvBuf:
1607 +               intptr = &options->tcp_rcv_buf;
1608 +               goto parse_int;
1609 +
1610         case oCipher:
1611                 intptr = &options->cipher;
1612                 arg = strdelim(&s);
1613 @@ -1065,6 +1108,12 @@ initialize_options(Options * options)
1614         options->tun_remote = -1;
1615         options->local_command = NULL;
1616         options->permit_local_command = -1;
1617 +       options->none_switch = -1;
1618 +       options->none_enabled = -1;
1619 +       options->hpn_disabled = -1;
1620 +       options->hpn_buffer_size = -1;
1621 +       options->tcp_rcv_buf_poll = -1;
1622 +       options->tcp_rcv_buf = -1;
1623  }
1624  
1625  /*
1626 @@ -1187,6 +1236,29 @@ fill_default_options(Options * options)
1627                 options->server_alive_interval = 0;
1628         if (options->server_alive_count_max == -1)
1629                 options->server_alive_count_max = 3;
1630 +       if (options->none_switch == -1)
1631 +               options->none_switch = 0;
1632 +       if (options->hpn_disabled == -1)
1633 +               options->hpn_disabled = 0;
1634 +       if (options->hpn_buffer_size > -1)
1635 +       {
1636 +         /* if a user tries to set the size to 0 set it to 1KB */
1637 +               if (options->hpn_buffer_size == 0)
1638 +               options->hpn_buffer_size = 1024;
1639 +               /*limit the buffer to 64MB*/
1640 +               if (options->hpn_buffer_size > 65536)
1641 +               {
1642 +                       options->hpn_buffer_size = 65536*1024;
1643 +                       debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1644 +               }
1645 +               debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1646 +       }
1647 +       if (options->tcp_rcv_buf == 0)
1648 +               options->tcp_rcv_buf = 1;
1649 +       if (options->tcp_rcv_buf > -1) 
1650 +               options->tcp_rcv_buf *=1024;
1651 +       if (options->tcp_rcv_buf_poll == -1)
1652 +               options->tcp_rcv_buf_poll = 1;
1653         if (options->control_master == -1)
1654                 options->control_master = 0;
1655         if (options->hash_known_hosts == -1)
1656 diff -NupwB openssh-4.9p1/readconf.h openssh-4.9p1-hpn13/readconf.h
1657 --- openssh-4.9p1/readconf.h    2008-02-10 06:25:52.000000000 -0500
1658 +++ openssh-4.9p1-hpn13/readconf.h      2008-04-01 13:18:43.000000000 -0400
1659 @@ -56,6 +56,11 @@ typedef struct {
1660         int     compression_level;      /* Compression level 1 (fast) to 9
1661                                          * (best). */
1662         int     tcp_keep_alive; /* Set SO_KEEPALIVE. */
1663 +        int     tcp_rcv_buf; /* user switch to set tcp recv buffer */
1664 +       int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
1665 +       int     hpn_disabled;    /* Switch to disable HPN buffer management */
1666 +       int     hpn_buffer_size; /* User definable size for HPN buffer window */
1667 +
1668         LogLevel log_level;     /* Level for logging. */
1669  
1670         int     port;           /* Port to connect. */
1671 @@ -101,6 +106,8 @@ typedef struct {
1672  
1673         int     enable_ssh_keysign;
1674         int64_t rekey_limit;
1675 +       int     none_switch;    /* Use none cipher */
1676 +       int     none_enabled;   /* Allow none to be used */
1677         int     no_host_authentication_for_localhost;
1678         int     identities_only;
1679         int     server_alive_interval;
1680 Common subdirectories: openssh-4.9p1/regress and openssh-4.9p1-hpn13/regress
1681 Common subdirectories: openssh-4.9p1/scard and openssh-4.9p1-hpn13/scard
1682 diff -NupwB openssh-4.9p1/scp.c openssh-4.9p1-hpn13/scp.c
1683 --- openssh-4.9p1/scp.c 2008-03-13 20:59:50.000000000 -0400
1684 +++ openssh-4.9p1-hpn13/scp.c   2008-04-01 13:03:59.000000000 -0400
1685 @@ -631,7 +631,7 @@ source(int argc, char **argv)
1686         BUF *bp;
1687         off_t i, amt, statbytes;
1688         int fd = -1, haderr, indx;
1689 -       char *last, *name, buf[2048], encname[MAXPATHLEN];
1690 +       char *last, *name, buf[16384], encname[MAXPATHLEN];
1691         int len;
1692  
1693         for (indx = 0; indx < argc; ++indx) {
1694 @@ -863,7 +863,7 @@ sink(int argc, char **argv)
1695         mode_t mode, omode, mask;
1696         off_t size, statbytes;
1697         int setimes, targisdir, wrerrno = 0;
1698 -       char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
1699 +       char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
1700         struct timeval tv[2];
1701  
1702  #define        atime   tv[0]
1703 diff -NupwB openssh-4.9p1/servconf.c openssh-4.9p1-hpn13/servconf.c
1704 --- openssh-4.9p1/servconf.c    2008-02-10 06:48:55.000000000 -0500
1705 +++ openssh-4.9p1-hpn13/servconf.c      2008-04-01 13:23:46.000000000 -0400
1706 @@ -123,11 +123,20 @@ initialize_server_options(ServerOptions 
1707         options->num_permitted_opens = -1;
1708         options->adm_forced_command = NULL;
1709         options->chroot_directory = NULL;
1710 +       options->none_enabled = -1;
1711 +       options->tcp_rcv_buf_poll = -1;
1712 +       options->hpn_disabled = -1;
1713 +       options->hpn_buffer_size = -1;
1714  }
1715  
1716  void
1717  fill_default_server_options(ServerOptions *options)
1718  {
1719 +       /* needed for hpn socket tests */
1720 +       int sock;
1721 +       int socksize;
1722 +       int socksizelen = sizeof(int);
1723 +
1724         /* Portable-specific options */
1725         if (options->use_pam == -1)
1726                 options->use_pam = 0;
1727 @@ -251,6 +260,42 @@ fill_default_server_options(ServerOption
1728         if (options->permit_tun == -1)
1729                 options->permit_tun = SSH_TUNMODE_NO;
1730  
1731 +       if (options->hpn_disabled == -1) 
1732 +               options->hpn_disabled = 0;
1733 +
1734 +       if (options->hpn_buffer_size == -1) {
1735 +               /* option not explicitly set. Now we have to figure out */
1736 +               /* what value to use */
1737 +               if (options->hpn_disabled == 1) {
1738 +                       options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
1739 +               } else {
1740 +                       /* get the current RCV size and set it to that */
1741 +                       /*create a socket but don't connect it */
1742 +                       /* we use that the get the rcv socket size */
1743 +                       sock = socket(AF_INET, SOCK_STREAM, 0);
1744 +                       getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
1745 +                                  &socksize, &socksizelen);
1746 +                       close(sock);
1747 +                       options->hpn_buffer_size = socksize;
1748 +                       debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
1749 +                       
1750 +               } 
1751 +       } else {
1752 +               /* we have to do this incase the user sets both values in a contradictory */
1753 +               /* manner. hpn_disabled overrrides hpn_buffer_size*/
1754 +               if (options->hpn_disabled <= 0) {
1755 +                       if (options->hpn_buffer_size == 0)
1756 +                               options->hpn_buffer_size = 1;
1757 +                       /* limit the maximum buffer to 64MB */
1758 +                       if (options->hpn_buffer_size > 64*1024) {
1759 +                               options->hpn_buffer_size = 64*1024*1024;
1760 +                       } else {
1761 +                               options->hpn_buffer_size *= 1024;
1762 +                       }
1763 +               } else
1764 +                       options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
1765 +       }
1766 +
1767         /* Turn privilege separation on by default */
1768         if (use_privsep == -1)
1769                 use_privsep = 1;
1770 @@ -293,7 +338,8 @@ typedef enum {
1771         sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
1772         sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
1773         sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
1774 -       sUsePrivilegeSeparation,
1775 +       sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
1776 +       sHPNDisabled, sHPNBufferSize,
1777         sDeprecated, sUnsupported
1778  } ServerOpCodes;
1779  
1780 @@ -405,6 +451,10 @@ static struct {
1781         { "permitopen", sPermitOpen, SSHCFG_ALL },
1782         { "forcecommand", sForceCommand, SSHCFG_ALL },
1783         { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
1784 +       { "noneenabled", sNoneEnabled },
1785 +       { "hpndisabled", sHPNDisabled },
1786 +       { "hpnbuffersize", sHPNBufferSize },
1787 +       { "tcprcvbufpoll", sTcpRcvBufPoll },
1788         { NULL, sBadOption, 0 }
1789  };
1790  
1791 @@ -420,6 +470,7 @@ parse_token(const char *cp, const char *
1792  
1793         for (i = 0; keywords[i].name; i++)
1794                 if (strcasecmp(cp, keywords[i].name) == 0) {
1795 +                       debug ("Config token is %s", keywords[i].name);
1796                         *flags = keywords[i].flags;
1797                         return keywords[i].opcode;
1798                 }
1799 @@ -831,6 +882,22 @@ parse_flag:
1800                         *intptr = value;
1801                 break;
1802  
1803 +       case sNoneEnabled:
1804 +               intptr = &options->none_enabled;
1805 +               goto parse_flag;
1806 +
1807 +       case sTcpRcvBufPoll:
1808 +               intptr = &options->tcp_rcv_buf_poll;
1809 +               goto parse_flag;
1810 +
1811 +       case sHPNDisabled:
1812 +               intptr = &options->hpn_disabled;
1813 +               goto parse_flag;
1814 +
1815 +       case sHPNBufferSize:
1816 +               intptr = &options->hpn_buffer_size;
1817 +               goto parse_int;
1818 +
1819         case sIgnoreUserKnownHosts:
1820                 intptr = &options->ignore_user_known_hosts;
1821                 goto parse_flag;
1822 diff -NupwB openssh-4.9p1/servconf.h openssh-4.9p1-hpn13/servconf.h
1823 --- openssh-4.9p1/servconf.h    2008-03-07 02:31:24.000000000 -0500
1824 +++ openssh-4.9p1-hpn13/servconf.h      2008-04-01 13:03:59.000000000 -0400
1825 @@ -140,6 +140,10 @@ typedef struct {
1826         char   *adm_forced_command;
1827  
1828         int     use_pam;                /* Enable auth via PAM */
1829 +        int     none_enabled;           /* enable NONE cipher switch */
1830 +        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
1831 +       int     hpn_disabled;           /* disable hpn functionality. false by default */
1832 +       int     hpn_buffer_size;        /* set the hpn buffer size - default 3MB */
1833  
1834         int     permit_tun;
1835  
1836 diff -NupwB openssh-4.9p1/serverloop.c openssh-4.9p1-hpn13/serverloop.c
1837 --- openssh-4.9p1/serverloop.c  2008-03-07 02:33:30.000000000 -0500
1838 +++ openssh-4.9p1-hpn13/serverloop.c    2008-04-01 13:03:59.000000000 -0400
1839 @@ -92,10 +92,10 @@ static int fdin;            /* Descriptor for stdi
1840  static int fdout;              /* Descriptor for stdout (for reading);
1841                                    May be same number as fdin. */
1842  static int fderr;              /* Descriptor for stderr.  May be -1. */
1843 -static long stdin_bytes = 0;   /* Number of bytes written to stdin. */
1844 -static long stdout_bytes = 0;  /* Number of stdout bytes sent to client. */
1845 -static long stderr_bytes = 0;  /* Number of stderr bytes sent to client. */
1846 -static long fdout_bytes = 0;   /* Number of stdout bytes read from program. */
1847 +static u_long stdin_bytes = 0; /* Number of bytes written to stdin. */
1848 +static u_long stdout_bytes = 0;        /* Number of stdout bytes sent to client. */
1849 +static u_long stderr_bytes = 0;        /* Number of stderr bytes sent to client. */
1850 +static u_long fdout_bytes = 0; /* Number of stdout bytes read from program. */
1851  static int stdin_eof = 0;      /* EOF message received from client. */
1852  static int fdout_eof = 0;      /* EOF encountered reading from fdout. */
1853  static int fderr_eof = 0;      /* EOF encountered readung from fderr. */
1854 @@ -119,6 +119,20 @@ static volatile sig_atomic_t received_si
1855  static void server_init_dispatch(void);
1856  
1857  /*
1858 + * Returns current time in seconds from Jan 1, 1970 with the maximum
1859 + * available resolution.
1860 + */
1861 +
1862 +static double
1863 +get_current_time(void)
1864 +{
1865 +       struct timeval tv;
1866 +       gettimeofday(&tv, NULL);
1867 +       return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
1868 +}
1869 +
1870 +
1871 +/*
1872   * we write to this pipe if a SIGCHLD is caught in order to avoid
1873   * the race between select() and child_terminated
1874   */
1875 @@ -407,6 +421,7 @@ process_input(fd_set *readset)
1876                 } else {
1877                         /* Buffer any received data. */
1878                         packet_process_incoming(buf, len);
1879 +                       fdout_bytes += len;
1880                 }
1881         }
1882         if (compat20)
1883 @@ -429,6 +444,7 @@ process_input(fd_set *readset)
1884                 } else {
1885                         buffer_append(&stdout_buffer, buf, len);
1886                         fdout_bytes += len;
1887 +                       debug ("FD out now: %ld", fdout_bytes);
1888                 }
1889         }
1890         /* Read and buffer any available stderr data from the program. */
1891 @@ -495,7 +511,7 @@ process_output(fd_set *writeset)
1892         }
1893         /* Send any buffered packet data to the client. */
1894         if (FD_ISSET(connection_out, writeset))
1895 -               packet_write_poll();
1896 +               stdin_bytes += packet_write_poll();
1897  }
1898  
1899  /*
1900 @@ -812,8 +828,10 @@ server_loop2(Authctxt *authctxt)
1901  {
1902         fd_set *readset = NULL, *writeset = NULL;
1903         int rekeying = 0, max_fd, nalloc = 0;
1904 +       double start_time, total_time;
1905  
1906         debug("Entering interactive session for SSH2.");
1907 +       start_time = get_current_time();
1908  
1909         mysignal(SIGCHLD, sigchld_handler);
1910         child_terminated = 0;
1911 @@ -875,6 +893,11 @@ server_loop2(Authctxt *authctxt)
1912  
1913         /* free remaining sessions, e.g. remove wtmp entries */
1914         session_destroy_all(NULL);
1915 +       total_time = get_current_time() - start_time;
1916 +       logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
1917 +             get_remote_ipaddr(), get_remote_port(),
1918 +             stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
1919 +             fdout_bytes / total_time);
1920  }
1921  
1922  static void
1923 @@ -956,9 +979,14 @@ server_request_direct_tcpip(void)
1924         xfree(originator);
1925         if (sock < 0)
1926                 return NULL;
1927 +       if (options.hpn_disabled)
1928         c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
1929             sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
1930             CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
1931 +       else
1932 +               c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
1933 +                   sock, sock, -1, options.hpn_buffer_size,
1934 +                   CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
1935         return c;
1936  }
1937  
1938 @@ -993,8 +1021,12 @@ server_request_tun(void)
1939         sock = tun_open(tun, mode);
1940         if (sock < 0)
1941                 goto done;
1942 +       if (options.hpn_disabled)
1943         c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
1944             CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
1945 +       else
1946 +               c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
1947 +                   options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
1948         c->datagram = 1;
1949  #if defined(SSH_TUN_FILTER)
1950         if (mode == SSH_TUNMODE_POINTOPOINT)
1951 @@ -1024,6 +1056,8 @@ server_request_session(void)
1952         c = channel_new("session", SSH_CHANNEL_LARVAL,
1953             -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
1954             0, "server-session", 1);
1955 +       if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled))
1956 +               c->dynamic_window = 1;
1957         if (session_open(the_authctxt, c->self) != 1) {
1958                 debug("session open failed, free channel %d", c->self);
1959                 channel_free(c);
1960 @@ -1120,7 +1154,8 @@ server_input_global_request(int type, u_
1961                 } else {
1962                         /* Start listening on the port */
1963                         success = channel_setup_remote_fwd_listener(
1964 -                           listen_address, listen_port, options.gateway_ports);
1965 +                           listen_address, listen_port, options.gateway_ports, 
1966 +                           options.hpn_disabled, options.hpn_buffer_size);
1967                 }
1968                 xfree(listen_address);
1969         } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
1970 diff -NupwB openssh-4.9p1/session.c openssh-4.9p1-hpn13/session.c
1971 --- openssh-4.9p1/session.c     2008-03-26 20:03:05.000000000 -0400
1972 +++ openssh-4.9p1-hpn13/session.c       2008-04-01 13:03:59.000000000 -0400
1973 @@ -217,6 +217,7 @@ auth_input_request_forwarding(struct pas
1974                 packet_disconnect("listen: %.100s", strerror(errno));
1975  
1976         /* Allocate a channel for the authentication agent socket. */
1977 +       /* this shouldn't matter if its hpn or not - cjr */
1978         nc = channel_new("auth socket",
1979             SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
1980             CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
1981 @@ -354,7 +355,8 @@ do_authenticated1(Authctxt *authctxt)
1982                         }
1983                         debug("Received TCP/IP port forwarding request.");
1984                         if (channel_input_port_forward_request(s->pw->pw_uid == 0,
1985 -                           options.gateway_ports) < 0) {
1986 +                             options.gateway_ports, options.hpn_disabled,
1987 +                              options.hpn_buffer_size) < 0) {
1988                                 debug("Port forwarding failed.");
1989                                 break;
1990                         }
1991 @@ -2147,11 +2149,18 @@ session_set_fds(Session *s, int fdin, in
1992          */
1993         if (s->chanid == -1)
1994                 fatal("no channel for session %d", s->self);
1995 +       if(options.hpn_disabled) 
1996         channel_set_fds(s->chanid,
1997             fdout, fdin, fderr,
1998             fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1999             1,
2000             CHAN_SES_WINDOW_DEFAULT);
2001 +       else
2002 +               channel_set_fds(s->chanid,
2003 +                   fdout, fdin, fderr,
2004 +                   fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2005 +                   1,
2006 +                   options.hpn_buffer_size);
2007  }
2008  
2009  /*
2010 @@ -2496,7 +2505,8 @@ session_setup_x11fwd(Session *s)
2011         }
2012         if (x11_create_display_inet(options.x11_display_offset,
2013             options.x11_use_localhost, s->single_connection,
2014 -           &s->display_number, &s->x11_chanids) == -1) {
2015 +           &s->display_number, &s->x11_chanids, 
2016 +           options.hpn_disabled, options.hpn_buffer_size) == -1) {
2017                 debug("x11_create_display_inet failed.");
2018                 return 0;
2019         }
2020 diff -NupwB openssh-4.9p1/ssh.c openssh-4.9p1-hpn13/ssh.c
2021 --- openssh-4.9p1/ssh.c 2008-02-28 03:13:52.000000000 -0500
2022 +++ openssh-4.9p1-hpn13/ssh.c   2008-04-01 13:03:59.000000000 -0400
2023 @@ -503,9 +503,6 @@ main(int ac, char **av)
2024                         no_shell_flag = 1;
2025                         no_tty_flag = 1;
2026                         break;
2027 -               case 'T':
2028 -                       no_tty_flag = 1;
2029 -                       break;
2030                 case 'o':
2031                         dummy = 1;
2032                         line = xstrdup(optarg);
2033 @@ -514,6 +511,13 @@ main(int ac, char **av)
2034                                 exit(255);
2035                         xfree(line);
2036                         break;
2037 +               case 'T':
2038 +                       no_tty_flag = 1;
2039 +                       /* ensure that the user doesn't try to backdoor a */
2040 +                       /* null cipher switch on an interactive session */
2041 +                       /* so explicitly disable it no matter what */
2042 +                       options.none_switch=0;
2043 +                       break;
2044                 case 's':
2045                         subsystem_flag = 1;
2046                         break;
2047 @@ -842,7 +846,8 @@ ssh_init_forwarding(void)
2048                     options.local_forwards[i].listen_port,
2049                     options.local_forwards[i].connect_host,
2050                     options.local_forwards[i].connect_port,
2051 -                   options.gateway_ports);
2052 +                   options.gateway_ports, options.hpn_disabled,
2053 +                   options.hpn_buffer_size);
2054         }
2055         if (i > 0 && success != i && options.exit_on_forward_failure)
2056                 fatal("Could not request local forwarding.");
2057 @@ -1160,6 +1165,9 @@ ssh_session2_open(void)
2058  {
2059         Channel *c;
2060         int window, packetmax, in, out, err;
2061 +       int sock;
2062 +       int socksize;
2063 +       int socksizelen = sizeof(int);
2064  
2065         if (stdin_null_flag) {
2066                 in = open(_PATH_DEVNULL, O_RDONLY);
2067 @@ -1180,9 +1188,70 @@ ssh_session2_open(void)
2068         if (!isatty(err))
2069                 set_nonblock(err);
2070  
2071 -       window = CHAN_SES_WINDOW_DEFAULT;
2072 +       /* we need to check to see if what they want to do about buffer */
2073 +       /* sizes here. In a hpn to nonhpn connection we want to limit */
2074 +       /* the window size to something reasonable in case the far side */
2075 +       /* has the large window bug. In hpn to hpn connection we want to */
2076 +       /* use the max window size but allow the user to override it */
2077 +       /* lastly if they disabled hpn then use the ssh std window size */
2078 +
2079 +       /* so why don't we just do a getsockopt() here and set the */
2080 +       /* ssh window to that? In the case of a autotuning receive */
2081 +       /* window the window would get stuck at the initial buffer */
2082 +       /* size generally less than 96k. Therefore we need to set the */
2083 +       /* maximum ssh window size to the maximum hpn buffer size */
2084 +       /* unless the user has specifically set the tcprcvbufpoll */
2085 +       /* to no. In which case we *can* just set the window to the */
2086 +       /* minimum of the hpn buffer size and tcp receive buffer size */
2087 +       
2088 +       if(options.hpn_disabled)
2089 +       {
2090 +               options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
2091 +       }
2092 +       else if (datafellows & SSH_BUG_LARGEWINDOW) 
2093 +       {
2094 +               debug("HPN to Non-HPN Connection");
2095 +               if (options.hpn_buffer_size < 0)
2096 +                       options.hpn_buffer_size = 2*1024*1024;
2097 +       } 
2098 +       else 
2099 +       {
2100 +               if (options.hpn_buffer_size < 0)
2101 +                       options.hpn_buffer_size = BUFFER_MAX_LEN_HPN;
2102 +
2103 +               /*create a socket but don't connect it */
2104 +               /* we use that the get the rcv socket size */
2105 +               sock = socket(AF_INET, SOCK_STREAM, 0);
2106 +               /* if they are using the tcp_rcv_buf option */
2107 +               /* attempt to set the buffer size to that */
2108 +               if (options.tcp_rcv_buf) 
2109 +                       setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
2110 +                                  sizeof(options.tcp_rcv_buf));
2111 +               getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
2112 +                          &socksize, &socksizelen);
2113 +               close(sock);
2114 +               debug("socksize %d", socksize);
2115 +               if (options.tcp_rcv_buf_poll <= 0) 
2116 +               {
2117 +                       options.hpn_buffer_size = MIN(socksize,options.hpn_buffer_size);
2118 +                       debug ("MIN of TCP RWIN and HPNBufferSize: %d", options.hpn_buffer_size);
2119 +               } 
2120 +               else
2121 +               {
2122 +                       if (options.tcp_rcv_buf > 0) 
2123 +                               options.hpn_buffer_size = MIN(options.tcp_rcv_buf, options.hpn_buffer_size);
2124 +                               debug ("MIN of TCPRcvBuf and HPNBufferSize: %d", options.hpn_buffer_size);
2125 +               }
2126 +               
2127 +       }
2128 +
2129 +       debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
2130 +
2131 +       window = options.hpn_buffer_size;
2132 +
2133         packetmax = CHAN_SES_PACKET_DEFAULT;
2134         if (tty_flag) {
2135 +               window = 4*CHAN_SES_PACKET_DEFAULT;
2136                 window >>= 1;
2137                 packetmax >>= 1;
2138         }
2139 @@ -1190,7 +1259,10 @@ ssh_session2_open(void)
2140             "session", SSH_CHANNEL_OPENING, in, out, err,
2141             window, packetmax, CHAN_EXTENDED_WRITE,
2142             "client-session", /*nonblock*/0);
2143 -
2144 +       if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
2145 +               c->dynamic_window = 1;
2146 +               debug ("Enabled Dynamic Window Scaling\n");
2147 +       }
2148         debug3("ssh_session2_open: channel_new: %d", c->self);
2149  
2150         channel_send_open(c->self);
2151 diff -NupwB openssh-4.9p1/sshconnect2.c openssh-4.9p1-hpn13/sshconnect2.c
2152 --- openssh-4.9p1/sshconnect2.c 2008-02-10 06:25:53.000000000 -0500
2153 +++ openssh-4.9p1-hpn13/sshconnect2.c   2008-04-01 13:03:59.000000000 -0400
2154 @@ -73,6 +73,12 @@
2155  extern char *client_version_string;
2156  extern char *server_version_string;
2157  extern Options options;
2158 +extern Kex *xxx_kex;
2159 +
2160 +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
2161 +/* if it is set then prevent the switch to the null cipher */
2162 +
2163 +extern int tty_flag;
2164  
2165  /*
2166   * SSH2 key exchange
2167 @@ -326,6 +332,28 @@ ssh_userauth2(const char *local_user, co
2168         pubkey_cleanup(&authctxt);
2169         dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
2170  
2171 +       /* if the user wants to use the none cipher do it */
2172 +       /* post authentication and only if the right conditions are met */
2173 +       /* both of the NONE commands must be true and there must be no */
2174 +       /* tty allocated */
2175 +       if ((options.none_switch == 1) && (options.none_enabled == 1)) 
2176 +       {
2177 +               if (!tty_flag) /* no null on tty sessions */
2178 +               {
2179 +                       debug("Requesting none rekeying...");
2180 +                       myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
2181 +                       myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
2182 +                       kex_prop2buf(&xxx_kex->my,myproposal);
2183 +                       packet_request_rekeying();
2184 +                       fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
2185 +               }
2186 +               else
2187 +               {
2188 +                       /* requested NONE cipher when in a tty */
2189 +                       debug("Cannot switch to NONE cipher with tty allocated");
2190 +                       fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
2191 +               }
2192 +       }
2193         debug("Authentication succeeded (%s).", authctxt.method->name);
2194  }
2195  
2196 diff -NupwB openssh-4.9p1/sshconnect.c openssh-4.9p1-hpn13/sshconnect.c
2197 --- openssh-4.9p1/sshconnect.c  2007-12-28 10:43:51.000000000 -0500
2198 +++ openssh-4.9p1-hpn13/sshconnect.c    2008-04-01 13:03:59.000000000 -0400
2199 @@ -184,6 +184,31 @@ ssh_proxy_connect(const char *host, u_sh
2200  }
2201  
2202  /*
2203 + * Set TCP receive buffer if requested.
2204 + * Note: tuning needs to happen after the socket is
2205 + * created but before the connection happens
2206 + * so winscale is negotiated properly -cjr
2207 + */
2208 +static void
2209 +ssh_set_socket_recvbuf(int sock)
2210 +{
2211 +       void *buf = (void *)&options.tcp_rcv_buf;
2212 +       int sz = sizeof(options.tcp_rcv_buf);
2213 +       int socksize;
2214 +       int socksizelen = sizeof(int);
2215 +
2216 +       debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
2217 +       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
2218 +         getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
2219 +         debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
2220 +       }
2221 +       else
2222 +               error("Couldn't set socket receive buffer to %d: %.100s",
2223 +                   options.tcp_rcv_buf, strerror(errno));
2224 +}
2225 +
2226 +
2227 +/*
2228   * Creates a (possibly privileged) socket for use as the ssh connection.
2229   */
2230  static int
2231 @@ -206,12 +231,18 @@ ssh_create_socket(int privileged, struct
2232                             strerror(errno));
2233                 else
2234                         debug("Allocated local port %d.", p);
2235 +
2236 +               if (options.tcp_rcv_buf > 0)
2237 +                       ssh_set_socket_recvbuf(sock);           
2238                 return sock;
2239         }
2240         sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
2241         if (sock < 0)
2242                 error("socket: %.100s", strerror(errno));
2243  
2244 +       if (options.tcp_rcv_buf > 0)
2245 +               ssh_set_socket_recvbuf(sock);
2246 +       
2247         /* Bind the socket to an alternative local IP address */
2248         if (options.bind_address == NULL)
2249                 return sock;
2250 @@ -553,7 +584,7 @@ ssh_exchange_identification(int timeout_
2251         snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
2252             compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
2253             compat20 ? PROTOCOL_MINOR_2 : minor1,
2254 -           SSH_VERSION);
2255 +           SSH_RELEASE);
2256         if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
2257                 fatal("write: %.100s", strerror(errno));
2258         client_version_string = xstrdup(buf);
2259 diff -NupwB openssh-4.9p1/sshd.c openssh-4.9p1-hpn13/sshd.c
2260 --- openssh-4.9p1/sshd.c        2008-03-11 07:58:25.000000000 -0400
2261 +++ openssh-4.9p1-hpn13/sshd.c  2008-04-01 13:03:59.000000000 -0400
2262 @@ -136,6 +136,9 @@ int deny_severity;
2263  #define REEXEC_CONFIG_PASS_FD          (STDERR_FILENO + 3)
2264  #define REEXEC_MIN_FREE_FD             (STDERR_FILENO + 4)
2265  
2266 +int myflag = 0;
2267 +
2268 +
2269  extern char *__progname;
2270  
2271  /* Server configuration options. */
2272 @@ -421,7 +424,7 @@ sshd_exchange_identification(int sock_in
2273                 major = PROTOCOL_MAJOR_1;
2274                 minor = PROTOCOL_MINOR_1;
2275         }
2276 -       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
2277 +       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
2278         server_version_string = xstrdup(buf);
2279  
2280         /* Send our protocol version identification. */
2281 @@ -472,6 +475,9 @@ sshd_exchange_identification(int sock_in
2282         }
2283         debug("Client protocol version %d.%d; client software version %.100s",
2284             remote_major, remote_minor, remote_version);
2285 +       logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
2286 +             get_remote_ipaddr(), get_remote_port(),
2287 +           remote_major, remote_minor, remote_version);
2288  
2289         compat_datafellows(remote_version);
2290  
2291 @@ -953,6 +959,8 @@ server_listen(void)
2292         int ret, listen_sock, on = 1;
2293         struct addrinfo *ai;
2294         char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2295 +       int socksize;
2296 +       int socksizelen = sizeof(int);
2297  
2298         for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
2299                 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2300 @@ -999,6 +1007,11 @@ server_listen(void)
2301  
2302                 debug("Bind to port %s on %s.", strport, ntop);
2303  
2304 +               getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
2305 +                                  &socksize, &socksizelen);
2306 +               debug("Server TCP RWIN socket size: %d", socksize);
2307 +               debug("HPN Buffer Size: %d", options.hpn_buffer_size);
2308 +
2309                 /* Bind the socket to the desired port. */
2310                 if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2311                         error("Bind to port %s on %s failed: %.200s.",
2312 @@ -2130,9 +2143,15 @@ do_ssh2_kex(void)
2313  {
2314         Kex *kex;
2315  
2316 +       myflag++;
2317 +       debug ("MYFLAG IS %d", myflag);
2318         if (options.ciphers != NULL) {
2319                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
2320                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
2321 +       } else if (options.none_enabled == 1) {
2322 +               debug ("WARNING: None cipher enabled");
2323 +               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
2324 +               myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
2325         }
2326         myproposal[PROPOSAL_ENC_ALGS_CTOS] =
2327             compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
2328 diff -NupwB openssh-4.9p1/sshd_config openssh-4.9p1-hpn13/sshd_config
2329 --- openssh-4.9p1/sshd_config   2008-02-10 06:40:12.000000000 -0500
2330 +++ openssh-4.9p1-hpn13/sshd_config     2008-04-01 13:03:59.000000000 -0400
2331 @@ -110,6 +110,20 @@ Protocol 2
2332  # override default of no subsystems
2333  Subsystem      sftp    /usr/libexec/sftp-server
2334  
2335 +# the following are HPN related configuration options
2336 +# tcp receive buffer polling. disable in non autotuning kernels
2337 +#TcpRcvBufPoll yes
2338
2339 +# allow the use of the none cipher
2340 +#NoneEnabled no
2341 +
2342 +# disable hpn performance boosts. 
2343 +#HPNDisabled no
2344 +
2345 +# buffer size for hpn to non-hpn connections
2346 +#HPNBufferSize 2048
2347 +
2348 +
2349  # Example of overriding settings on a per-user basis
2350  #Match User anoncvs
2351  #      X11Forwarding no
2352 diff -NupwB openssh-4.9p1/version.h openssh-4.9p1-hpn13/version.h
2353 --- openssh-4.9p1/version.h     2008-03-26 20:18:13.000000000 -0400
2354 +++ openssh-4.9p1-hpn13/version.h       2008-04-01 13:03:59.000000000 -0400
2355 @@ -3,4 +3,5 @@
2356  #define SSH_VERSION    "OpenSSH_4.9"
2357  
2358  #define SSH_PORTABLE   "p1"
2359 -#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE
2360 +#define SSH_HPN         "-hpn13v1"
2361 +#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE SSH_HPN
This page took 0.197955 seconds and 3 git commands to generate.