Subject: Invalid channel numbers

From: [email-masked] (Peter Gutmann)
Date: Fri, 30 Jul 2004 00:05:42 +1200

Is there any concept of an invalid channel number for SSH channels, akin to
the Posix convention that -1 is always an invalid file descriptor/error status
value?  It'd be useful to have a never-valid value to use akin to the way -1
is used (or at least returned) for open/creat to indicate a non-file
descriptor.

Peter.

---

From: der Mouse <[email-masked]>
Date: Thu, 29 Jul 2004 12:11:03 -0400 (EDT)

> Is there any concept of an invalid channel number for SSH channels,
> akin to the Posix convention that -1 is always an invalid file
> descriptor/error status value?  It'd be useful to have a never-valid
> value to use akin to the way -1 is used (or at least returned) for
> open/creat to indicate a non-file descriptor.

For channel numbers assigned by your implementation, you can simply
make sure you never assign your favourite flag value (-1 or whatever),
and you're fine.

For channel numbers assigned by the peer, I don't think there are any
reserved values; you need to keep the valid bit somewhere else.  I
suppose you could build an implementation that croaks if the peer ever
uses channel 0xffffffff, but that strikes me as rather broken.

Since it's probably an ignorable possibility that the peer will ever
use all 4294967296 distinct channel numbers, you could perhaps track
what numbers have been used and use any number that hasn't as your
flag, switching if the peer uses your flag value.  It'd mean some
interesting tapdancing and would likely be more complex than just
keeping a separate valid bit, but it could be done.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       [email-masked]
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

---

From: Jon Bright <[email-masked]>
Date: Thu, 29 Jul 2004 18:36:24 +0200

> is used (or at least returned) for open/creat to indicate a non-file

Just on the offchance that someone's already implemented with channel 
numbers counting down 0, -1, -2, I'd guess 0x80000000 might be a safer 
value to pick.  I admit it's unlikely, but nonetheless...

-- 
Jon Bright
Silicon Circus Ltd.
http://www.siliconcircus.com

---

From: Bill Sommerfeld <[email-masked]>
Date: Thu, 29 Jul 2004 13:14:34 -0400

It looks like the answer to Peter's original question is a clear "No,
there is no reserved channel number".

(In any event, you likely need more than just a channel number to track
peer channel state, so a valid bit or state variable doesn't seem like
such a big deal.  no reason to change the protocol..)

					- Bill

---

From: [email-masked] (Peter Gutmann)
Date: Sat, 31 Jul 2004 18:02:27 +1200

der Mouse <[email-masked]> writes:

>reserved values; you need to keep the valid bit somewhere else.  I suppose
>you could build an implementation that croaks if the peer ever uses channel
>0xffffffff, but that strikes me as rather broken.

Actually there's another reason for requiring this (just dug it up from an old
code comment): When you get a channel-specific request (channel open, channel
request, etc), you're supposed to send back a succeeded or failed status.  How
do you send back a response for the condition that you couldn't parse the
request to the point of finding the channel number to use in the response?

Peter.

---

From: der Mouse <[email-masked]>
Date: Sat, 31 Jul 2004 02:41:30 -0400 (EDT)

> When you get a channel-specific request (channel open, channel
> request, etc), you're supposed to send back a succeeded or failed
> status.  How do you send back a response for the condition that you
> couldn't parse the request to the point of finding the channel number
> to use in the response?

There is no such condition, because if you can't parse the request, you
have no request to respond to, so you don't have to worry about framing
any particular kind of response to it.  You can of course send a "you
sent me something I couldn't make head nor tail of" error, but that's
very different from an error response to a channel-specific request.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: [email-masked] (Peter Gutmann)
Date: Sat, 31 Jul 2004 19:34:16 +1200

der Mouse <[email-masked]> writes:

>There is no such condition, because if you can't parse the request, you have
>no request to respond to, so you don't have to worry about framing any
>particular kind of response to it.

Does the spec say this anywhere?  I can see an implementation hanging while
waiting for a response to a request that'll never arrive if you don't send it
back at least some sort of response.  Not replying seems somewhat broken to
me, if the spec says (as it seems to) that you need to send back a "succeeded"
or "failed" response then not sending back anything under some conditions
seems wrong - you've detected an error, you should send back some indication
of this.

>You can of course send a "you sent me something I couldn't make head nor tail
>of" error, but that's very different from an error response to a channel-
>specific request.

The only error message mechanism that I can see if you can't send a request-
failed response is a full disconnect, which is rather drastic if there are
(for example) valid data transfers in progress on other channels at the time.

Peter.

---

From: Joseph Galbraith <[email-masked]>
Date: Sat, 31 Jul 2004 11:06:02 -0600

> seems wrong - you've detected an error, you should send back some indication

 From section 5.4:

      byte      SSH_MSG_CHANNEL_REQUEST
      uint32    recipient channel
      string    request type in US-ASCII characters only
      boolean   want reply
      ... type-specific data

    If want reply is FALSE, no response will be sent to the request.
    Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS
    or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation
    messages.  If the request is not recognized or is not supported for
    the channel, SSH_MSG_CHANNEL_FAILURE is returned.

The channel number is part of the packet that is predefined.
Therefore, you can always parse the channel number, and
send the response.

If 'want reply' is true, and you don't understand the request,
send failure.  If 'want reply' is false, don't send anything,
regardless of whether you understand the request.

This is the only way this can work (otherwise, it is not possible
to line up requests and responses.)  I'm also pretty sure we've
discussed it before in the working group, but I don't see in the
draft, that the responses must be made in order, in the case of
multiple requests.

I will admit, it would be nice if the final sentance was more
clear (or gone.)  If any change is needed, I would say something
like:

    If want reply is FALSE, no response will be sent to the request.
    Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS
    or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation
    messages.

    If the request is not recognized or is not supported for
    the channel, and 'want reply' is true, SSH_MSG_CHANNEL_FAILURE
    is returned.  If 'want reply' is false, the request is
    ignored.

    The client is allowed to send further messages without waiting for
    the response to the request.  Requests MUST be responded to in the
    order received.

    This message does not consume window space and can be sent even if no
    window space is available.  Request types are local to each channel
    type.

Thanks,

Joseph

---

From: der Mouse <[email-masked]>
Date: Sat, 31 Jul 2004 15:26:50 -0400 (EDT)

>>> How do you send back a response for the condition that you couldn't
>>> parse the request to the point of finding the channel number to use
>>> in the response?
>> There is no such condition, because if you can't parse the request,
>> you have no request to respond to [...]
> Does the spec say this anywhere?

Not specifically, but the spec does describ the syntax of channel
requests.  If the circumstance arises, either your request parsing is
severely broken or the sender's request generation is severely broken.
In either case, interoperability problems are only to be expected.

> I can see an implementation hanging while waiting for a response to a
> request that'll never arrive if you don't send it back at least some
> sort of response.

So can I.  But if it happens for this reason, it's the fault of the end
with broken code, and arises because of that broken code.  No matter
what we do, we can't make the protocol robust in the face of excessive
implementation brokenness.

>> You can of course send a "you sent me something I couldn't make head
>> nor tail of" error, but that's very different from an error response
>> to a channel-specific request.
> The only error message mechanism that I can see if you can't send a
> request-failed response is a full disconnect, which is rather drastic
> if there are (for example) valid data transfers in progress on other
> channels at the time.

Yes, it is.  But no more drastic than the sender sending a request so
badly mangled as to be unparseable - or, as the case may be, your
parsing code being so broken as to be unable to parse a valid request.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign