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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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* */