IETF-SSH archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Channel close logic, needs clarification?



On Thu, Mar 08, 2001 at 05:31:58PM +0100, Niels Möller wrote:
> Do we need to make some more detailed recommendations about channel
> close logic? Different behaviour can cause interoperability problems.

Yes, I think so :)
I'm quoting all of your message since the context is important.

> For instance, I have heard reports that when logging in with the
> openssh client to a recent lshd, the client will hang after logout.

Yes, I can reproduce this problem. Do other SSH client implementations
hang, too?

> I'll describe the logic that lsh and lshd uses. The basic rules are as
> follows:
> 
> 1. When SSH_MSG_CHANNEL_CLOSE is both sent and received, the channel
>    is killed. This is unconditionally required by the spec.

So does OpenSSH.

> 2. When SSH_MSG_CHANNEL_EOF is both sent and received,
>    SSH_MSG_CHANNEL_CLOSE is sent (unless it wasn't sent earlier). This
>    makes sense in almost all cases (and the only exceptions I'm aware
>    of seem out-of-scope here, they are related to proxying or
>    gatewaying channels).

I'm not sure that you can rely on getting an EOF message.

> So, what is left to decide is when to send SSH_MSG_CHANNEL_EOF. In
> most cases, the decision is easy, but sometimes it is not.
> 
> Consider the scenario where a client creates a session channel, gets a
> login shell, and later exits the shell by explicitly typing exit or
> logout. The result, at the server side, is
> 
>  * The server handles SIGCLD, discovers that its child process died,
>    and sends an SSH_MSG_CHANNEL_REQUEST "exit-status". This is of
>    course not done directly by the signal handler, but some time later
>    from the main loop.
> 
>  * The server gets an EOF condition on the process' stdout and stderr
>    (unless their are any grand children that still has one or the other
>    open). When EOF has occured on both stdout and stderr, the server
>    sends an SSH_MSG_CHANNEL_EOF.

Same here (more or less).

> The two events above can occur in more or less random order. The
> server has not received any SSH_MSG_CHANNEL_EOF, so rule 2 doesn't
> apply. The channel is still open.

Same here.

> What happens at the client? When the lsh client receives
> an SSH_MSG_CHANNEL_REQUEST "exit-status" message, it decides that it's
> time to stop talking, and it sends an SSH_MSG_CHANNEL_EOF. Now rule 2
> applies, and the channel gets closed properly.

The OpenSSH client considers the "exit-status" message just informational
and does _not_ send an EOF message back.

> But appearantly, this logic doesn't work right when talking to the
> openssh client. It doesn't send any SSH_MSG_CHANNEL_EOF, and to the
> user it appears that the system just hangs.

The OpenSSH server does not wait for the EOF message from the client.
However, since the servers' child process is dead, the server decides
that it will not write to more data to the 'stdin' handle and does _not_
wait for the EOF message from the client.  This way the the channel is
correctly closed.

> Does the lsh behaviour above make sense to you? What are other
> implementations doing?

Yes, I'm really interested in what other SSH implementations are
doing in these cases.

-markus



Home | Main Index | Thread Index | Old Index