X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=ssh.c;h=505b4ae1dcb811773d9a77d4158bfffbd7bf7715;hb=bb1d656dd4dac5594bf13717dac1e2512b311935;hp=a21bbc7b97a180170fd1909bfa2f94593e74e850;hpb=69a01afe48365b8898a9b48cea0d9f9729d32347;p=PuTTY.git diff --git a/ssh.c b/ssh.c index a21bbc7b..505b4ae1 100644 --- a/ssh.c +++ b/ssh.c @@ -558,7 +558,15 @@ enum { /* channel types */ CHAN_X11, CHAN_AGENT, CHAN_SOCKDATA, - CHAN_SOCKDATA_DORMANT /* one the remote hasn't confirmed */ + CHAN_SOCKDATA_DORMANT, /* one the remote hasn't confirmed */ + /* + * CHAN_ZOMBIE is used to indicate a channel for which we've + * already destroyed the local data source: for instance, if a + * forwarded port experiences a socket error on the local side, we + * immediately destroy its local socket and turn the SSH channel + * into CHAN_ZOMBIE. + */ + CHAN_ZOMBIE }; /* @@ -4250,6 +4258,35 @@ void sshfwd_write_eof(struct ssh_channel *c) ssh_channel_try_eof(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); + break; + case CHAN_SOCKDATA: + case CHAN_SOCKDATA_DORMANT: + pfd_close(c->u.pfd.s); + break; + } + c->type = CHAN_ZOMBIE; + + ssh2_channel_check_close(c); +} + int sshfwd_write(struct ssh_channel *c, char *buf, int len) { Ssh ssh = c->ssh; @@ -6999,7 +7036,7 @@ static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin) /* * Send outgoing EOF. */ - sshfwd_write_eof(ssh->mainchan); + sshfwd_write_eof(c); } /*