X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=ssh.c;h=750017f65daff02b4724b238194481c6ce8a7890;hb=b73527e641fa09ff57ffd4d20ec4e4045039b890;hp=aabbcc4a078e2b71c48a8c166bad7ce43ec5da53;hpb=da66c0656a6622a23cfdd8316e66681e487b87f1;p=PuTTY.git diff --git a/ssh.c b/ssh.c index aabbcc4a..750017f6 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; @@ -6551,9 +6588,10 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin) /* * Never send WINDOW_ADJUST for a channel that the remote side has * already sent EOF on; there's no point, since it won't be - * sending any more data anyway. + * sending any more data anyway. Ditto if _we've_ already sent + * CLOSE. */ - if (c->closes & CLOSES_RCVD_EOF) + if (c->closes & (CLOSES_RCVD_EOF | CLOSES_SENT_CLOSE)) return; /* @@ -6563,7 +6601,6 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin) */ if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT) newwin = OUR_V2_MAXPKT; - /* * Only send a WINDOW_ADJUST if there's significantly more window @@ -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); } /* @@ -8524,6 +8561,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } ssh2_pkt_send_with_padding(ssh, s->pktout, 256); + /* + * Free the prompts structure from this iteration. + * If there's another, a new one will be allocated + * when we return to the top of this while loop. + */ + free_prompts(s->cur_prompt); + /* * Get the next packet in case it's another * INFO_REQUEST. @@ -9993,6 +10037,12 @@ static void ssh_unthrottle(void *handle, int bufsize) } } } + + /* + * Now process any SSH connection data that was stashed in our + * queue while we were frozen. + */ + ssh_process_queued_incoming_data(ssh); } void ssh_send_port_open(void *channel, char *hostname, int port, char *org)