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