IETF-SSH archive

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

Re: Channel close logic, needs clarification?



Markus Friedl <Markus.Friedl%informatik.uni-erlangen.de@localhost> writes:

> On Thu, Mar 08, 2001 at 05:31:58PM +0100, Niels Möller wrote:
>
> > 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.

I'm not sure what you're saying here. I'm saying that the "normal"
reason the channel close process is initiated is that CHANNEL_EOF is
both sent and received. There are other, less "normal", reasons. For
instance, if lsh or lshd receives a CHANNEL_CLOSE, that is not
preceded by a CHANNEL_EOF, it displays a warning message "unexpected
channel close", and then it replies with CHANNEL_CLOSE so that the
channel goes away.

> > 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.

That seems reasonable (as the client can't really know if the server
implements exit-status), but on the other hand that message is the
only reliable hint the client gets that it will not be able to send
any more data.

The alternative is for the server to send CHANNEL_CLOSE after the
exit-status message. If I understand you and Sami correctly, that is
what both the ssh2 and openssh servers do.

But the server can't do that *immediately* after process death,
because then it may lose some of the data on stdout/stderr. Rather,
the rule has to be that the server sends CHANNEL_CLOSE after *all*
these events have occured:

  * Process death
  * EOF on stderr
  * EOF on stdout

Is that what you are doing? I considered doing that in lshd, and the
reason I didn't was the following scenario:

 1. Client sends CHANNEL_EOF

 2. The process' stdin is closed by the server.

 3. The process dies, and its stderr and stdout is closed
    automatically by the system.

 4. The server happens to notice the EOF conditions before it notices
    the process death. So the server sends CHANNEL_EOF.

 5. Now, the "CHANNEL_EOF both sent and received" kicks in, and the
    server sends CHANNEL_CLOSE.

Problem: No exit-status is ever sent (and the client exits with the
"default exit code" of 17, so my lsh testsuite at least has a chance
to notice the problem).

So in addition to the conditions above, one needs a special exception
to the "CHANNEL_EOF both sent and received" rule, which makes things
even more complex. Is this still the Right Way to go?

Suggestions?

/Niels



Home | Main Index | Thread Index | Old Index