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
12 @@ -67,6 +68,9 @@ extern Authmethod method_hostbased;
13 extern Authmethod method_gssapi;
16 +static int log_flag = 0;
19 Authmethod *authmethods[] = {
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);
27 + logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s",
28 + get_remote_ipaddr(), get_remote_port(), user);
31 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
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:
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",
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
55 +/* move the following to a more appropriate place and name */
56 +#define BUFFER_MAX_LEN_HPN 0x4000000 /* 64MB */
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;
70 c->remote_name = xstrdup(remote_name);
72 @@ -765,11 +766,35 @@ channel_pre_open_13(Channel *c, fd_set *
73 FD_SET(c->sock, writeset);
76 +int channel_tcpwinsz () {
77 + u_int32_t tcpwinsz = 0;
78 + socklen_t optsz = sizeof(tcpwinsz);
81 + /* if we aren't on a socket return 128KB*/
82 + if(!packet_connection_is_on_socket())
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());
95 channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
97 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
99 + /* check buffer limits */
100 + if ((!c->tcpwinsz) || (c->dynamic_window > 0))
101 + c->tcpwinsz = channel_tcpwinsz();
103 + limit = MIN(limit, 2 * c->tcpwinsz);
105 if (c->istate == CHAN_INPUT_OPEN &&
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;
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);
124 debug2("channel %d: window %d sent adjust %d",
125 c->self, c->local_window,
127 - c->local_window += c->local_consumed;
128 + c->local_window += c->local_consumed + addition;
129 c->local_consumed = 0;
132 @@ -1871,11 +1903,12 @@ channel_after_select(fd_set *readset, fd
135 /* If there is data to send to the connection, enqueue some of it now. */
138 channel_output_poll(void)
142 + int packet_length = 0;
144 for (i = 0; i < channels_alloc; 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);
151 + packet_length = packet_send();
152 c->remote_window -= dlen + 4;
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);
160 + packet_length = packet_send();
161 buffer_consume(&c->input, len);
162 c->remote_window -= len;
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);
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);
175 + return (packet_length);
179 @@ -2342,7 +2376,8 @@ channel_set_af(int af)
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)
188 int sock, r, success = 0, wildcard = 0, is_client;
189 @@ -2456,9 +2491,15 @@ channel_setup_fwd_listener(int type, con
192 /* Allocate a channel number for the socket. */
193 + /* explicitly test for hpn disabled option. if true use smaller window size */
195 c = channel_new("port listener", type, sock, sock, -1,
196 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
197 0, "port listener", 1);
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) */
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)
213 return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
214 listen_host, listen_port, host_to_connect, port_to_connect,
216 + gateway_ports, hpn_disabled, hpn_buffer_size);
219 /* protocol v2 remote port fwd, used by sshd */
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)
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);
232 @@ -2623,7 +2666,8 @@ channel_request_rforward_cancel(const ch
233 * message if there was an error).
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)
240 u_short port, host_port;
242 @@ -2649,7 +2693,7 @@ channel_input_port_forward_request(int i
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);
249 /* Free the argument string. */
251 @@ -2853,7 +2897,8 @@ channel_send_window_changes(void)
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)
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++) {
265 + /* Is this really necassary? */
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);
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;
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;
288 int single_connection;
291 char *ctype; /* type */
293 @@ -122,9 +124,11 @@ struct Channel {
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)
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)
304 #define CHAN_X11_PACKET_DEFAULT (16*1024)
305 #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
307 @@ -193,7 +197,7 @@ void channel_input_window_adjust(int, u
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);
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);
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 *,
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);
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 },
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);
376 @@ -330,6 +332,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
380 + case SSH_CIPHER_NONE:
381 case SSH_CIPHER_SSH2:
383 case SSH_CIPHER_BLOWFISH:
384 @@ -364,6 +367,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
388 + case SSH_CIPHER_NONE:
389 case SSH_CIPHER_SSH2:
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
397 + * OpenSSH Multi-threaded AES-CTR Cipher
399 + * Author: Benjamin Bennett <ben@psc.edu>
400 + * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
402 + * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
403 + * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
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.
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.
417 +#include "includes.h"
419 +#include <sys/types.h>
424 +#include <openssl/evp.h>
426 +#include "xmalloc.h"
429 +/* compatibility with old or broken OpenSSL versions */
430 +#include "openbsd-compat/openssl-compat.h"
432 +#ifndef USE_BUILTIN_RIJNDAEL
433 +#include <openssl/aes.h>
436 +#include <pthread.h>
438 +/*-------------------- TUNABLES --------------------*/
439 +/* Number of pregen threads to use */
440 +#define CIPHER_THREADS 2
442 +/* Number of keystream queues */
443 +#define NUMKQ (CIPHER_THREADS + 2)
445 +/* Length of a keystream queue */
448 +/* Processor cacheline length */
449 +#define CACHELINE_LEN 64
451 +/* Collect thread stats and print at cancellation when in debug mode */
452 +// #define CIPHER_THREAD_STATS
454 +/* Use single-byte XOR instead of 8-byte XOR */
455 +// #define CIPHER_BYTE_XOR
456 +/*-------------------- END TUNABLES --------------------*/
459 +const EVP_CIPHER *evp_aes_ctr_mt(void);
461 +#ifdef CIPHER_THREAD_STATS
463 + * Struct to collect thread stats
465 +struct thread_stats {
473 + * Debug print the thread stats
474 + * Use with pthread_cleanup_push for displaying at thread cancellation
477 +thread_loop_stats(void *x)
479 + struct thread_stats *s = x;
481 + debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
482 + s->fills, s->skips, s->waits);
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++; }
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)
500 +/* Keystream Queue state */
509 +/* Keystream Queue struct */
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];
520 +/* Context struct */
521 +struct ssh_aes_ctr_ctx
523 + struct kq q[NUMKQ];
525 + STATS_STRUCT(stats);
526 + u_char aes_counter[AES_BLOCK_SIZE];
527 + pthread_t tid[CIPHER_THREADS];
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])
539 +ssh_ctr_inc(u_char *ctr, u_int len)
543 + for (i = len - 1; i >= 0; i--)
544 + if (++ctr[i]) /* continue on overflow */
549 + * Add num to counter 'ctr'
552 +ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
557 + for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
558 + n = ctr[i] + (num & 0xff) + n;
566 + * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
569 +thread_loop_cleanup(void *x)
571 + pthread_mutex_unlock((pthread_mutex_t *)x);
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.
580 +thread_loop(void *x)
583 + STATS_STRUCT(stats);
584 + struct ssh_aes_ctr_ctx *c = x;
589 + /* Threads stats on cancellation */
591 +#ifdef CIPHER_THREAD_STATS
592 + pthread_cleanup_push(thread_loop_stats, &stats);
595 + /* Thread local copy of AES key */
596 + memcpy(&key, &c->aes_ctx, sizeof(key));
599 + * Handle the special case of startup, one thread must fill
600 + * the first KQ then mark it as draining. Lock held throughout.
602 + if (pthread_equal(pthread_self(), c->tid[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);
610 + ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
611 + q->qstate = KQDRAINING;
613 + pthread_cond_broadcast(&q->cond);
615 + pthread_mutex_unlock(&q->lock);
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.
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.
629 + for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
630 + /* Check if I was cancelled, also checked in cond_wait */
631 + pthread_testcancel();
633 + /* Lock queue and block if its draining */
635 + pthread_mutex_lock(&q->lock);
636 + pthread_cleanup_push(thread_loop_cleanup, &q->lock);
637 + while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
639 + pthread_cond_wait(&q->cond, &q->lock);
641 + pthread_cleanup_pop(0);
643 + /* If filling or full, somebody else got it, skip */
644 + if (q->qstate != KQEMPTY) {
645 + pthread_mutex_unlock(&q->lock);
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.
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);
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;
667 + pthread_cond_signal(&q->cond);
668 + pthread_mutex_unlock(&q->lock);
671 +#ifdef CIPHER_THREAD_STATS
673 + pthread_cleanup_pop(1);
680 +ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
683 + struct ssh_aes_ctr_ctx *c;
684 + struct kq *q, *oldq;
690 + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
693 + q = &c->q[c->qidx];
696 + /* src already padded to block multiple */
698 + buf = q->keys[ridx];
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];
718 + *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
719 + *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
720 + *(uint64_t *)(buf + 8);
726 + ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
728 + /* Increment read index, switch queues on rollover */
729 + if ((ridx = (ridx + 1) % KQLEN) == 0) {
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);
740 + q->qstate = KQDRAINING;
741 + pthread_mutex_unlock(&q->lock);
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);
759 +ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
762 + struct ssh_aes_ctr_ctx *c;
765 + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
766 + c = xmalloc(sizeof(*c));
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);
774 + STATS_INIT(c->stats);
776 + EVP_CIPHER_CTX_set_app_data(ctx, c);
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;
790 + AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
792 + c->state |= HAVE_KEY;
796 + memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
797 + c->state |= HAVE_IV;
800 + if (c->state == (HAVE_KEY | HAVE_IV)) {
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;
812 + /* Start threads */
813 + for (i = 0; i < CIPHER_THREADS; i++) {
814 + pthread_create(&c->tid[i], NULL, thread_loop, c);
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);
826 +ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
828 + struct ssh_aes_ctr_ctx *c;
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,
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);
842 + memset(c, 0, sizeof(*c));
844 + EVP_CIPHER_CTX_set_app_data(ctx, NULL);
851 +evp_aes_ctr_mt(void)
853 + static EVP_CIPHER aes_ctr;
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;
864 + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
865 + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
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)
874 set_nonblock(client_fd);
876 + if (options.hpn_disabled)
877 window = CHAN_SES_WINDOW_DEFAULT;
879 + window = options.hpn_buffer_size;
881 packetmax = CHAN_SES_PACKET_DEFAULT;
882 if (cctx->want_tty) {
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)
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.");
900 @@ -1737,9 +1741,15 @@ client_request_forwarded_tcpip(const cha
901 xfree(listen_address);
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);
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();
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);
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);
933 @@ -1795,9 +1811,15 @@ client_request_agent(const char *request
934 sock = ssh_get_authentication_socket();
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);
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);
950 @@ -1825,10 +1847,18 @@ client_request_tun_fwd(int tun_mode, int
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,
960 + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
961 + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
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)
980 + if (strstr(version,"hpn") == NULL)
982 + datafellows |= SSH_BUG_LARGEWINDOW;
983 + debug("Remote is NON-HPN aware");
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
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
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
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
1018 +Use examples: ssh -caes128-ctr you@host.com
1019 + scp -oCipher=aes256-ctr file you@host.com:~/file
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
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.
1033 +http://www.psc.edu/networking/projects/hpn-ssh
1037 +If HPN is disabled the receive buffer size will be set to the
1038 +OpenSSH default of 64K.
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.
1043 +If an HPN to HPN connection is established a number of different things might
1044 +happen based on the user options and conditions.
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.
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
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).
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.
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.
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
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
1081 +HPN Specific Configuration options
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.
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)
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.
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.
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.
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
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
1138 #include "dispatch.h"
1139 #include "monitor.h"
1140 +#include "canohost.h"
1142 #define KEX_COOKIE_LEN 16
1144 @@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
1145 static void kex_choose_conf(Kex *);
1147 /* put algorithm proposal into buffer */
1149 +/* used in sshconnect.c as well as kex.c */
1151 kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
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;
1162 + auth_flag = packet_authentication_state();
1164 + debug ("AUTH STATE IS %d", auth_flag);
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.");
1178 + fatal("Pre-authentication none cipher requests are not allowed.");
1181 debug("kex: %s %s %s %s",
1182 ctos ? "client->server" : "server->client",
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*/
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);
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 *);
1210 +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
1212 Kex *kex_setup(char *[PROPOSAL_MAX]);
1213 void kex_finish(Kex *);
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@
1221 CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
1223 +LIBS=@LIBS@ -lpthread
1227 @@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
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
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 \
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)
1254 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
1258 packet_send2_wrapped(void)
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);
1272 + static int packet_length = 0;
1273 static int rekeying = 0;
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);
1281 + return(sizeof(Buffer));
1285 @@ -854,7 +856,7 @@ packet_send2(void)
1286 if (type == SSH2_MSG_KEXINIT)
1289 - packet_send2_wrapped();
1290 + packet_length = packet_send2_wrapped();
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)
1296 TAILQ_REMOVE(&outgoing, p, next);
1298 - packet_send2_wrapped();
1299 + packet_length += packet_send2_wrapped();
1302 + return(packet_length);
1309 + int packet_len = 0;
1312 + packet_len = packet_send2();
1315 DBG(debug("packet_send done"));
1316 + return(packet_len);
1320 @@ -1419,21 +1424,23 @@ packet_disconnect(const char *fmt,...)
1322 /* Checks if there is any buffered output, and tries to write some of the output. */
1326 packet_write_poll(void)
1328 - int len = buffer_len(&output);
1330 + len = buffer_len(&output);
1333 len = write(connection_out, buffer_ptr(&output), len);
1335 if (errno == EAGAIN)
1339 fatal("Write failed: %.100s", strerror(errno));
1341 buffer_consume(&output, len);
1347 @@ -1441,14 +1448,15 @@ packet_write_poll(void)
1353 packet_write_wait(void)
1356 + u_int bytes_sent = 0;
1358 setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
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) *
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))
1369 - packet_write_poll();
1370 + bytes_sent += packet_write_poll();
1373 + return (bytes_sent);
1376 /* Returns true if there is buffered data to write to the connection. */
1377 @@ -1580,12 +1589,24 @@ packet_send_ignore(int nbytes)
1381 +int rekey_requested = 0;
1383 +packet_request_rekeying(void)
1385 + rekey_requested = 1;
1388 #define MAX_PACKETS (1U<<31)
1390 packet_need_rekeying(void)
1392 if (datafellows & SSH_BUG_NOREKEY)
1394 + if (rekey_requested == 1)
1396 + rekey_requested = 0;
1400 (p_send.packets > MAX_PACKETS) ||
1401 (p_read.packets > MAX_PACKETS) ||
1402 @@ -1610,3 +1631,9 @@ packet_set_authenticated(void)
1404 after_authentication = 1;
1408 +packet_authentication_state(void)
1410 + return(after_authentication);
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
1417 #include <openssl/bn.h>
1420 +packet_request_rekeying(void);
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);
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);
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 *);
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);
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;
1471 transferred = *counter - cur_pos;
1474 bytes_left = end_pos - cur_pos;
1476 + delta_pos = cur_pos - last_pos;
1477 + if (delta_pos > max_delta_pos)
1478 + max_delta_pos = delta_pos;
1481 elapsed = now - last_update;
1483 @@ -158,7 +165,7 @@ refresh_progress_meter(void)
1487 - file_len = win_size - 35;
1488 + file_len = win_size - 45;
1490 len = snprintf(buf, file_len + 1, "\r%s", file);
1492 @@ -175,7 +182,8 @@ refresh_progress_meter(void)
1493 percent = ((float)cur_pos / end_pos) * 100;
1496 - snprintf(buf + strlen(buf), win_size - strlen(buf),
1498 + snprintf(buf + strlen(buf), win_size - strlen(buf-8),
1499 " %3d%% ", percent);
1501 /* amount transferred */
1502 @@ -188,6 +196,11 @@ refresh_progress_meter(void)
1503 (off_t)bytes_per_second);
1504 strlcat(buf, "/s ", win_size);
1506 + /* instantaneous rate */
1507 + format_rate(buf + strlen(buf), win_size - strlen(buf),
1509 + strlcat(buf, "/s ", win_size);
1514 @@ -224,6 +237,7 @@ refresh_progress_meter(void)
1516 atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
1518 + last_pos = cur_pos;
1522 @@ -270,6 +284,7 @@ void
1523 stop_progress_meter(void)
1530 @@ -278,6 +293,8 @@ stop_progress_meter(void)
1531 if (cur_pos != end_pos)
1532 refresh_progress_meter();
1534 + format_rate(lbuf, sizeof(lbuf), max_delta_pos);
1535 + printf("\nMax throughput: %s/s\n", lbuf);
1536 atomicio(vwrite, STDOUT_FILENO, "\n", 1);
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,
1548 oDeprecated, oUnsupported
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 }
1564 @@ -454,6 +462,37 @@ parse_flag:
1565 intptr = &options->check_host_ip;
1568 + case oNoneEnabled:
1569 + intptr = &options->none_enabled;
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 */
1576 + if(strcmp(filename,"command-line")==0)
1578 + intptr = &options->none_switch;
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);
1587 + case oHPNDisabled:
1588 + intptr = &options->hpn_disabled;
1591 + case oHPNBufferSize:
1592 + intptr = &options->hpn_buffer_size;
1595 + case oTcpRcvBufPoll:
1596 + intptr = &options->tcp_rcv_buf_poll;
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;
1607 + intptr = &options->tcp_rcv_buf;
1611 intptr = &options->cipher;
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;
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)
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)
1642 + options->hpn_buffer_size = 65536*1024;
1643 + debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1645 + debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
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
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 */
1668 LogLevel log_level; /* Level for logging. */
1670 int port; /* Port to connect. */
1671 @@ -101,6 +106,8 @@ typedef struct {
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)
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];
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];
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;
1717 fill_default_server_options(ServerOptions *options)
1719 + /* needed for hpn socket tests */
1722 + int socksizelen = sizeof(int);
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;
1731 + if (options->hpn_disabled == -1)
1732 + options->hpn_disabled = 0;
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;
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);
1747 + options->hpn_buffer_size = socksize;
1748 + debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
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;
1761 + options->hpn_buffer_size *= 1024;
1764 + options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
1767 /* Turn privilege separation on by default */
1768 if (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
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 }
1791 @@ -420,6 +470,7 @@ parse_token(const char *cp, const char *
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;
1799 @@ -831,6 +882,22 @@ parse_flag:
1803 + case sNoneEnabled:
1804 + intptr = &options->none_enabled;
1807 + case sTcpRcvBufPoll:
1808 + intptr = &options->tcp_rcv_buf_poll;
1811 + case sHPNDisabled:
1812 + intptr = &options->hpn_disabled;
1815 + case sHPNBufferSize:
1816 + intptr = &options->hpn_buffer_size;
1819 case sIgnoreUserKnownHosts:
1820 intptr = &options->ignore_user_known_hosts;
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;
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 */
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);
1858 + * Returns current time in seconds from Jan 1, 1970 with the maximum
1859 + * available resolution.
1863 +get_current_time(void)
1865 + struct timeval tv;
1866 + gettimeofday(&tv, NULL);
1867 + return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
1872 * we write to this pipe if a SIGCHLD is caught in order to avoid
1873 * the race between select() and child_terminated
1875 @@ -407,6 +421,7 @@ process_input(fd_set *readset)
1877 /* Buffer any received data. */
1878 packet_process_incoming(buf, len);
1879 + fdout_bytes += len;
1883 @@ -429,6 +444,7 @@ process_input(fd_set *readset)
1885 buffer_append(&stdout_buffer, buf, len);
1887 + debug ("FD out now: %ld", fdout_bytes);
1890 /* Read and buffer any available stderr data from the program. */
1891 @@ -495,7 +511,7 @@ process_output(fd_set *writeset)
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();
1900 @@ -812,8 +828,10 @@ server_loop2(Authctxt *authctxt)
1902 fd_set *readset = NULL, *writeset = NULL;
1903 int rekeying = 0, max_fd, nalloc = 0;
1904 + double start_time, total_time;
1906 debug("Entering interactive session for SSH2.");
1907 + start_time = get_current_time();
1909 mysignal(SIGCHLD, sigchld_handler);
1910 child_terminated = 0;
1911 @@ -875,6 +893,11 @@ server_loop2(Authctxt *authctxt)
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);
1923 @@ -956,9 +979,14 @@ server_request_direct_tcpip(void)
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);
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);
1938 @@ -993,8 +1021,12 @@ server_request_tun(void)
1939 sock = tun_open(tun, mode);
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);
1946 + c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
1947 + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 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);
1960 @@ -1120,7 +1154,8 @@ server_input_global_request(int type, u_
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);
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));
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)
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.");
1991 @@ -2147,11 +2149,18 @@ session_set_fds(Session *s, int fdin, in
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,
1998 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2000 CHAN_SES_WINDOW_DEFAULT);
2002 + channel_set_fds(s->chanid,
2003 + fdout, fdin, fderr,
2004 + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2006 + options.hpn_buffer_size);
2010 @@ -2496,7 +2505,8 @@ session_setup_x11fwd(Session *s)
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.");
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)
2032 line = xstrdup(optarg);
2033 @@ -514,6 +511,13 @@ main(int ac, char **av)
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;
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);
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)
2060 int window, packetmax, in, out, err;
2063 + int socksizelen = sizeof(int);
2065 if (stdin_null_flag) {
2066 in = open(_PATH_DEVNULL, O_RDONLY);
2067 @@ -1180,9 +1188,70 @@ ssh_session2_open(void)
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 */
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 */
2088 + if(options.hpn_disabled)
2090 + options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
2092 + else if (datafellows & SSH_BUG_LARGEWINDOW)
2094 + debug("HPN to Non-HPN Connection");
2095 + if (options.hpn_buffer_size < 0)
2096 + options.hpn_buffer_size = 2*1024*1024;
2100 + if (options.hpn_buffer_size < 0)
2101 + options.hpn_buffer_size = BUFFER_MAX_LEN_HPN;
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);
2114 + debug("socksize %d", socksize);
2115 + if (options.tcp_rcv_buf_poll <= 0)
2117 + options.hpn_buffer_size = MIN(socksize,options.hpn_buffer_size);
2118 + debug ("MIN of TCP RWIN and HPNBufferSize: %d", options.hpn_buffer_size);
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);
2129 + debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
2131 + window = options.hpn_buffer_size;
2133 packetmax = CHAN_SES_PACKET_DEFAULT;
2135 + window = 4*CHAN_SES_PACKET_DEFAULT;
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);
2144 + if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
2145 + c->dynamic_window = 1;
2146 + debug ("Enabled Dynamic Window Scaling\n");
2148 debug3("ssh_session2_open: channel_new: %d", c->self);
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
2155 extern char *client_version_string;
2156 extern char *server_version_string;
2157 extern Options options;
2158 +extern Kex *xxx_kex;
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 */
2163 +extern int tty_flag;
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);
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))
2177 + if (!tty_flag) /* no null on tty sessions */
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");
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");
2193 debug("Authentication succeeded (%s).", authctxt.method->name);
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
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
2209 +ssh_set_socket_recvbuf(int sock)
2211 + void *buf = (void *)&options.tcp_rcv_buf;
2212 + int sz = sizeof(options.tcp_rcv_buf);
2214 + int socksizelen = sizeof(int);
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);
2222 + error("Couldn't set socket receive buffer to %d: %.100s",
2223 + options.tcp_rcv_buf, strerror(errno));
2228 * Creates a (possibly privileged) socket for use as the ssh connection.
2231 @@ -206,12 +231,18 @@ ssh_create_socket(int privileged, struct
2234 debug("Allocated local port %d.", p);
2236 + if (options.tcp_rcv_buf > 0)
2237 + ssh_set_socket_recvbuf(sock);
2240 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
2242 error("socket: %.100s", strerror(errno));
2244 + if (options.tcp_rcv_buf > 0)
2245 + ssh_set_socket_recvbuf(sock);
2247 /* Bind the socket to an alternative local IP address */
2248 if (options.bind_address == NULL)
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,
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)
2269 extern char *__progname;
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;
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);
2280 /* Send our protocol version identification. */
2281 @@ -472,6 +475,9 @@ sshd_exchange_identification(int sock_in
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);
2289 compat_datafellows(remote_version);
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];
2296 + int socksizelen = sizeof(int);
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)
2302 debug("Bind to port %s on %s.", strport, ntop);
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);
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)
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;
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
2335 +# the following are HPN related configuration options
2336 +# tcp receive buffer polling. disable in non autotuning kernels
2339 +# allow the use of the none cipher
2342 +# disable hpn performance boosts.
2345 +# buffer size for hpn to non-hpn connections
2346 +#HPNBufferSize 2048
2349 # Example of overriding settings on a per-user basis
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
2356 #define SSH_VERSION "OpenSSH_4.9"
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