Subject: Re: SCTP API section 5.2.2

From: Michael Tuexen <[email-masked]>
Date: Tue, 1 Mar 2005 10:18:03 +0100

Hi David,

see my comments in-line.

Best regards
Michael

On Feb 28, 2005, at 22:14 Uhr, David Lehmann wrote:

> Hello,
>
> In section 5.2.2, the I-D states:
>    sinfo_ppid: 32 bits (unsigned integer)
>
>    This value in sendmsg() is an opaque unsigned value that is passed 
> to
>    the remote end in each user message.  In recvmsg() this value is the
>    same information that was passed by the upper layer in the peer
>    application.  Please note that byte order issues are NOT accounted
>    for and this information is passed opaquely by the SCTP stack from
>    one end to the other.
This means that the user has to do the htonl() call before the send call
and ntohl() call after the receive call. It is NOT done by the 
SCTP-implementation.
>
> The last sentence concerns me.  Is this stating that the ppid will
> not be sent up to the user in host byte order?  As stated, it sounds
> like that if I have a server which examines the ppid, I will get a
> different value depending if the application sent the data from an
> Intel box as opposed to a Sparc box.
The SCTP user must provide it in network byte order and receiver
must expect it in network byte order.
>
> If the last sentence was trying to say that the ppid will be passed up
> in network byte order, can it be reworded to plainly say so?
>
>
> -- 
>
> David Lehmann
> Ulticom, Inc.
> http://www.ulticom.com

---

From: David Lehmann <[email-masked]>
Date: Tue, 01 Mar 2005 08:51:45 -0500

Michael Tuexen wrote:
>>    This value in sendmsg() is an opaque unsigned value that is passed to
> ...

That was a lot of words just to state that it is in network byte
order. For a couple fields, the draft does explicitly says that
the values are in "network byte order."

IMHO, the draft should be explicit for all fields.  Maybe for each
structure, the draft should state something like:
     "All members of struct sctp_xxxx are in network byte order,
      except for member3 and member6, which are in host byte order."

-- 

David Lehmann
Ulticom, Inc.
http://www.ulticom.com

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 01 Mar 2005 11:27:11 -0800

> the values are in "network byte order."

Actually, even though the sinfo_ppid is "supposed" to be
a 32 bit integer, it is really opaque to the SCTP stack and
socket layer.  So the app may as well put 4 8 bit bytes
there.  Specifying any byte order in the text is probably
not correct.  This also applies to the sinfo_context.

-- 

						K. Poon.
						[email-masked]

---

From: David Lehmann <[email-masked]>
Date: Tue, 01 Mar 2005 15:29:16 -0500

> not correct.  This also applies to the sinfo_context.

I think that I would have to disagree.  This is a 32-bit value
which is sent over the network and read by the peer SCTP user.
The payload protocol has to be interpreted by the upper layer.
There is nothing in RFC 2960 that makes this field different
from any other field (e.g. the stream number, SSN, etc) in
this regard.

In addition, when Sigtran protocols define the payload
protocol ID, they just specify the number.  (e.g. 2 for
M2UA.  See RFC 3331, section 8.1. M2UA doesn't specify
which of the four bytes should be set to 2.)

The sinfo_context, OTOH, should be opaque.  It is passed
by the user to SCTP, which may send it back to the _same_ user.
The sinfo_context does not get sent over the network.
Since the user that is interpreting the sinfo_context
value is the _same_ user that created the value, it makes
sense that it is opaque.

>>      except for member3 and member6, which are in host byte order."

I still think the above clarification should be made for each
structure.

-- 

David Lehmann
Ulticom, Inc.
http://www.ulticom.com

---

From: Randall Stewart <[email-masked]>
Date: Tue, 01 Mar 2005 16:54:51 -0500

> from any other field (e.g. the stream number, SSN, etc) in

The word opaque in the spec does make it different.
Data is also opaque.. do you want the SCTP stack
playing around with what it "thinks" are int's..

You don't. And I do agree with Kacheong completely here.. an
app can in theory put 4 8 bit values or 2 16 bit values or
whatever it chooses to do with the field...

You can't say what byte order they are in since the user
can do a ntohl() on them or NOT .. and so it is opaque as
the original text in 2960 said...

> which of the four bytes should be set to 2.)

Well.. then they need to specify that its a 2 in
network byte order...

