1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Improvements to SSH1 channel close handling: track sending and

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]
This commit is contained in:
Simon Tatham 2002-09-15 13:24:00 +00:00
parent 994aee285f
commit 9b69e1b8aa

27
ssh.c
View File

@ -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);
}