Module Name:    src
Committed By:   mlelstv
Date:           Sat Aug 27 10:04:45 UTC 2022

Modified Files:
        src/crypto/external/bsd/openssh/dist: channels.c readconf.c ssh.c
            sshbuf.h

Log Message:
Adopt TCP window handling from current HPN patch at

https://github.com/rapier1/openssh-portable


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/crypto/external/bsd/openssh/dist/channels.c
cvs rdiff -u -r1.38 -r1.39 src/crypto/external/bsd/openssh/dist/readconf.c
cvs rdiff -u -r1.40 -r1.41 src/crypto/external/bsd/openssh/dist/ssh.c
cvs rdiff -u -r1.16 -r1.17 src/crypto/external/bsd/openssh/dist/sshbuf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/openssh/dist/channels.c
diff -u src/crypto/external/bsd/openssh/dist/channels.c:1.36 src/crypto/external/bsd/openssh/dist/channels.c:1.37
--- src/crypto/external/bsd/openssh/dist/channels.c:1.36	Fri Apr 15 14:00:06 2022
+++ src/crypto/external/bsd/openssh/dist/channels.c	Sat Aug 27 10:04:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: channels.c,v 1.36 2022/04/15 14:00:06 christos Exp $	*/
+/*	$NetBSD: channels.c,v 1.37 2022/08/27 10:04:45 mlelstv Exp $	*/
 /* $OpenBSD: channels.c,v 1.415 2022/03/30 21:10:25 djm Exp $ */
 /*
  * Author: Tatu Ylonen <y...@cs.hut.fi>
@@ -41,7 +41,7 @@
  */
 
 #include "includes.h"
-__RCSID("$NetBSD: channels.c,v 1.36 2022/04/15 14:00:06 christos Exp $");
+__RCSID("$NetBSD: channels.c,v 1.37 2022/08/27 10:04:45 mlelstv Exp $");
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1117,9 +1117,9 @@ channel_tcpwinsz(struct ssh *ssh)
 	    return(128*1024);
 	ret = getsockopt(ssh_packet_get_connection_in(ssh),
 			 SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-	/* return no more than 64MB */
-	if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
-	    tcpwinsz = BUFFER_MAX_LEN_HPN;
+	/* return no more than SSHBUF_SIZE_MAX (currently 256MB) */
+	if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX)
+	    tcpwinsz = SSHBUF_SIZE_MAX;
 	debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
 	       ssh_packet_get_connection_in(ssh));
 	return(tcpwinsz);