> value is the _same_ user that created the value, it makes
Opaque is opaque.. the SCTP stack will place the data
in the packet in PPID terms and NOT touch it.. the same
with the data on the wire... the stack may bust it up
into chunks and re-assemble it .. but it will not touch
in bytes to change the "byte order".

and the context field will of course be opaque as well.. its
less likely to have a byte order issue though.. since as you
say, it remains on the same machine...

R

-- 
Randall Stewart
ITD
803-345-0369 <or> 815-342-5222

---

From: David Lehmann <[email-masked]>
Date: Wed, 02 Mar 2005 08:42:50 -0500

> the original text in 2960 said...

RFC 2960 says that the payload protocol ID _is_ a 32 bit unsigned
integer AND it is in network byte order.

RFC 2960, section 3:
-----------------------------------------------------------------
3.  SCTP packet Format

    An SCTP packet is composed of a common header and chunks. A chunk
    contains either control information or user data.

    ...
    All integer fields in an SCTP packet MUST be transmitted in network
    byte order, unless otherwise stated.
-----------------------------------------------------------------

RFC 2960, section 3.3.1:
-----------------------------------------------------------------
3.3.1 Payload Data (DATA) (0)
    Length:  16 bits (unsigned integer)
    TSN : 32 bits (unsigned integer)
    Stream Identifier S: 16 bits (unsigned integer)
    Stream Sequence Number n: 16 bits (unsigned integer)
    Payload Protocol Identifier: 32 bits (unsigned integer)

-----------------------------------------------------------------

RFC 2960 is clear: the Payload Protocol Identifier _is_
a 32-bit unsigned integer AND since it is an integer field,
it MUST be sent in network byte order.

So even though SCTP treats the value as opaque (i.e. it is not
interpreted by SCTP), the SCTP _user_ may interpreted it and
expects a 32-bit unsigned integer.

-- 

David Lehmann
Ulticom, Inc.
http://www.ulticom.com

---

From: Randall Stewart <[email-masked]>
Date: Wed, 02 Mar 2005 10:39:17 -0500

> integer AND it is in network byte order.

And you missed:

    o  payload protocol-id - A 32 bit unsigned integer that is to be
       passed to the peer indicating the type of payload protocol data
       being transmitted.  This value is passed as opaque data by SCTP.
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This is the statement that is illustrated by:

             ^^^^^^^^^^^^^^^^^^^^^^^

Yes, maybe that is not clear.. that is what the recent I-G is trying
to clear up... Its opaque.. it states so to tell you that SCTP
will NOT muck with whatever the app sends. If the app wants
to send it has a 4 byte integer then it needs to be doing
ntohl()/htonl(). If instead it wants to use it has a
4 byte character string.. its welcome to do that too... Its
up to the APP since it is "opaque".

And 2960 specifically added the 'opaque' wording to tell you
that it will NOT be necessarily in network byte order.

R

---

From: David Lehmann <[email-masked]>
Date: Wed, 02 Mar 2005 15:45:25 -0500

>       being transmitted.  This value is passed as opaque data by SCTP.

No, I didn't miss that.  I understood it to mean that it is opaque
to SCTP since SCTP does nothing with it.  But it is not opaque
to the SCTP user.

> byte order, unless otherwise stated.

IMHO, it wasn't otherwise stated.  If it was otherwise stated, I would
have expected something more explicit like: "This value is not transmitted
in network byte order." to counter act the explicit statement in
section 3.

> up to the APP since it is "opaque".

Yep, the RFC is not only unclear, but misleading.  The RFC calls
it a 32 bit unsigned integer.  How else do you expect someone
to interpret that?

Doesn't Ethereal interpret it as a 32-bit unsigned integer in
network-byte order?  Can the Ethereal people comment?

> that it will NOT be necessarily in network byte order.

OK.  (I seem to be losing sight of the purpose of this
field.  It seems to me, it is just wasted bandwidth.  If a user
protocol just needed four extra bytes, it should just put them in
its own headers.)

Regardless of all the misunderstanding above, it still comes
down to an API issue.  Since the sinfo_ppid is presented as a 4-byte
unsigned integer (not four separate bytes), either the user of
the API or the socket library that is implementing the API has to do
the htonl() when sending and ntohl() when receiving... regardless
of whether it is two 2-byte values, one 4-byte value, or
four 1-byte values.  In order to extract the proper values from
the given uint32_t somebody has to do the ntohl()/htonl().

