mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-26 09:42:25 +00:00
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. [originally from svn r9631]
This commit is contained in:
parent
3fa95b2a7f
commit
0768c8557d
26
ssh.c
26
ssh.c
@ -4278,25 +4278,19 @@ void sshfwd_write_eof(struct ssh_channel *c)
|
|||||||
void sshfwd_unclean_close(struct ssh_channel *c)
|
void sshfwd_unclean_close(struct ssh_channel *c)
|
||||||
{
|
{
|
||||||
Ssh ssh = c->ssh;
|
Ssh ssh = c->ssh;
|
||||||
struct Packet *pktout;
|
|
||||||
|
|
||||||
if (ssh->state == SSH_STATE_CLOSED)
|
if (ssh->state == SSH_STATE_CLOSED)
|
||||||
return;
|
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) {
|
switch (c->type) {
|
||||||
case CHAN_X11:
|
case CHAN_X11:
|
||||||
x11_close(c->u.x11.s);
|
x11_close(c->u.x11.s);
|
||||||
|
logevent("Forwarded X11 connection terminated due to local error");
|
||||||
break;
|
break;
|
||||||
case CHAN_SOCKDATA:
|
case CHAN_SOCKDATA:
|
||||||
case CHAN_SOCKDATA_DORMANT:
|
case CHAN_SOCKDATA_DORMANT:
|
||||||
pfd_close(c->u.pfd.s);
|
pfd_close(c->u.pfd.s);
|
||||||
|
logevent("Forwarded port closed due to local error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c->type = CHAN_ZOMBIE;
|
c->type = CHAN_ZOMBIE;
|
||||||
@ -6946,18 +6940,20 @@ static void ssh2_channel_check_close(struct ssh_channel *c)
|
|||||||
Ssh ssh = c->ssh;
|
Ssh ssh = c->ssh;
|
||||||
struct Packet *pktout;
|
struct Packet *pktout;
|
||||||
|
|
||||||
if ((c->closes & (CLOSES_SENT_EOF | CLOSES_RCVD_EOF | CLOSES_SENT_CLOSE))
|
if ((!((CLOSES_SENT_EOF | CLOSES_RCVD_EOF) & ~c->closes) ||
|
||||||
== (CLOSES_SENT_EOF | CLOSES_RCVD_EOF) && !c->v.v2.chanreq_head) {
|
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
|
* We have both sent and received EOF (or the channel is a
|
||||||
* outstanding channel requests, which means the
|
* zombie), and we have no outstanding channel requests, which
|
||||||
* channel is in final wind-up. But we haven't sent CLOSE, so
|
* means the channel is in final wind-up. But we haven't sent
|
||||||
* let's do so now.
|
* CLOSE, so let's do so now.
|
||||||
*/
|
*/
|
||||||
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
|
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
|
||||||
ssh2_pkt_adduint32(pktout, c->remoteid);
|
ssh2_pkt_adduint32(pktout, c->remoteid);
|
||||||
ssh2_pkt_send(ssh, pktout);
|
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)) {
|
if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user