X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/3620f307749e6d295ae88d19680eca8704fa79c8..04120005c69fade02fcf13c154419cece35de375:/ssh.c diff --git a/ssh.c b/ssh.c index a1cb34bd..b773e851 100644 --- a/ssh.c +++ b/ssh.c @@ -439,6 +439,8 @@ enum { #define crState(t) crStateP(t, ssh->t) #define crFinish(z) } *crLine = 0; return (z); } #define crFinishV } *crLine = 0; return; } +#define crFinishFree(z, s) } *crLine = 0; sfree(s); return (z); } +#define crFinishFreeV(s) } *crLine = 0; sfree(s); return; } #define crReturn(z) \ do {\ *crLine =__LINE__; return (z); case __LINE__:;\ @@ -4276,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; @@ -6944,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)) { @@ -7513,8 +7511,7 @@ static void ssh2_maybe_setup_x11(struct ssh_channel *c, struct Packet *pktin, logevent("X11 forwarding refused"); } } - sfree(s); - crFinishV; + crFinishFreeV(s); } static void ssh2_maybe_setup_agent(struct ssh_channel *c, struct Packet *pktin, @@ -7545,8 +7542,7 @@ static void ssh2_maybe_setup_agent(struct ssh_channel *c, struct Packet *pktin, logevent("Agent forwarding refused"); } } - sfree(s); - crFinishV; + crFinishFreeV(s); } static void ssh2_maybe_setup_pty(struct ssh_channel *c, struct Packet *pktin, @@ -7599,8 +7595,7 @@ static void ssh2_maybe_setup_pty(struct ssh_channel *c, struct Packet *pktin, } else { ssh->editing = ssh->echoing = 1; } - sfree(s); - crFinishV; + crFinishFreeV(s); } static void ssh2_setup_env(struct ssh_channel *c, struct Packet *pktin, @@ -7663,9 +7658,8 @@ static void ssh2_setup_env(struct ssh_channel *c, struct Packet *pktin, c_write_str(ssh, "Server refused to set all environment variables\r\n"); } } -out: - sfree(s); - crFinishV; + out:; + crFinishFreeV(s); } /*