W3C home > Mailing lists > Public > public-webrtc@w3.org > February 2012

Fwd: Re: SCTP mapping to data channels

From: Randell Jesup <randell-ietf@jesup.org>
Date: Sat, 04 Feb 2012 13:52:33 -0500
Message-ID: <4F2D7E71.3010903@jesup.org>
To: "public-webrtc@w3.org" <public-webrtc@w3.org>
CC: Randall Stewart <rrs@lakerest.net>
Forwarded for Randall Stewart, who hasn't subscribed to the w3c list 
yet.  The ability to change the number of channels makes things much 
simpler!  Cool.  And the reset may be handy.


Comment in line..

On Feb 3, 2012, at 4:50 PM, Randell Jesup wrote:

>  On 2/3/2012 12:49 PM, Stefan Hakansson LK wrote:
>>  On 02/03/2012 06:41 PM, Harald Alvestrand wrote:
>>>  An advantage of bidirectional streams is that it doesn't matter which
>>>  end creates the data stream; with unidirectional, there either has to be
>>>  a flag stating the direction or a convention that the data sender (or
>>>  receiver) always creates them.
>>  Or different objects; the one creating the dataStream has a "sink" and
>>  the the receiver a "source". But I think it is simpler if they are
>>  bi-directional.
>  I believe I agree - it's simpler for the application developer; I see no real advantage to their being unidirectional.  (RTP is (normally - symmetric RTP) bidirectional as well).
>  I should note that SCTP per-se considers streams unidirectional, but typically applications tie a pair of streams together, one in each direction.
>  Internally we could handle this by creating the reverse channel automatically when we hear the forward channel is "created".  Which brings the next big thing that people may not be realizing:
>  *** SCTP streams (within an association) have no "open" or "close" ***
>  The number of streams in each direction is negotiated at association creation; and they're all available from that point (and the number cannot be changed during the association).

The statement in the () is not true. The last RFC on SCTP that just went out called stream-reconfiguration
allows one too:

1) Add more streams
2) reset the stream sequence number in a stream to 0

and a few other items.

The BSD implementation supports this but in an older version of the drafts.. I believe one of Michael
and I's agenda items for paris is to bring the stream reset code into full conformance to the RFC (which
is not a lot of work but needs doing).

>   The application decides what to do with data arriving on a stream.

This is always true ;-)

>  In terms of number of data channels, that could be specified in the peer connection before it's connected to the far end.  (An application should be able to do this, since all the data on those channels is specific to the application.)  If the application will use a dynamic number, it should specify the max in use at one time.  [OPEN ISSUE: what's the overhead for specifying extra channels you don't really need?]

Streams take about 24 bytes in each direction if I remember right.. could be a bit less.

But with the add-streams feature you can start small.. note you cannot delete streams though

>  In our case, the WebRTC implementation will be sctp_recvmsg()ing the data, which will come with a stream value for each chunk.  We'll use that to de-multiplex the data to the correct JS data channel.
>  Just as an FYI, the linux SCTP api:
>  int sctp_sendmsg(int sd,
>                  const void * msg,
>                  size_t len,
>                  struct sockaddr *to,
>                  socklen_t tolen,
>                  uint32_t ppid,
>                  uint32_t flags, // UNORDERED, etc
>                  uint16_t stream_no,
>                  uint32_t timetolive,
>                  uint32_t context);
>  We have some options:
>  1) use an API that preserves that behavior up to the JS app.  This is a lower-level, handle-all-the-options-yourself interface between SCTP and the JS app.  Powerful but ugly and prone to misuse; requires more app code.
>  2) use an API that's closer to the current "define a channel and use it" behavior.  This is closer to typical JS idioms, using a hints object to set the default behavior of each channel.  These channels could be made to be bidirectional within our layering.  Internally, each would map to a stream in each direction.
>  Note that we need to be careful about this - if we just blindly use an "unused" stream and we expect bidirectionality, it may race (glare) with an attempt to do the same from the other end.  So, it may be better to signal that usage over some sort of control channel or via some type of signaling.
>  Typically, protocols using SCTP use stream 0 as a "control" stream, much as I'd laid out in my "FTP-like" example a while ago.  ("I'm sending file X on stream Y now", etc).  This is not required and is totally up to the application.

