4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
|
c->pending_eof = TRUE;
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);
}
|
<
<
<
<
<
<
<
<
>
>
|
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
|
c->pending_eof = TRUE;
ssh_channel_try_eof(c);
}
void sshfwd_unclean_close(struct ssh_channel *c)
{
Ssh ssh = c->ssh;
if (ssh->state == SSH_STATE_CLOSED)
return;
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;
ssh2_channel_check_close(c);
}
|
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
|
}
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) {
/*
* 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.
*/
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
ssh2_pkt_adduint32(pktout, c->remoteid);
ssh2_pkt_send(ssh, pktout);
c->closes |= CLOSES_SENT_CLOSE;
}
if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes)) {
assert(c->v.v2.chanreq_head == NULL);
/*
* We have both sent and received CLOSE, which means we're
* completely done with the channel.
|
|
>
|
>
|
|
|
|
|
|
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
|
}
static void ssh2_channel_check_close(struct ssh_channel *c)
{
Ssh ssh = c->ssh;
struct Packet *pktout;
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 (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_EOF | CLOSES_SENT_CLOSE;
}
if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes)) {
assert(c->v.v2.chanreq_head == NULL);
/*
* We have both sent and received CLOSE, which means we're
* completely done with the channel.
|