Skip to content

Commit 4bb06c8

Browse files
authored
Merge pull request #64 from rapier1/18.3-testing
Merging 18.3-testing into release_candidates after successful review.
2 parents 1be8f2b + c398f27 commit 4bb06c8

File tree

6 files changed

+56
-26
lines changed

6 files changed

+56
-26
lines changed

channels.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@
104104
/* Maximum number of fake X11 displays to try. */
105105
#define MAX_DISPLAYS 1000
106106

107+
/* in version of OpenSSH later than 8.8 if we advertise a window
108+
* 16MB or larger is causes a pathological behaviour that reduces
109+
* throughput. This is not a great solution. */
110+
#define NON_HPN_WINDOW_MAX (15 * 1024 * 1024)
111+
107112
/* Per-channel callback for pre/post IO actions */
108113
typedef void chan_fn(struct ssh *, Channel *c);
109114

@@ -1243,8 +1248,15 @@ channel_tcpwinsz(struct ssh *ssh)
12431248
/* return no more than SSHBUF_SIZE_MAX (currently 256MB) */
12441249
if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX)
12451250
tcpwinsz = SSHBUF_SIZE_MAX;
1251+
/* if the remote side is OpenSSH after version 8.8 we need to restrict
1252+
* the size of the advertised window. Now this means that any HPN to non-HPN
1253+
* connection will be window limited to 15MB of receive space. This is a
1254+
* non-optimal solution.
1255+
*/
12461256

1247-
return tcpwinsz;
1257+
if ((ssh->compat & SSH_RESTRICT_WINDOW) && (tcpwinsz > NON_HPN_WINDOW_MAX))
1258+
tcpwinsz = NON_HPN_WINDOW_MAX;
1259+
return (tcpwinsz);
12481260
}
12491261

12501262
static void
@@ -2376,8 +2388,10 @@ channel_check_window(struct ssh *ssh, Channel *c)
23762388
addition = tcpwinsz - c->local_window_max;
23772389
}
23782390
c->local_window_max += addition;
2379-
sshbuf_set_window_max(c->output, c->local_window_max);
2380-
sshbuf_set_window_max(c->input, c->local_window_max);
2391+
/* doesn't look like we need these
2392+
* sshbuf_set_window_max(c->output, c->local_window_max);
2393+
* sshbuf_set_window_max(c->input, c->local_window_max);
2394+
*/
23812395
debug("Channel %d: Window growth to %d by %d bytes",c->self,
23822396
c->local_window_max, addition);
23832397
}
@@ -2390,6 +2404,8 @@ channel_check_window(struct ssh *ssh, Channel *c)
23902404
(r = sshpkt_send(ssh)) != 0) {
23912405
fatal_fr(r, "channel %i", c->self);
23922406
}
2407+
debug2("channel %d: window %d sent adjust %d", c->self,
2408+
c->local_window, c->local_consumed + addition);
23932409
c->local_window += c->local_consumed + addition;
23942410
c->local_consumed = 0;
23952411
}