@@ -1128,10 +1128,6 @@ channel_tcpwinsz(struct ssh *ssh)
 static void
 channel_pre_open(struct ssh *ssh, Channel *c)
 {
-        /* check buffer limits */
-	if ((!c->tcpwinsz) || (c->dynamic_window > 0))
-    	    c->tcpwinsz = channel_tcpwinsz(ssh);
-	
 	c->io_want = 0;
 	if (c->istate == CHAN_INPUT_OPEN &&
 	    c->remote_window > 0 &&
@@ -2170,17 +2166,17 @@ channel_check_window(struct ssh *ssh, Ch
 	    c->local_window < c->local_window_max/2) &&
 	    c->local_consumed > 0) {
 		u_int addition = 0;
-
-		if (!c->have_remote_id)
-			fatal_f("channel %d: no remote id", c->self);
-
+		u_int32_t tcpwinsz = channel_tcpwinsz(ssh);
 		/* adjust max window size if we are in a dynamic environment */
-		if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
+		if (c->dynamic_window && (tcpwinsz > c->local_window_max)) {
 			/* grow the window somewhat aggressively to maintain 
 			 * pressure */
-			addition = 1.5*(c->tcpwinsz - c->local_window_max);
+			addition = 1.5*(tcpwinsz - c->local_window_max);
 			c->local_window_max += addition;
+			debug("Channel: Window growth to %d by %d bytes", c->local_window_max, addition);
 		}
+		if (!c->have_remote_id)
+			fatal_f("channel %d: no remote id", c->self);
 		if ((r = sshpkt_start(ssh,
 		    SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
 		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
@@ -2189,7 +2185,8 @@ channel_check_window(struct ssh *ssh, Ch
 			fatal_fr(r, "channel %i", c->self);
 		}
 		debug2("channel %d: window %d sent adjust %d", c->self,
-		    c->local_window, c->local_consumed);
+		    c->local_window,
+		    c->local_consumed + addition);
 		c->local_window += c->local_consumed + addition;
 		c->local_consumed = 0;
 	}

Index: src/crypto/external/bsd/openssh/dist/readconf.c
diff -u src/crypto/external/bsd/openssh/dist/readconf.c:1.38 src/crypto/external/bsd/openssh/dist/readconf.c:1.39
--- src/crypto/external/bsd/openssh/dist/readconf.c:1.38	Wed Feb 23 19:07:20 2022
+++ src/crypto/external/bsd/openssh/dist/readconf.c	Sat Aug 27 10:04:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: readconf.c,v 1.38 2022/02/23 19:07:20 christos Exp $	*/
+/*	$NetBSD: readconf.c,v 1.39 2022/08/27 10:04:45 mlelstv Exp $	*/
 /* $OpenBSD: readconf.c,v 1.366 2022/02/08 08:59:12 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <y...@cs.hut.fi>
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-__RCSID("$NetBSD: readconf.c,v 1.38 2022/02/23 19:07:20 christos Exp $");
+__RCSID("$NetBSD: readconf.c,v 1.39 2022/08/27 10:04:45 mlelstv Exp $");
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -42,6 +42,7 @@ __RCSID("$NetBSD: readconf.c,v 1.38 2022
 
 #include "xmalloc.h"
 #include "ssh.h"
+#include "sshbuf.h"
 #include "ssherr.h"
 #include "compat.h"
 #include "cipher.h"
@@ -2711,13 +2712,14 @@ fill_default_options(Options * options)
 	{
 	  /* if a user tries to set the size to 0 set it to 1KB */
 		if (options->hpn_buffer_size == 0)
-		options->hpn_buffer_size = 1024;
+			options->hpn_buffer_size = 1;
 		/*limit the buffer to 64MB*/
-		if (options->hpn_buffer_size > 65536)
+		if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024))
 		{
-			options->hpn_buffer_size = 65536*1024;
-			debug("User requested buffer larger than 64MB. Request reverted to 64MB");
-		}
+			options->hpn_buffer_size = SSHBUF_SIZE_MAX;
+			debug("User requested buffer larger than 256MB. Request reverted to 256MB");
+		} else
+			options->hpn_buffer_size *= 1024;
 		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
 	}
 	if (options->tcp_rcv_buf == 0)

