X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/15abfc2e8c2854b3cc0fd6d474982b9ac1709830..7646c432cee3ca277363e53a26e9a77f3ecc1693:/ssh.c diff --git a/ssh.c b/ssh.c index 08741abc..7a697a16 100644 --- a/ssh.c +++ b/ssh.c @@ -183,7 +183,7 @@ static const char *const ssh2_disconnect_reasons[] = { /* * Codes for terminal modes. * Most of these are the same in SSH-1 and SSH-2. - * This list is derived from draft-ietf-secsh-connect-25 and + * This list is derived from RFC 4254 and * SSH-1 RFC-1.2.31. */ static const struct { @@ -470,11 +470,15 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * * - 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. It must be <= INT_MAX. */ #define SSH1_BUFFER_LIMIT 32768 #define SSH_MAX_BACKLOG 32768 #define OUR_V2_WINSIZE 16384 +#define OUR_V2_BIGWIN 0x7fffffff #define OUR_V2_MAXPKT 0x4000UL /* Maximum length of passwords/passphrases (arbitrary) */ @@ -552,7 +556,7 @@ struct ssh_channel { bufchain outbuffer; unsigned remwindow, remmaxpkt; /* locwindow is signed so we can cope with excess data. */ - int locwindow; + int locwindow, locmaxwin; } v2; } v; union { @@ -4030,7 +4034,7 @@ void sshfwd_unthrottle(struct ssh_channel *c, int bufsize) ssh1_throttle(ssh, -1); } } else { - ssh2_set_window(c, OUR_V2_WINSIZE - bufsize); + ssh2_set_window(c, c->v.v2.locmaxwin - bufsize); } } @@ -6187,7 +6191,7 @@ static void ssh2_set_window(struct ssh_channel *c, unsigned newwin) * * "Significant" is arbitrarily defined as half the window size. */ - if (newwin >= c->v.v2.locwindow * 2) { + if (newwin / 2 >= c->v.v2.locwindow) { struct Packet *pktout; pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST); @@ -6288,8 +6292,8 @@ static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin) * need to adjust the window if the server's * sent excess data. */ - ssh2_set_window(c, bufsize < OUR_V2_WINSIZE ? - OUR_V2_WINSIZE - bufsize : 0); + ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ? + c->v.v2.locmaxwin - bufsize : 0); } } @@ -6756,7 +6760,7 @@ static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin) } 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); @@ -7967,7 +7971,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, 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); @@ -8009,7 +8014,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, 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); @@ -8054,6 +8060,20 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = ssh2_msg_channel_open; + if (ssh->cfg.ssh_simple) { + /* + * This message indicates to the server that we promise + * not to try to run any other channel in parallel with + * this one, so it's safe for it to advertise a very large + * window and leave the flow control to TCP. + */ + s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); + ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); + ssh2_pkt_addstring(s->pktout, "simple@putty.projects.tartarus.org"); + ssh2_pkt_addbool(s->pktout, 0); /* no reply */ + ssh2_pkt_send(ssh, s->pktout); + } + /* * Potentially enable X11 forwarding. */ @@ -9062,7 +9082,8 @@ static void ssh_unthrottle(void *handle, int bufsize) 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); } } @@ -9085,7 +9106,7 @@ void ssh_send_port_open(void *channel, char *hostname, int port, char *org) 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);