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* */