Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Nearly forgot noting this down in the 'half-closed' bug entry: don't send CHANNEL_CLOSE until we have acks for all our winadj requests. Should work around https://bugzilla.mindrot.org/show_bug.cgi?id=1818 . |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
de1e102574ad7977774f9c495ed8b0da |
| User & Date: | simon 2011-09-13 06:56:25.000 |
Context
|
2011-09-13
| ||
| 10:38 | Changed my mind about the EOF policy in SSH mode: I think the SSH backend should unilaterally assume outgoing EOF when it sees incoming EOF, if and only if the main session channel is talking to a pty. (Because ptys don't have a strong concept of EOF in the first place, that seems like a sensible place to draw the line.) This fixes a bug introduced by today's revamp in which if you used Unix Plink to run a console session it would hang after you hit ^D - because the server had sent EOF, but it was waiting for a client-side EOF too. check-in: 3aaf9b7e0f user: simon tags: trunk | |
| 06:56 | Nearly forgot noting this down in the 'half-closed' bug entry: don't send CHANNEL_CLOSE until we have acks for all our winadj requests. Should work around https://bugzilla.mindrot.org/show_bug.cgi?id=1818 . check-in: de1e102574 user: simon tags: trunk | |
| 06:44 | Revamp of EOF handling in all network connections, pipes and other data channels. Should comprehensively fix 'half-closed', in principle, though it's a big and complicated change and so there's a good chance I've made at least one mistake somewhere. All connections should now be rigorous about propagating end-of-file (or end-of-data-stream, or socket shutdown, or whatever) independently in both directions, except in frontends with no mechanism for sending explicit EOF (e.g. interactive terminal windows) or backends which are basically always used for interactive sessions so it's unlikely that an application would be depending on independent EOF (telnet, rlogin). EOF should now never accidentally be sent while there's still buffered data to go out before it. (May help fix 'portfwd-corrupt', and also I noticed recently that the ssh main session channel can accidentally have MSG_EOF sent before the output bufchain is clear, leading to embarrassment when it subsequently does send the output). check-in: 0831792ea4 user: simon tags: trunk | |
Changes
Changes to ssh.c.
| ︙ | ︙ | |||
469 470 471 472 473 474 475 476 477 478 479 480 481 482 | static int ssh2_pkt_construct(Ssh, struct Packet *); static void ssh2_pkt_send(Ssh, struct Packet *); static void ssh2_pkt_send_noqueue(Ssh, struct Packet *); static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, struct Packet *pktin); static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, struct Packet *pktin); static void ssh_channel_destroy(struct ssh_channel *c); /* * Buffer management constants. There are several of these for * various different purposes: * * - SSH1_BUFFER_LIMIT is the amount of backlog that must build up | > | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | static int ssh2_pkt_construct(Ssh, struct Packet *); static void ssh2_pkt_send(Ssh, struct Packet *); static void ssh2_pkt_send_noqueue(Ssh, struct Packet *); static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, struct Packet *pktin); static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, struct Packet *pktin); static void ssh2_channel_check_close(struct ssh_channel *c); static void ssh_channel_destroy(struct ssh_channel *c); /* * Buffer management constants. There are several of these for * various different purposes: * * - SSH1_BUFFER_LIMIT is the amount of backlog that must build up |
| ︙ | ︙ | |||
6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 |
/*
* winadj messages are only sent when the window is fully open, so
* if we get an ack of one, we know any pending unthrottle is
* complete.
*/
if (c->v.v2.throttle_state == UNTHROTTLING)
c->v.v2.throttle_state = UNTHROTTLED;
return TRUE;
}
static void ssh2_msg_channel_success(Ssh ssh, struct Packet *pktin)
{
/*
* This should never get called. All channel requests are either
| > > > > > | 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 |
/*
* winadj messages are only sent when the window is fully open, so
* if we get an ack of one, we know any pending unthrottle is
* complete.
*/
if (c->v.v2.throttle_state == UNTHROTTLING)
c->v.v2.throttle_state = UNTHROTTLED;
/*
* We may now initiate channel-closing procedures, if that winadj
* was the last thing outstanding before we send CHANNEL_CLOSE.
*/
ssh2_channel_check_close(c);
return TRUE;
}
static void ssh2_msg_channel_success(Ssh ssh, struct Packet *pktin)
{
/*
* This should never get called. All channel requests are either
|
| ︙ | ︙ | |||
6884 6885 6886 6887 6888 6889 6890 |
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))
| | | > | > | 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 |
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.winadj_head) {
/*
* We have both sent and received EOF, and we have no
* outstanding winadj 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;
}
|
| ︙ | ︙ |