The only other way around it is to cast the pointer to sinfo_ppid
to a (char *) and manually place each byte into the payload id.
Do we really expect users to do such a thing?
If so and if the protocol ID is truly opaque, shouldn't it be
four separate bytes?  (I am not recommending this.)

I may be going out on a limb, but I think the vast majority of the
users will use it as an unsigned 32-bit integer and will be forced
to ntohl()/htonl() it themselves.  This is not a problem, but
the API text should clearly state it.

-- 

David Lehmann
Ulticom, Inc.
http://www.ulticom.com

---

From: Michael Tuexen <[email-masked]>
Date: Wed, 2 Mar 2005 23:08:11 +0100

Dear all,

I'm not sure why we are so controversial here.

I think it is clear that the text is not clear:
- David had questions.
- the Linux guys did it wrong in the first versions.

What does IANA say (http://www.iana.org/assignments/sctp-parameters):
SCTP Payload Protocol Identifiers                         REFERENCE
---------------------------------                         ---------

   1 - IUA                                                 [RFC3057]
   2 - M2UA                                                [RFC3331]
   3 - M3UA                                                [RFC3332]
   4 - SUA                                                 [RFC2960]
   5 - M2PA                                                [RFC2960]
   6 - V5UA                                                [RFC2960]
   7 - H.248                                                 [H.248]
   8 - BICC/Q.2150.3	                            [Q.1902.1/Q.2150.3]
   9 - TALI                                                [RFC3094]
  10 - DUA        <draft-ietf-sigtran-dua-03.txt>              [Ong]
  11 - ASAP       <draft-ietf-rserpool-asap-03.txt>            [Ong]
  12 - ENRP       <draft-ietf-rserpool-enrp-03.txt>            [Ong]
  13 - H.323                                                 [H.323]
  14 - Q.IPC/Q.2150.3                              [Q.2631.1/Q.2150.3]

What is the intention of the PPID? RFC 2960 says:

       This value represents an application (or upper layer) specified
       protocol identifier.  This value is passed to SCTP by its upper
       layer and sent to its peer.  This identifier is not used by SCTP
       but can be used by certain network entities as well as the peer
       application to identify the type of information being carried in
       this DATA chunk. This field must be sent even in fragmented DATA
       chunks (to make sure it is available for agents in the middle of
       the network).

       The value 0 indicates no application identifier is specified by
       the upper layer for this payload data.

Ethereal is one of these network entities, which uses the it as an 32 
bit
unsigned integer to find the upper layer protocol and dissect the
user data. It is possible (and we use this in RSerPool) to bundle
to DATA chunks with different upper layer protocols.

This means that all applications I know use the field as an integer.

What does the socketapi ID say:

    struct sctp_sndrcvinfo {
       uint16_t sinfo_stream;
       uint16_t sinfo_ssn;
       uint16_t sinfo_flags;
       uint32_t sinfo_ppid;
       uint32_t sinfo_context;
       uint32_t sinfo_timetolive;
       uint32_t sinfo_tsn;
       uint32_t sinfo_cumtsn;
       sctp_assoc_t sinfo_assoc_id;
    };

This is a 32 bit integer. Of course, you can put anything in it
(four 8 bit chars, two 16 bit ints), but you pass it AS AN INTEGER.
And the important thing is, that the SCTP implementation does NOT
change it. At least, this is what Solaris, Linux and KAME do. Since
I have no other stack in my lab, I do not know what other 
implementations
do.

So why not change

to

    This value in sendmsg() is an unsigned integer that is passed to
    the remote end in each user message.  In recvmsg() this value is the
    same information that was passed by the upper layer in the peer
    application.  Please note that the SCTP stack performs no byte
    order modification of this field. For example, if the DATA chunk
    has to contain a given value in network byte order, the SCTP user
    has to perform the htonl() computation.

Best regards
Michael

---

From: Randall Stewart <[email-masked]>
Date: Wed, 02 Mar 2005 18:16:32 -0500

Sounds fine to me... I like your
clearification :-D

R

Michael Tuexen wrote:
> Ethereal is one of these network entities, which uses the it as an 32 bit
> I have no other stack in my lab, I do not know what other implementations
> do.
> 
> So why not change
>

---

From: David Lehmann <[email-masked]>
Date: Thu, 03 Mar 2005 08:12:22 -0500

Agreed.

-- 

David Lehmann
Ulticom, Inc.
http://www.ulticom.com