Index: src/crypto/external/bsd/openssh/dist/ssh.c
diff -u src/crypto/external/bsd/openssh/dist/ssh.c:1.40 src/crypto/external/bsd/openssh/dist/ssh.c:1.41
--- src/crypto/external/bsd/openssh/dist/ssh.c:1.40	Fri Apr 15 14:00:06 2022
+++ src/crypto/external/bsd/openssh/dist/ssh.c	Sat Aug 27 10:04:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: ssh.c,v 1.40 2022/04/15 14:00:06 christos Exp $	*/
+/*	$NetBSD: ssh.c,v 1.41 2022/08/27 10:04:45 mlelstv Exp $	*/
 /* $OpenBSD: ssh.c,v 1.574 2022/03/30 04:33:09 djm Exp $ */
 /*
  * Author: Tatu Ylonen <y...@cs.hut.fi>
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
-__RCSID("$NetBSD: ssh.c,v 1.40 2022/04/15 14:00:06 christos Exp $");
+__RCSID("$NetBSD: ssh.c,v 1.41 2022/08/27 10:04:45 mlelstv Exp $");
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -2046,15 +2046,85 @@ ssh_session2_setup(struct ssh *ssh, int 
 	    NULL, fileno(stdin), command, environ);
 }
 
+static void
+hpn_options_init(struct ssh *ssh)
+{
+	/*
+	 * We need to check to see if what they want to do about buffer
+	 * sizes here. In a hpn to nonhpn connection we want to limit
+	 * the window size to something reasonable in case the far side
+	 * has the large window bug. In hpn to hpn connection we want to
+	 * use the max window size but allow the user to override it
+	 * lastly if they disabled hpn then use the ssh std window size.
+	 *
+	 * So why don't we just do a getsockopt() here and set the
+	 * ssh window to that? In the case of a autotuning receive
+	 * window the window would get stuck at the initial buffer
+	 * size generally less than 96k. Therefore we need to set the
+	 * maximum ssh window size to the maximum hpn buffer size
+	 * unless the user has specifically set the tcprcvbufpoll
+	 * to no. In which case we *can* just set the window to the
+	 * minimum of the hpn buffer size and tcp receive buffer size.
+	 */
+
+	if (tty_flag)
+		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
+	else
+		options.hpn_buffer_size = 2 * 1024 * 1024;
+
+	if (ssh->compat & SSH_BUG_LARGEWINDOW) {
+		debug("HPN to Non-HPN connection");
+	} else {
+		debug("HPN to HPN connection");
+		int sock, socksize;
+		socklen_t socksizelen;
+		if (options.tcp_rcv_buf_poll <= 0) {
+			sock = socket(AF_INET, SOCK_STREAM, 0);
+			socksizelen = sizeof(socksize);
+			getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+				   &socksize, &socksizelen);
+			close(sock);
+			debug("socksize %d", socksize);
+			options.hpn_buffer_size = socksize;
+			debug("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
+		} else {
+			if (options.tcp_rcv_buf > 0) {
+				/*
+				 * Create a socket but don't connect it:
+				 * we use that the get the rcv socket size
+				 */
+				sock = socket(AF_INET, SOCK_STREAM, 0);
+				/*
+				 * If they are using the tcp_rcv_buf option,
+				 * attempt to set the buffer size to that.
+				 */
+				if (options.tcp_rcv_buf) {
+					socksizelen = sizeof(options.tcp_rcv_buf);
+					setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+						   &options.tcp_rcv_buf, socksizelen);
+				}
+				socksizelen = sizeof(socksize);
+				getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+					   &socksize, &socksizelen);
+				close(sock);
+				debug("socksize %d", socksize);
+				options.hpn_buffer_size = socksize;
+				debug("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
+			}
+		}
+	}
+
+	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
+
+	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
+}
+
 /* open new channel for a session */
 static int
 ssh_session2_open(struct ssh *ssh)
 {
 	Channel *c;
 	int window, packetmax, in, out, err;
-	int sock;
-	int socksize;
-	socklen_t socksizelen = sizeof(int);
 
 	if (options.stdin_null) {
 		in = open(_PATH_DEVNULL, O_RDONLY);
@@ -2075,60 +2145,7 @@ ssh_session2_open(struct ssh *ssh)
 	if (!isatty(err))
 		set_nonblock(err);
 
-	/* we need to check to see if what they want to do about buffer */
-	/* sizes here. In a hpn to nonhpn connection we want to limit */
-	/* the window size to something reasonable in case the far side */
-	/* has the large window bug. In hpn to hpn connection we want to */
-	/* use the max window size but allow the user to override it */
-	/* lastly if they disabled hpn then use the ssh std window size */
-
-	/* so why don't we just do a getsockopt() here and set the */
-	/* ssh window to that? In the case of a autotuning receive */
-	/* window the window would get stuck at the initial buffer */
-	/* size generally less than 96k. Therefore we need to set the */
-	/* maximum ssh window size to the maximum hpn buffer size */
-	/* unless the user has specifically set the tcprcvbufpoll */
-	/* to no. In which case we *can* just set the window to the */
-	/* minimum of the hpn buffer size and tcp receive buffer size */
-	
-	if (tty_flag)
-		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
-	else
-		options.hpn_buffer_size = 2*1024*1024;
-
-	if (options.tcp_rcv_buf_poll <= 0) {
-		sock = socket(AF_INET, SOCK_STREAM, 0);
-		getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
-			   &socksize, &socksizelen);
-		close(sock);
-		debug("socksize %d", socksize);
-		options.hpn_buffer_size = socksize;
-		debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
-	} else {
-		if (options.tcp_rcv_buf > 0) {
-			/*create a socket but don't connect it */
-			/* we use that the get the rcv socket size */
-			sock = socket(AF_INET, SOCK_STREAM, 0);
-			/* if they are using the tcp_rcv_buf option */
-			/* attempt to set the buffer size to that */
-			if (options.tcp_rcv_buf) 
-				setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
-					   sizeof(options.tcp_rcv_buf));
-			getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
-				   &socksize, &socksizelen);
-			close(sock);
-			debug("socksize %d", socksize);
-			options.hpn_buffer_size = socksize;
-			debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
-		}
-	}
-
-	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
-
 	window = options.hpn_buffer_size;