clientloop.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2990,7 +2990,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
29902990
* binaries installed. In that case we need to rewrite any
29912991
* scp commands to look for hpnscp instead.
29922992
*/
2993-
if (ssh->compat & SSH_HPNSSH) {
2993+
if (ssh->compat & SSH_HPNSSH_PREFIX) {
29942994
char *new_cmd;
29952995
new_cmd = malloc(len+4);
29962996
/* read the existing command into a temp buffer */

compat.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,30 @@ compat_banner(struct ssh *ssh, const char *version)
134134
/* Check to see if the remote side is OpenSSH and not HPN */
135135
/* TODO: See if we can work this into the new method for bug checks */
136136
if (strstr(version, "OpenSSH") != NULL) {
137-
if (strstr(version, "hpn") == NULL) {
138-
ssh->compat |= SSH_BUG_LARGEWINDOW;
139-
debug("Remote is NOT HPN enabled");
140-
} else {
141-
/* this checks to see if the remote
142-
* version string indicates that we
143-
* have access to hpn prefixed binaries
144-
* You'll need to change this to include
145-
* new major version numbers. Which is
146-
* why we should figure out how to make
147-
* the match pattern list work
148-
*/
149-
if ((strstr(version, "hpn16") != NULL) ||
150-
(strstr(version, "hpn17") != NULL))
151-
ssh->compat |= SSH_HPNSSH;
152-
debug("Remote is HPN Enabled");
137+
if (strstr(version, "hpn")) {
138+
ssh->compat |= SSH_HPNSSH;
139+
debug("Remote is HPN enabled");
140+
}
141+
/* this checks to see if the remote
142+
* version string indicates that we
143+
* have access to hpn prefixed binaries
144+
* You'll need to change this to include
145+
* new major version numbers. Which is
146+
* why we should figure out how to make
147+
* the match pattern list work
148+
*/
149+
if ((strstr(version, "hpn16") != NULL) ||
150+
(strstr(version, "hpn17") != NULL) ||
151+
(strstr(version, "hpn18") != NULL)) {
152+
ssh->compat |= SSH_HPNSSH_PREFIX;
153+
debug("Remote uses HPNSSH prefixes.");
154+
break;
155+
}
156+
/* if it's openssh and not hpn */
157+
if ((strstr(version, "OpenSSH_8.9") != NULL) ||
158+
(strstr(version, "OpenSSH_9") != NULL)) {
159+
ssh->compat |= SSH_RESTRICT_WINDOW;
160+
debug("Restricting adverstised window size.");
153161
}
154162
}
155163
debug("ssh->compat is %u", ssh->compat);

compat.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@
4646
/* #define unused 0x00010000 */
4747
/* #define unused 0x00020000 */
4848
/* #define unused 0x00040000 */
49-
/* #define unused 0x00100000 */
49+
#define SSH_HPNSSH 0x00100000 /* basically a notice that this is HPN aware */
5050
#define SSH_BUG_EXTEOF 0x00200000
5151
#define SSH_BUG_PROBE 0x00400000
52-
/* #define unused 0x00800000 */
52+
#define SSH_RESTRICT_WINDOW 0x00800000 /* restrict adverstised window to OpenSSH clients */
5353
#define SSH_OLD_FORWARD_ADDR 0x01000000
54-
#define SSH_HPNSSH 0x02000000 /* indicates that we have hpn prefixes binaries */
54+
#define SSH_HPNSSH_PREFIX 0x02000000 /* indicates that we have hpn prefixes binaries */
5555
#define SSH_NEW_OPENSSH 0x04000000
5656
#define SSH_BUG_DYNAMIC_RPORT 0x08000000
5757
#define SSH_BUG_CURVE25519PAD 0x10000000
5858
#define SSH_BUG_HOSTKEYS 0x20000000
5959
#define SSH_BUG_DHGEX_LARGE 0x40000000
60-
#define SSH_BUG_LARGEWINDOW 0x80000000 /* basically a notice that this is HPN aware */
60+
/* #define unused 0x80000000 */
6161

6262
struct ssh;
6363

kex.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
16001600
if (version_addendum != NULL && *version_addendum == '\0')
16011601
version_addendum = NULL;
16021602
if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n",
1603-
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
1603+
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE,
16041604
version_addendum == NULL ? "" : " ",
16051605
version_addendum == NULL ? "" : version_addendum)) != 0) {
16061606
oerrno = errno;
@@ -1747,6 +1747,13 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
17471747
debug("Remote protocol version %d.%d, remote software version %.100s",
17481748
remote_major, remote_minor, remote_version);
17491749
compat_banner(ssh, remote_version);
1750+
if (ssh->compat & SSH_HPNSSH)
1751+
debug("HPN to HPN Connection.");
1752+
else
1753+
debug("Non-HPN to HPN Connection.");
1754+
1755+
if(ssh->compat & SSH_RESTRICT_WINDOW)
1756+
debug ("Window size restricted.");
17501757

17511758
mismatch = 0;
17521759
switch (remote_major) {

ssh.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1881,7 +1881,6 @@ fork_postauth(struct ssh *ssh)
18811881
fatal("daemon() failed: %.200s", strerror(errno));
18821882
if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
18831883
error_f("stdfd_devnull failed");
1884-
18851884
/* we do the cipher switch here in the event that the client
18861885
is forking or has a delayed fork */
18871886
cipher_switch(ssh);

0 commit comments

Comments
 (0)