ssh_do_close() was only closing about half the channels. Fixed.
[sgt/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 25c236e..825731e 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -2377,7 +2377,7 @@ static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
 
 static int ssh_do_close(Ssh ssh, int notify_exit)
 {
-    int i, ret = 0;
+    int ret = 0;
     struct ssh_channel *c;
 
     ssh->state = SSH_STATE_CLOSED;
@@ -2390,11 +2390,11 @@ static int ssh_do_close(Ssh ssh, int notify_exit)
             ret = 1;
     }
     /*
-     * Now we must shut down any port and X forwardings going
+     * Now we must shut down any port- and X-forwarded channels going
      * through this connection.
      */
     if (ssh->channels) {
-       for (i = 0; NULL != (c = index234(ssh->channels, i)); i++) {
+       while (NULL != (c = index234(ssh->channels, 0))) {
            switch (c->type) {
              case CHAN_X11:
                x11_close(c->u.x11.s);
@@ -2403,7 +2403,7 @@ static int ssh_do_close(Ssh ssh, int notify_exit)
                pfd_close(c->u.pfd.s);
                break;
            }
-           del234(ssh->channels, c);
+           del234(ssh->channels, c); /* moving next one to index 0 */
            if (ssh->version == 2)
                bufchain_clear(&c->v.v2.outbuffer);
            sfree(c);
@@ -3808,6 +3808,8 @@ static void ssh_setup_portfwd(Ssh ssh, const Config *cfg)
            }
        } else {
            while (*portfwd_strptr) portfwd_strptr++;
+           host[0] = 0;
+           dports[0] = 0;
            dport = dserv = -1;
            portfwd_strptr++;          /* eat the NUL and move to next one */
        }
@@ -5142,16 +5144,19 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
     /*
      * Now generate and send e for Diffie-Hellman.
      */
+    set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
     s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
     s->pktout = ssh2_pkt_init(s->kex_init_value);
     ssh2_pkt_addmp(s->pktout, s->e);
     ssh2_pkt_send_noqueue(ssh, s->pktout);
 
+    set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
     crWaitUntil(pktin);
     if (pktin->type != s->kex_reply_value) {
        bombout(("expected key exchange reply packet from server"));
        crStop(0);
     }
+    set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
     ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
     s->f = ssh2_pkt_getmp(pktin);
     if (!s->f) {
@@ -5162,6 +5167,10 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
 
     s->K = dh_find_K(ssh->kex_ctx, s->f);
 
+    /* We assume everything from now on will be quick, and it might
+     * involve user interaction. */
+    set_busy_status(ssh->frontend, BUSY_NOT);
+
     sha_string(&ssh->exhash, s->hostkeydata, s->hostkeylen);
     if (ssh->kex == &ssh_diffiehellman_gex) {
        sha_uint32(&ssh->exhash, s->pbits);