Skip to content

Commit 218c234

Browse files
committed
Checkpoint
1 parent 1be8f2b commit 218c234

File tree

6 files changed

+62
-25
lines changed

6 files changed

+62
-25
lines changed

channels.c

Lines changed: 17 additions & 2 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,13 @@ 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;
1246-
1247-
return tcpwinsz;
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 but thats okay. This bug shows up when
1254+
* sending data to an hpn */
1255+
if ((ssh->compat & SSH_RESTRICT_WINDOW) && (tcpwinsz > NON_HPN_WINDOW_MAX))
1256+
tcpwinsz = NON_HPN_WINDOW_MAX;
1257+
return (tcpwinsz);
12481258
}
12491259

12501260
static void
@@ -2380,6 +2390,9 @@ channel_check_window(struct ssh *ssh, Channel *c)
23802390
sshbuf_set_window_max(c->input, c->local_window_max);
23812391
debug("Channel %d: Window growth to %d by %d bytes",c->self,
23822392
c->local_window_max, addition);
2393+
//if ((ssh->compat & SSH_RESTRICT_WINDOW) &&
2394+
// (addition > NON_HPN_WINDOW_MAX))
2395+
// addition = NON_HPN_WINDOW_MAX;
23832396
}
23842397
if (!c->have_remote_id)
23852398
fatal_f("channel %d: no remote id", c->self);
@@ -2390,6 +2403,8 @@ channel_check_window(struct ssh *ssh, Channel *c)
23902403
(r = sshpkt_send(ssh)) != 0) {
23912404
fatal_fr(r, "channel %i", c->self);
23922405
}
2406+
debug2("channel %d: window %d sent adjust %d", c->self,
2407+
c->local_window, c->local_consumed + addition);
23932408
c->local_window += c->local_consumed + addition;
23942409
c->local_consumed = 0;
23952410
}

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: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,36 +124,44 @@ compat_banner(struct ssh *ssh, const char *version)
124124
{ NULL, 0 }
125125
};
126126

127+
debug ("------------------------ VERSION IS %s", version);
127128
/* process table, return first match */
128129
ssh->compat = 0;
129130
for (i = 0; check[i].pat; i++) {
131+
debug_f("PATTERN IS %d for %s\n", i, check[i].pat);
130132
if (match_pattern_list(version, check[i].pat, 0) == 1) {
131133
debug_f("match: %s pat %s compat 0x%08x",
132134
version, check[i].pat, check[i].bugs);
133135
ssh->compat = check[i].bugs;
134136
/* Check to see if the remote side is OpenSSH and not HPN */
135137
/* TODO: See if we can work this into the new method for bug checks */
136138
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");
139+
if (strstr(version, "hpn")) {
140+
ssh->compat |= SSH_HPNSSH;
141+
debug("Remote is HPN enabled");
142+
}
143+
/* this checks to see if the remote
144+
* version string indicates that we
145+
* have access to hpn prefixed binaries
146+
* You'll need to change this to include
147+
* new major version numbers. Which is
148+
* why we should figure out how to make
149+
* the match pattern list work
150+
*/
151+
if ((strstr(version, "hpn16") != NULL) ||
152+
(strstr(version, "hpn17") != NULL) ||
153+
(strstr(version, "hpn18") != NULL)) {
154+
ssh->compat |= SSH_HPNSSH_PREFIX;
155+
debug("Remote uses HPNSSH prefixes.");
156+
break;
157+
}
158+
if ((strstr(version, "OpenSSH_8.9") != NULL) ||
159+
(strstr(version, "OpenSSH_9") != NULL)) {
160+
ssh->compat |= SSH_RESTRICT_WINDOW;
161+
debug("Restricting adverstised window size.");
153162
}
154163
}
155164
debug("ssh->compat is %u", ssh->compat);
156-
return;
157165
}
158166
}
159167
debug_f("no match: %s", version);

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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,14 @@ 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.");
17501754

1755+
if(ssh->compat & SSH_RESTRICT_WINDOW)
1756+
debug ("---------------------- RESTRICT");
1757+
17511758
mismatch = 0;
17521759
switch (remote_major) {
17531760
case 2:

ssh.c

Lines changed: 8 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);
@@ -2195,6 +2194,14 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
21952194
static void
21962195
hpn_options_init(struct ssh *ssh)
21972196
{
2197+
if (ssh->compat & SSH_HPNSSH)
2198+
debug("HPN to HPN Connection.");
2199+
else
2200+
debug("Non-HPN to HPN Connection.");
2201+
2202+
if(ssh->compat & SSH_RESTRICT_WINDOW)
2203+
debug ("---------------------- RESTRICT");
2204+
21982205
channel_set_hpn_disabled(options.hpn_disabled);
21992206
debug_f("HPN disabled: %d", options.hpn_disabled);
22002207
}

0 commit comments

Comments
 (0)