From: ben Date: Mon, 27 Aug 2012 17:37:44 +0000 (+0000) Subject: Don't close SSH-2 channels with outstanding channel requests on local error. X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/commitdiff_plain/04120005c69fade02fcf13c154419cece35de375 Don't close SSH-2 channels with outstanding channel requests on local error. In sshfwd_unclean_close(), get ssh2_check_close() to handle sending SSH_MSG_CHANNEL_CLOSE. That way, it can hold off doing so until any outstanding channel requests are processed. Also add event log message for unclean channel closures. git-svn-id: svn://svn.tartarus.org/sgt/putty@9631 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/ssh.c b/ssh.c index ad9ccae4..b773e851 100644 --- a/ssh.c +++ b/ssh.c @@ -4278,25 +4278,19 @@ void sshfwd_write_eof(struct ssh_channel *c) void sshfwd_unclean_close(struct ssh_channel *c) { Ssh ssh = c->ssh; - struct Packet *pktout; if (ssh->state == SSH_STATE_CLOSED) return; - if (!(c->closes & CLOSES_SENT_CLOSE)) { - pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE); - ssh2_pkt_adduint32(pktout, c->remoteid); - ssh2_pkt_send(ssh, pktout); - c->closes |= CLOSES_SENT_EOF | CLOSES_SENT_CLOSE; - } - switch (c->type) { case CHAN_X11: x11_close(c->u.x11.s); + logevent("Forwarded X11 connection terminated due to local error"); break; case CHAN_SOCKDATA: case CHAN_SOCKDATA_DORMANT: pfd_close(c->u.pfd.s); + logevent("Forwarded port closed due to local error"); break; } c->type = CHAN_ZOMBIE; @@ -6946,18 +6940,20 @@ static void ssh2_channel_check_close(struct ssh_channel *c) Ssh ssh = c->ssh; struct Packet *pktout; - if ((c->closes & (CLOSES_SENT_EOF | CLOSES_RCVD_EOF | CLOSES_SENT_CLOSE)) - == (CLOSES_SENT_EOF | CLOSES_RCVD_EOF) && !c->v.v2.chanreq_head) { + if ((!((CLOSES_SENT_EOF | CLOSES_RCVD_EOF) & ~c->closes) || + c->type == CHAN_ZOMBIE) && + !c->v.v2.chanreq_head && + !(c->closes & CLOSES_SENT_CLOSE)) { /* - * We have both sent and received EOF, and we have no - * outstanding channel requests, which means the - * channel is in final wind-up. But we haven't sent CLOSE, so - * let's do so now. + * We have both sent and received EOF (or the channel is a + * zombie), and we have no outstanding channel requests, which + * means the channel is in final wind-up. But we haven't sent + * CLOSE, so let's do so now. */ pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE); ssh2_pkt_adduint32(pktout, c->remoteid); ssh2_pkt_send(ssh, pktout); - c->closes |= CLOSES_SENT_CLOSE; + c->closes |= CLOSES_SENT_EOF | CLOSES_SENT_CLOSE; } if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes)) {