-
-	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
-
 	packetmax = CHAN_SES_PACKET_DEFAULT;
 	if (tty_flag) {
 		window = 4*CHAN_SES_PACKET_DEFAULT;
@@ -2160,6 +2177,13 @@ ssh_session2(struct ssh *ssh, const stru
 	int r, id = -1;
 	char *cp, *tun_fwd_ifname = NULL;
 
+	/*
+	 * We need to initialize this early because the forwarding logic below
+	 * might open channels that use the hpn buffer sizes.  We can't send a
+	 * window of -1 (the default) to the server as it breaks things.
+	 */
+	hpn_options_init(ssh);
+
 	/* XXX should be pre-session */
 	if (!options.control_persist)
 		ssh_init_stdio_forwarding(ssh);

Index: src/crypto/external/bsd/openssh/dist/sshbuf.h
diff -u src/crypto/external/bsd/openssh/dist/sshbuf.h:1.16 src/crypto/external/bsd/openssh/dist/sshbuf.h:1.17
--- src/crypto/external/bsd/openssh/dist/sshbuf.h:1.16	Wed Feb 23 19:07:20 2022
+++ src/crypto/external/bsd/openssh/dist/sshbuf.h	Sat Aug 27 10:04:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: sshbuf.h,v 1.16 2022/02/23 19:07:20 christos Exp $	*/
+/*	$NetBSD: sshbuf.h,v 1.17 2022/08/27 10:04:45 mlelstv Exp $	*/
 /*	$OpenBSD: sshbuf.h,v 1.25 2022/01/22 00:43:43 djm Exp $	*/
 /*
  * Copyright (c) 2011 Damien Miller
@@ -34,10 +34,7 @@
 #define EC_POINT	void
 #endif /* WITH_OPENSSL */
 
-/* move the following to a more appropriate place and name */
-#define BUFFER_MAX_LEN_HPN	0x4000000	/* 64MB */
-
-#define SSHBUF_SIZE_MAX		0x8000000	/* Hard maximum size */
+#define SSHBUF_SIZE_MAX		0x10000000	/* Hard maximum size 256MB */
 #define SSHBUF_REFS_MAX		0x100000	/* Max child buffers */
 #define SSHBUF_MAX_BIGNUM	(16384 / 8)	/* Max bignum *bytes* */
 #define SSHBUF_MAX_ECPOINT	((528 * 2 / 8) + 1) /* Max EC point *bytes* */

Reply via email to