*
* - OUR_V2_WINSIZE is the maximum window size we present on SSH-2
* channels.
+ *
+ * - OUR_V2_BIGWIN is the window size we advertise for the only
+ * channel in a simple connection.
*/
#define SSH1_BUFFER_LIMIT 32768
#define SSH_MAX_BACKLOG 32768
#define OUR_V2_WINSIZE 16384
+#define OUR_V2_BIGWIN 0x10000000
#define OUR_V2_MAXPKT 0x4000UL
/* Maximum length of passwords/passphrases (arbitrary) */
struct ssh2_data_channel {
bufchain outbuffer;
unsigned remwindow, remmaxpkt;
- unsigned locwindow;
+ /* locwindow is signed so we can cope with excess data. */
+ int locwindow, locmaxwin;
} v2;
} v;
union {
/* "Session data" packets - omit the data field */
if ((st->pktin->type == SSH1_SMSG_STDOUT_DATA) ||
(st->pktin->type == SSH1_SMSG_STDERR_DATA)) {
- do_blank = TRUE; blank_prefix = 0;
- } else if (st->pktin->type == SSH1_MSG_CHANNEL_DATA) {
do_blank = TRUE; blank_prefix = 4;
+ } else if (st->pktin->type == SSH1_MSG_CHANNEL_DATA) {
+ do_blank = TRUE; blank_prefix = 8;
}
if (do_blank) {
blank.offset = blank_prefix;
int do_blank = FALSE, blank_prefix = 0;
/* "Session data" packets - omit the data field */
if (st->pktin->type == SSH2_MSG_CHANNEL_DATA) {
- do_blank = TRUE; blank_prefix = 4;
- } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
do_blank = TRUE; blank_prefix = 8;
+ } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
+ do_blank = TRUE; blank_prefix = 12;
}
if (do_blank) {
blank.offset = blank_prefix;
} else {
send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
PKT_INT, c->remoteid,
- PKTT_DATA,
PKT_INT, replylen,
+ PKTT_DATA,
PKT_DATA, sentreply, replylen,
PKTT_OTHER,
PKT_END);
if (ssh->version == 1) {
send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
PKT_INT, c->remoteid,
- PKTT_DATA,
- PKT_INT, len, PKT_DATA, buf, len,
+ PKT_INT, len, PKTT_DATA, PKT_DATA, buf, len,
PKTT_OTHER, PKT_END);
/*
* In SSH-1 we can return 0 here - implying that forwarded
ssh1_throttle(ssh, -1);
}
} else {
- ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
+ ssh2_set_window(c, c->v.v2.locmaxwin - bufsize);
}
}
} else {
while (inlen > 0) {
int len = min(inlen, 512);
- send_packet(ssh, SSH1_CMSG_STDIN_DATA, PKTT_DATA,
- PKT_INT, len, PKT_DATA, in, len,
+ send_packet(ssh, SSH1_CMSG_STDIN_DATA,
+ PKT_INT, len, PKTT_DATA, PKT_DATA, in, len,
PKTT_OTHER, PKT_END);
in += len;
inlen -= len;
len = c->v.v2.remmaxpkt;
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(pktout, c->remoteid);
- dont_log_data(ssh, pktout, PKTLOG_OMIT);
ssh2_pkt_addstring_start(pktout);
+ dont_log_data(ssh, pktout, PKTLOG_OMIT);
ssh2_pkt_addstring_data(pktout, data, len);
end_log_omission(ssh, pktout);
ssh2_pkt_send(ssh, pktout);
*
* "Significant" is arbitrarily defined as half the window size.
*/
- if (newwin > c->v.v2.locwindow * 2) {
+ if (newwin >= c->v.v2.locwindow * 2) {
struct Packet *pktout;
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
/*
* If we are not buffering too much data,
* enlarge the window again at the remote side.
+ * If we are buffering too much, we may still
+ * need to adjust the window if the server's
+ * sent excess data.
*/
- if (bufsize < OUR_V2_WINSIZE)
- ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
+ ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
+ c->v.v2.locmaxwin - bufsize : 0);
}
}
} else {
c->localid = alloc_channel_id(ssh);
c->closes = 0;
- c->v.v2.locwindow = OUR_V2_WINSIZE;
+ c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
c->v.v2.remwindow = winsize;
c->v.v2.remmaxpkt = pktsize;
bufchain_init(&c->v.v2.outbuffer);
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "direct-tcpip");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
- ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
+ ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
+ ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "session");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
- ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
+ ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
+ ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ssh2_pkt_send(ssh, s->pktout);
ssh1_throttle(ssh, -1);
}
} else {
- ssh2_set_window(ssh->mainchan, OUR_V2_WINSIZE - bufsize);
+ ssh2_set_window(ssh->mainchan,
+ ssh->mainchan->v.v2.locmaxwin - bufsize);
}
}
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(pktout, "direct-tcpip");
ssh2_pkt_adduint32(pktout, c->localid);
- c->v.v2.locwindow = OUR_V2_WINSIZE;
+ c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
ssh2_pkt_addstring(pktout, hostname);