This is true.

[patching together two messages from Randall - he had to stop and continue later]

> We*could*  define that stream 0 is our control channel for handling the mapping of pc.createDataChannel() calls; used to inform the other end about them and any meta-data like labels (though I don't think in this usage they're needed) and type of stream (though SCTP itself doesn't require streams in opposite directions be correlated).  We also could use the PPID field for control info (see below).  In either case, we don't need to signal dataChannel creation/removal through the server (and SDP and JSEP), and I'd strongly recommend avoiding SDP/JSEP here.
> We can either (again) expose the details to the JS app, or we can hide them behind dataChannel abstractions.
> I propose we retain most of the current proposed JS API, which is a dataChannel abstraction layered on top of the SCTP channels.  Unlike raw SCTP, the application would specify the mode of transport for the dataChannel (raw SCTP allows you to set the reliable, unreliable, etc bits on each individual datagram at sctp_sendmsg() time, so a stream can be a mix of reliable and unreliable datagrams - powerful, but not used often and confusing).
> At createDataChannel() (or what-have-you) time, we would (via hints) specify the type of data channel (reliable, unreliable, etc).  We would use that to notify the other side of the creation (over SCTP stream 0), and (if we choose bidirectional) the other side would set up the reverse stream.  The stream used for the dataChannel would be picked by the two ends via some mechanism.
> Note that if we only support unidirectional channels, this is simplified - it's just a notification.  Unidirectional would imply we have dataChannelOutgoing objects and dataChannelIncoming objects (both can inherit if we want from dataChannel).
> Removing a data channel would throw the stream "back into the pool" to use for createDataChannel/etc.

You could, if you wanted, at that point do a stream-reset to reset the 
SSN back to 0 when you were done. This also gives the peer a reset 
indication that tells them that the stream was reset... a lot of app's 
find this handy as a way to "add it back to the pool" with SCTP 
providing the notifications that it was done to the peer

> We also have the PPID field we can use (Payload Protocol Identifier); it's an opaque value (to SCTP) that can be attached to each DATA chunk.  That presents on option to use that to put the "signaling" data for each stream in the stream itself (for unidirectional streams at least), by using a specific PPID value saying basically "this is metadata about the stream".  These metadata messages would also specify reliable in-order delivery.
> Even if we want to do bidirectional the in-stream metadata messages could be used to handle that; we'd need a handshake and "glare" resolution mechanism to decide which attempt to open the stream would get punted to another stream number.  That would avoid us needing a control channel (I believe; this is based on reading examples and APIs).
> Randall, how does all this sound to you?  Did I misunderstand the API/protocol in some way, or do I have the gist of it correct? (Randall, if you're not a member of the W3 list and want to respond to everyone you should subscribe first - it's lower volume than rctweb.)
Hmm opps I am not a member and just got to this after my previous 
reply.. sorry

where do I sign up..

As to most of this, yeah you are correct. Apps have a *lot* of 
flexibility built into the API... so that you can do what you want.. 
uni-directional, bi-directional.. use specific streams as always 
reliable or not...

Some notes on the PPID field

1) You must remember to put it in/take it out of network byte order.. 
SCTP does not touch it since it is opaque... so if you are different 
types of machines a ntohl()/htonl() will be in order.

2) Its a IANA controlled field. I.e. you should get a IANA approved 
number.. they are given out on a first come first serve basis with no 
real restrictions.. If I remember right is you ask for one and tell it 
what you will call it.. thats about it.

PPID's are actually quite useful for markings and a lot of apps use 
them.. Of course some don't bother getting a IANA approved code-point 
and just use the space themselves.. which you know would happen anyway.. 
if all I talk to is my set other app, I don't have to worry about it. 
Only when you want to inter-operate (like you are doing I would imagine) 
do you need a IANA assigned code-point..

Well, I have to run, if you want forward my emails.. if not bounce back 
to me the sign up address and I will add myself and resend my emails. 
need to head up to my hotel near SFO R

Randall Stewart
803-317-4952 (cell)
Received on Saturday, 4 February 2012 18:54:38 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 15:19:27 UTC