]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Improvements to SSH1 channel close handling: track sending and
authorSimon Tatham <anakin@pobox.com>
Sun, 15 Sep 2002 13:24:00 +0000 (13:24 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 15 Sep 2002 13:24:00 +0000 (13:24 +0000)
receiving of CLOSE and CLOSE_CONFIRMATION separately rather than
taking short cuts. I believe ssh-1.2.33 sending CLOSE_CONFIRMATION
before CLOSE was causing the remaining incidences of bug
`nonexistent-channel'. (ssh-1.2.33 appears to have unilaterally
decreed that CLOSE and CLOSE_CONFIRMATION are respectively renamed
INPUT_EOF and OUTPUT_CLOSING, hence there is no longer an ordering
constraint on them. Bah.)

[originally from svn r1961]

ssh.c

diff --git a/ssh.c b/ssh.c
index b2859651de65500ea1cfb8a7b7758ad974dedebb..a23ead91d1fca58b97bd85296950609c76edcbaf 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -426,6 +426,16 @@ enum {                                    /* channel types */
 struct ssh_channel {
     unsigned remoteid, localid;
     int type;
+    /*
+     * In SSH1, this value contains four bits:
+     * 
+     *   1   We have sent SSH1_MSG_CHANNEL_CLOSE.
+     *   2   We have sent SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
+     *   4   We have received SSH1_MSG_CHANNEL_CLOSE.
+     *   8   We have received SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
+     * 
+     * A channel is completely finished with when all four bits are set.
+     */
     int closes;
     union {
        struct ssh1_data_channel {
@@ -2888,7 +2898,7 @@ void sshfwd_close(struct ssh_channel *c)
                ssh2_pkt_send();
            }
        }
-       c->closes = 1;
+       c->closes = 1;                 /* sent MSG_CLOSE */
        if (c->type == CHAN_X11) {
            c->u.x11.s = NULL;
            logevent("Forwarded X11 connection terminated");
@@ -3348,9 +3358,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
                    int closetype;
                    closetype =
                        (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
-                   if (!(c->closes & closetype))
-                       send_packet(pktin.type, PKT_INT, c->remoteid,
-                                   PKT_END);
+
                    if ((c->closes == 0) && (c->type == CHAN_X11)) {
                        logevent("Forwarded X11 connection terminated");
                        assert(c->u.x11.s != NULL);
@@ -3363,8 +3371,15 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
                        pfd_close(c->u.pfd.s);
                        c->u.pfd.s = NULL;
                    }
-                   c->closes |= closetype;
-                   if (c->closes == 3) {
+
+                   c->closes |= (closetype << 2);   /* seen this message */
+                   if (!(c->closes & closetype)) {
+                       send_packet(pktin.type, PKT_INT, c->remoteid,
+                                   PKT_END);
+                       c->closes |= closetype;      /* sent it too */
+                   }
+
+                   if (c->closes == 15) {
                        del234(ssh_channels, c);
                        sfree(c);
                    }