ssh->mainchan can be NULL; try not to segfault in that situation.
[sgt/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 51b5320..a2aeb54 100644 (file)
--- 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 {
@@ -472,13 +472,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
  *    channels.
  *
  *  - OUR_V2_BIGWIN is the window size we advertise for the only
- *    channel in a simple connection.
+ *    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 0x10000000
+#define OUR_V2_BIGWIN 0x7fffffff
 #define OUR_V2_MAXPKT 0x4000UL
 
 /* Maximum length of passwords/passphrases (arbitrary) */
@@ -663,7 +663,7 @@ static void ssh_special(void *handle, Telnet_Special);
 static int ssh2_try_send(struct ssh_channel *c);
 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len);
 static void ssh_throttle_all(Ssh ssh, int enable, int bufsize);
-static void ssh2_set_window(struct ssh_channel *c, unsigned newwin);
+static void ssh2_set_window(struct ssh_channel *c, int newwin);
 static int ssh_sendbuffer(void *handle);
 static int ssh_do_close(Ssh ssh, int notify_exit);
 static unsigned long ssh_pkt_getuint32(struct Packet *pkt);
@@ -6172,7 +6172,7 @@ static void ssh2_try_send_and_unthrottle(struct ssh_channel *c)
 /*
  * Potentially enlarge the window on an SSH-2 channel.
  */
-static void ssh2_set_window(struct ssh_channel *c, unsigned newwin)
+static void ssh2_set_window(struct ssh_channel *c, int newwin)
 {
     Ssh ssh = c->ssh;
 
@@ -6191,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);
@@ -8060,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.
      */
@@ -9068,8 +9082,9 @@ static void ssh_unthrottle(void *handle, int bufsize)
            ssh1_throttle(ssh, -1);
        }
     } else {
-       ssh2_set_window(ssh->mainchan,
-                       ssh->mainchan->v.v2.locmaxwin - bufsize);
+       if (ssh->mainchan)
+           ssh2_set_window(ssh->mainchan,
+                           ssh->mainchan->v.v2.locmaxwin - bufsize);
     }
 }