Subject: [rtcweb] Data Channel Negotiation

From: Martin Thomson <[email-masked]>
Date: Thu, 7 Feb 2013 06:22:15 -0500

We're a fickle lot.  It seems that decisions can be unmade very easily.

In any case, I promised a concrete proposal.  Here it is.  Beware:
long post ahead.

This proposal is progressive, I think that the best option would be to
take all of it, but we could choose to not adopt the later parts.
I'll start with the basics.

==Layer 1

Negotiate all new data channels with SDP offer/answer.

As I understand it, the 1.5 round trip cost for in-band channel
creation was to prevent glare.  (Randell hinted that there might have
been something else that was SCTP-specific, but this appears to reduce
to a straightforward glare situation.)  Doing the negotiation in SDP
lets us use the glare mitigation mechanisms we have built into SDP, so
we save 0.5 round trips for every new channel.

This allows us to ditch the in-band signaling protocol almost entirely
(see Option B below).

Creating a new data channel triggers the onnegotiationneeded event.

==Layer 2

Zero round trip channel establishment

The only reason that we have for negotiation of each channel is to
provide a consistent set of characteristics for each channel.  The
peer that creates a channel decides the values for label,
retransmission count (0, n, infinite), and subprotocol.  If you don't
care about these values being consistent between peers, or you have
another means of ensuring consistency, you don't need to negotiate new
channels at all.

Here, we permit the use of additional channels immediately after
creation, without negotiation.  This has several advantages...and
ramifications.  And no real drawbacks.

Firstly, the arrival of a packet on a stream that is not negotiated
will require the creation of a data channel.  The properties of this
data channel will be largely unknown. The browser can possibly detect
that the channel is unreliable if the packet doesn't request
acknowledgement, but that's something I'm not 100% clear on for
partially reliable messages.  As a result, the browser will be
required to leave these properties undefined or generate default
values for them.

It's perfectly OK to have default or undefined values for label,
reliability and subprotocol as long as you let the application set new
values.  This allows for another advantage: applications can, if they
choose, set the reliability on a per-packet basis, consistent with all
other SCTP APIs, but setting the property before sending each packet.
This keeps the simplicity of the API design, ensures websocket
compatibility for those that need it, but it exposes more SCTP
capabilities to those that desire those features.

This does have consequences for negotiation: Values for label,
reliability and subprotocol need to be declarative in SDP, not
negotiated.  Both peers would be required to signal the values that
they are using for each stream.  This would allow for the fact that
peers could set different values for the same stream number, based on
whatever values are set on their data channel object.  In the general
case, it allows one peer to declare the use of a particular stream and
the other peer to not advertise anything on the matching stream.

This also makes the 'onopen' event useless for all but the first
channel.  It should fire immediately for any channel that is created
when the association is already active.

Receipt of a message on a channel that has not already been created
locally causes the following events, one after the other:
ondatachannel, onopen, onmessage.

In order to maintain the symmetrical usage pattern, and the
websockets-compatible usage pattern, we would then require several
things:
1. The browser MUST, by default, negotiate streams with values that
match any in an offer if it does not already have a data channel for
that stream number.  The browser MUST also create the corresponding
data channels.
2. Applications that require perfect channel symmetry need to
negotiate before using streams.
3. Applications that care about having their use of the API be
interchangeable with websockets need to wait for the 'onopen' event
before sending anything, lest they get errors when switching to
websockets.

On that last point: We could require that channels reject attempts to
send() prior to the onopen event being processed, but that is
unnecessarily mean.  Calling createDataChannel() followed immediately
by send() should be OK as long as the association is active.  Just
because you haven't processed the 'onopen', doesn't mean that you
should be prevented from using a perfectly usable channel.  Of course,
waiting for onopen would be safest in the general case, and many
applications would naturally do this, but I see no reason to constrain
usage patterns unnecessarily.

===Option A

Removing the in-band protocol makes the negotiation of the protocol
that layers on top of SCTP less crucial ... it makes negotiation of
the upper-layer protocol less crucial.  In the WebRTC case, we
probably don't need to negotiate 'webrtc-datachannel', we could even
let the application decide the value for that label.

Personally, I don't think that we need to surface API to enable
changing protocols.  However, it would be completely harmless in this
configuration for an application to change the protocol label to
something else by editing SDP, so that they could interoperate with a
peer that expected another protocol.  That would enable CLUE usage, or
BFCP, or whatever, as long as you can find someone who talks SCTP over
DTLS over UDP.

===Option B

The one remnant of the in-band protocol that remains is the parts that
apply to the data payloads.  The in-band protocol is required to
provide two features:
1. the ability to distinguish between textual data and binary data
2. the ability to send messages of arbitrary length

I am sorely tempted to suggest that the first feature can instead be
part of channel configuration, such that it is negotiated (with a
default of binary).  This would mean that negotiation is needed if you
want to use text and you can't handle the conversion of binary to
text.  (Sadly, this isn't made easy and the top answer at
stackoverflow doesn't work for UTF-8:
http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers)

For the second, draft-jesup-rtcweb-data-protocol indicates that 2Gb is
the limit, but my reading of RFC 4920 indicates that there is no limit
to message size.  I'm far from expert in this area, but is it possible
that this is an implementation limitation rather than a protocol one?
Either way, I'm tempted to suggest that fragmentation can be pushed to
the application.

This would allow for direct access to SCTP, rather than an
encapsulated layer.  This is good for several reasons.  Firstly, we
don't need to specify a protocol at all.  We avoid all the arguments
about what byte goes where.  More importantly, it leaves the SCTP
clean, allowing WebRTC applications to use SCTP without ornamentation.

===Option C

If you care about reconciling the values for label, reliability, and
subprotocol, it might be necessary to surface the values declared by
your peer in the API.  You can get this information from the SDP, but
if you don't like the idea of SDP spelunking you have two choices:
provide an 'on(re)negotiated' event that carries the values declared
by the remote peer; or, provide read-only accessors for these.

I'm not certain that reconciliation of these values is important.
Applications can even build their own mechanisms if it is.  If we must
build more mechanisms, then I tend to favor the 'on(re)negotiated'
event.

---

From: Randell Jesup <[email-masked]>
Date: Thu, 07 Feb 2013 10:49:42 -0500

> we save 0.5 round trips for every new channel.

The SCTP-specific thing requiring the ACK was to avoid an in-band issue 
(need to review mail archives with the SCTP authors to find it), so it 
wouldn't apply here.  I think it was only need to be able to tell the 
app for *sure* that the other side had processed the openresponse, but 
I'm not certain.

> Creating a new data channel triggers the onnegotiationneeded event.

This solution will work.  It means you're beholden to SDP and 
negotiation with the app involved.  I've always tried to avoid 
re-negotiation wherever possible; renegotiation is rife with 
hard-to-track-down timing and other issues.

> another means of ensuring consistency, you don't need to negotiate new

In fact, the current design (in-band protocol or the 'mixed' (2b) 
proposal) doesn't actually negotiate them - they're declarative. The 
response merely tells the creator what the opposite-direction stream 
number is (or if there was some failure).

> negotiated.

The proposal I made yesterday (though I really didn't get a chance to 
present it) was purely declarative in the SDP (the mixed case I 
proposed).  They were stand-ins for the Open in-band messages and 
carried the same declarative info.

>   Both peers would be required to signal the values that

I'll note this is virtually the same as the original in-band protocol 
suggestion from Stockholm, with the loss of symmetry and labels.  The 
original proposal has the first message on a  stream be an Open message, 
but you can call Send() immediately.  We could fire onOpen immediately 
for WebSockets compatibility (without waiting for an OpenResponse); 
since we're declarative, this isn't unreasonable even semantically 
different than what causes onOpen in Websockets.

The downside(?) would be you have actual Open/OpenResponse/ACK(maybe).  
This also means there's no need to ever specify the channels in the SDP 
or renegotiate; all channel opens are 0 RTT effectively.

We previously had discussed exposing the full SCTP per-packet options, 
and generally people saw this as minimally useful and adding 
considerable confusion/complexity to web app authors.  Given you can 
open any number of channels with different characteristics the user 
isn't that constrained by this.

> by send() should be OK as long as the association is active.

The wire protocol I've speced in draft-jesup-datachannel-protocol (sp) 
allows for send immediately after createDataChannel.  I agree and see no 
reason not to allow the JS to do this, though I think there was some 
disagreement last time from the W3 side.  However, this is not a real 
issue if you're going to fire onopen immediately on both sides.

>    Just

They'd need to support SCTP over DTLS over ICE, and they'd need to 
support JSEP (or you'd need to somehow fake a response)
Is this an actual usecase?  If so, it hasn't been really surfaced 
before; could you expand on what this really means and how it would work?

If this is an important usecase (examples!), then we can move Open 
notifications over to a control channel.  This could be a wireline 
protocol in the browser (basically the same as the current wireline 
protocol with a field or two added).  Or as you say you push it all off 
into the application - but that means simple uses need a lot more 
boilerplate or JS-implement network protocol that many of these authors 
aren't familiar with.

> http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers)

this would introduce a significant incompatibility with Websockets I 
believe.

> Either way, I'm tempted to suggest that fragmentation can be pushed to

This limit probably can be relaxed; Websockets allows IIRC 71-bit 
lengths ...  just in case you need them.

The practical limit is likely lower in that it returns a single 
arraybuffer/blob.  Right now Firefox limits Websockets to 2Gb.

> clean, allowing WebRTC applications to use SCTP without ornamentation.

Sure, we can expose raw (or virtually raw) SCTP.  This was my original 
proposal over a year ago.  For what I think are good reasons, we pretty 
definitively decided on a simpler API for the JS programming API and in 
the wireline, and had left that decision lie since then.

> _____________________________________________

I like (a lot) the declarative approach, and all the complications were 
due to needing to fulfill glare considerations (now resolved by not 
requiring resolving of label glare and not requiring bidirectional 
stream pairs have the same number), and due to the requirement for 
websockets compatibility with onOpen (and to not fire it until you have 
positive notification from the other side). If you drop that last part, 
you have immediate declarative 0-RTT opening time DataChannels.  I would 
propose keeping things simpler for users and to use the wireline 
protocol for the declaration/response, and avoid all the weirdnesses 
around labels, protocols and modes caused by dropping it.

I like your Layer 2, but with the wireline protocol previously speced.  
It gets you all the label/mode/etc sync stuff, and merely rules out 
option A (or requires you to dedicate a control stream).

-- 
Randell Jesup
[email-masked]

---

From: Martin Thomson <[email-masked]>
Date: Fri, 8 Feb 2013 04:21:48 -0500

On 7 February 2013 10:49, Randell Jesup <[email-masked]> wrote:
> present it) was purely declarative in the SDP (the mixed case I proposed).
> They were stand-ins for the Open in-band messages and carried the same
> declarative info.

The difference, from what I saw, was that the declarations in your
examples showed stream 1 in the offer and no stream 1 in the answer.
This would require that stream 1 appear in the answer with the
attributes that the answerer had assigned (which we would require to
be the same as the offerer, unless the answerer side had already had
created a DataChannel).

> This limit probably can be relaxed; Websockets allows IIRC 71-bit lengths
> ...  just in case you need them.

63 bit.  A poor decision in my opinion, but we need to respect working
group consensus.

> arraybuffer/blob.  Right now Firefox limits Websockets to 2Gb.

This is definitely an implementation choice.  I expect lower limits in
many implementations.  Desktop browsers probably need to be a little
more flexible than most.

> I like (a lot) the declarative approach, and all the complications were due
> to needing to fulfill glare considerations (now resolved by not requiring
> resolving of label glare and not requiring bidirectional stream pairs have
> the same number), and due to the requirement for websockets compatibility
> with onOpen (and to not fire it until you have positive notification from
> the other side). If you drop that last part, you have immediate declarative
> 0-RTT opening time DataChannels.  I would propose keeping things simpler for
> users and to use the wireline protocol for the declaration/response, and
> avoid all the weirdnesses around labels, protocols and modes caused by
> dropping it.
>
> I like your Layer 2, but with the wireline protocol previously speced.  It
> gets you all the label/mode/etc sync stuff, and merely rules out option A
> (or requires you to dedicate a control stream).

If we have out-of-band negotiation, the only thing that the protocol
needs is a type indicator (one bit).  Reserve the other 7 bits (or 254
values) and we're done.  There is no benefit to the control messages.

---

From: Michael Tuexen <[email-masked]>
Date: Fri, 8 Feb 2013 18:43:54 +0100

Hi Martin,

just a few comments/questions in-line.

Best regards
Michael

> Creating a new data channel triggers the onnegotiationneeded event.
The signaling channel might have a different RTT than the peer to peer
connections. So you prefer to do take always the signaling channel.
Taking down a data channel is not signaled via SDP, right?

How do you handle a shortage in the number of streams? How do you
handle collisions if both sides want to open a data channel and
chose the same streams?
> retransmission count (0, n, infinite), and subprotocol.  If you don't
There is also a limitation of lifetime in milli seconds.
> another means of ensuring consistency, you don't need to negotiate new
So basically a data channel is not symmetric anymore. Do you consider
it bidirectional or unidirectional?
> will require the creation of a data channel.  The properties of this
If you consider a data channel to be bidirectional, what makes sure
that a stream for the backwards direction is available? How do you
now the pairing?
> partially reliable messages.  As a result, the browser will be
From an SCTP point of view: A receiver doesn't know that a particular
user message was sent reliable or not until it gets a FORWARD-TSN
chunk...
> capabilities to those that desire those features.
I guess most of this comes down to the question of uni-/bi-directional...
> to message size.  I'm far from expert in this area, but is it possible
Not sure why you refer to RFC 4920... RFC 4960 (SCTP) doesn't have such
a limit.
> clean, allowing WebRTC applications to use SCTP without ornamentation.
Going down this road: Do you consider data channels as abstractions
of SCTP streams? So uni-directional?
> _______________________________________________
> rtcweb mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/rtcweb
>

---

From: Randell Jesup <[email-masked]>
Date: Sat, 09 Feb 2013 10:24:44 -0500

> be the same as the offerer, unless the answerer side had already had

As I mentioned, it was purely declarative (no response/negotiation), 
which is why the return SDP doesn't have them.

If you were to extend this to work for renegotiations where glare is 
possible, you'd have to either wait for the renegotiation to finish, or 
use some even/odd sort of trick which was proposed way back when on the 
list.

> 63 bit.  A poor decision in my opinion, but we need to respect working

Ah yes, you're correct, 63 bits (encoded in 71 bits).  So small!

> values) and we're done.  There is no benefit to the control messages.

Out-of-band negotiation means either:

a) SDP offer/answer (which in many cases will go via a central server, 
though it can go over an existing datachannel), min 1 RTT (perhaps 
1-RTT-through-server) plus SDP processing delay, and requires 
implementing error handling for cases where the answers and offers don't 
properly match up,

b) a single control stream, which works, but it adds complexity since 
SCTP doesn't make between-stream guarantees about delivery, so you have 
to either have a handshake on the control stream before sending data (1 
RTT at least), or you need to have methods in place to handle 
out-of-order control versus data delivery, or

c) application-implemented out-of-band negotiation, which just (IMHO) 
pushes the problem off onto the application without solving any problems 
for the general case.  In the (fairly common) app talking to another 
instance of itself or a "known" peer, the application could pre-define 
what streams/channels mean, if we surface the stream numbers to the API 
(this would be far closer to the old 'raw SCTP' proposals, which push a 
lot over onto the app). This would also make interoperating in 
federation cases considerably more complex.

The reason the current in-band protocol uses in-stream open messages is 
that this avoids any out-of-order delivery issues (they're marked as 
reliable-in-order).  If you relax the don't-send-until-onopen JS 
requirement (which is no work for the wireline protocol; it's already 
supported) and fire onopen immediately on createDataChannel or when a 
channel open comes in, you have 0-RTT startup, and you retain all the 
symmetry, label, protocol, etc that had been previously agreed to.  See 
my quoted proposal above.

Are there real usecases where the in-band Open and OpenResponse messages 
actually cause a usecase not to work?

-- 
Randell Jesup
[email-masked]

---

From: Martin Thomson <[email-masked]>
Date: Mon, 11 Feb 2013 11:40:11 -0800

> connections. So you prefer to do take always the signaling channel.

But since you have a short path for this, you can take that path.
Some people may prefer to take the slower signaling path for this, but
those that care about speed will use the data channel to do channel
establishment (and they will probably do what I suggest below).

> Taking down a data channel is not signaled via SDP, right?

I believe that you are able to use in-band mechanisms (6525) for take-down.

> handle collisions if both sides want to open a data channel and

A shortage is easy, createDataChannel can throw an exception.

Collisions are also easy - if you care about consistency, then do an
offer/answer, which has inbuilt glare resolution.  If you don't care
about consistency, both sides can create and use channels without
having to agree on the details.  (That's mostly based on the stuff
below.

> There is also a limitation of lifetime in milli seconds.

Sure, let's have that too.  All this is per-message, so consistency
isn't really a required property.

> it bidirectional or unidirectional?

Yes.  Depending on the needs of your application.  Inherently, they
are unidirectional.  But if you care about the bidirectional property,
then you are free to perform a signaling negotiation to ensure
consistency (which is the only property that was provided by the
negotiation as designed previously).

> that a stream for the backwards direction is available? How do you

There is no guarantee.  Two reasons for this, neither of which I find
particularly dire:

a. I don't recall there being any signalling of the stream limit, so
there is a possibility that the stream limit in one direction will
exceed the limit in the other.  Streams with numbers that exceed the
lower limit will of course be unable to be reciprocal.  Two solutions
occur to me: 1. prevent the sending of return messages, or 2. cap the
number of channels to the lower of the two stream limits.  I prefer
the latter.

b. There is no guarantee that the other side hasn't already created a
data channel on the same number.  That's not a problem - you just end
up with asymmetry.

Note: deferring the allocation of a stream number until messages are
sent on streams does allow the browser implementation some flexibility
in how it manages assignment of streams.

> Not sure why you refer to RFC 4920... RFC 4960 (SCTP) doesn't have such
Crossed wires :)

---

From: Martin Thomson <[email-masked]>
Date: Mon, 11 Feb 2013 11:54:00 -0800

On 9 February 2013 07:24, Randell Jesup <[email-masked]> wrote:
> As I mentioned, it was purely declarative (no response/negotiation), which
> is why the return SDP doesn't have them.

Your examples didn't have the values for stream 1 echoed in the
answer, so I assumed that it was "semi-declarative" or something like
that: where the values for stream 1 were inferred.

> possible, you'd have to either wait for the renegotiation to finish, or use
> some even/odd sort of trick which was proposed way back when on the list.

If you want to resolve glare, then you use the mechanisms you already
have for glare resolution.  Which, RFC 3264 defers to RFC 3261, which
uses a fairly heavy-weight mechanism.  Keep in mind that you already
need this if you are using offer-answer.  Use whatever mechanism you
already have in place (I like the tie-breaker random number method
myself).

Or, you could stop worrying about glare and in those cases where glare
is possible, allow the collision to proceed.

This is an application choice.
> 1-RTT-through-server) plus SDP processing delay, and requires implementing
> error handling for cases where the answers and offers don't properly match
> up,

This was my thought.  There is no need to reserve a channel for this
purpose, that's just extra machinery.  Any app that wants the fast
path for this will make their own.  And, the nice thing about that is
that they can do this before setting up the session.

> actually cause a usecase not to work?

Well, given that we need message type stuff, we already have to suffer
some extra muck on top of the SCTP association.  Not many applications
will survive that.

No, the real question is: what value do these messages actually add?
What information do they convey that isn't already negotiated through
other channels?

Starting a stream with a header that declares attributes for a stream
sounds nice, but it's completely unnecessary in a vast number of
cases.  For many cases, this is a case of the same piece of software
talking to itself - it hardly cares.  In many other cases, negotiation
of properties through SDP is perfectly sufficient.

The only case I see for an in-band protocol is where you wish to
invent some new protocol on this platform, and I can't really muster
up that much enthusiasm for that.  It's far too heavily reliant on my
imagination.  Even in those cases, my knowledge of existing SCTP usage
patterns suggest that the properties that are sent in
Open/OpenResponse messages are not that useful to have.  Many
applications will use the same values for all new streams.

---

From: Michael Tuexen <[email-masked]>
Date: Mon, 11 Feb 2013 21:04:28 +0100

> No, the real question is: what value do these messages actually add?
One important thing is that they tie the two outgoing streams together.
Each side controls its outgoing streams.
The other things are just declaring channel properties...

Best regards
Michael

---

From: Michael Tuexen <[email-masked]>
Date: Mon, 11 Feb 2013 21:14:53 +0100

> I believe that you are able to use in-band mechanisms (6525) for take-down.
Sure. The goal of my questions is to understand your proposal better...
> having to agree on the details.  (That's mostly based on the stuff
However, *if* data channels are bidirectional (which they currently are),
then you need to tie two streams together. This has to be done somehow.
I'm wondering how you envision this without using SDP and without the
data channel protocol...
> isn't really a required property.
OK.
> negotiation as designed previously).
If we change to data channels being uni-directional, then most of
the stuff done by the data channel protocol is not required... I agree
with that conclusion.
However, currently that the bi-directional.
> occur to me: 1. prevent the sending of return messages, or 2. cap the
Instead of "prevent sending the return message" which would one side
waiting forever, I would prefer sending some sort of error message
(which is currently not specified enough in the data channel protocol).
> number of channels to the lower of the two stream limits.  I prefer
As long as you know this limit... But RFC 6525 allows you to increase the
number of streams (unless the peer agrees to do so). 
> data channel on the same number.  That's not a problem - you just end
This is a normal case with the current data channel protocol. The
stream identifiers might not be the same in both directions.
When testing with the current implementation in Firefox, this actually
happens a lot.
>> Not sure why you refer to RFC 4920... RFC 4960 (SCTP) doesn't have such
... that was my guess.

---

From: Martin Thomson <[email-masked]>
Date: Mon, 11 Feb 2013 13:43:58 -0800

> The other things are just declaring channel properties...

The binding between stream X in one direction and stream X in the
other is as strong - or as loose - as the application needs.  This is
a departure from what was previously specified, but I think that the
advantages (0 RTT establishment) outweigh the disadvantages.

> I'm wondering how you envision this without using SDP and without the

The easiest way to tie two channels together is to use the stream
number.  That is what I was proposing.

(If stream numbers are used, then you don't even need to have a strong
uniqueness guarantee on the label.)

In the case that this is negotiated, then the guarantee is exactly the
same as the one provided previously.  Otherwise, it's a little less
strong.  If both sides create a channel at the same time, then they
could be bound together without any strong assurances about the exact
nature of the bidirectionality guarantee.  Now, I'm OK with that.  You
may not be.

> However, currently that the bi-directional.

The API would remain bi-directional.  In fact, the API would be
unchanged, except as it pertains to timing of channel use.  The
guarantees with respect to consistency would be weaker than what is
provided, depending (again) on that timing.

> waiting forever,

That presumes a lot.  Many protocols have one-way messages.

> I would prefer sending some sort of error message

This also assumes that you have some channel upon which to end this
error message, plus a definition for the error message.  I'm looking
to have less protocol machinery, not more.

> number of streams (unless the peer agrees to do so).

Negotiating stream limits up doesn't seem like a particularly likely
thing in this sort of environment.  That said, we probably need to
decide if this is a feature that we want to have available.  If it is
available, then this could be used in the case that the limits are
reached.

> When testing with the current implementation in Firefox, this actually

Interesting.  I'd be interested in learning how this would be signaled
and what the advantages of this arrangement are.

---

From: Randell Jesup <[email-masked]>
Date: Wed, 13 Feb 2013 05:36:10 -0500

A general note to start this:

We've been here before.  ALL of this has been argued over in great 
detail A YEAR AGO.  I'm sorry if some people were not involved at the 
time, and I'm fine with technical criticism of details of the solutions 
chosen.  However, while we did not have formal consensus calls (I 
think), there certainly was list (and in many cases room) consensus on 
these details, such as bidirectional channels and adding the WebSockets 
'protocol' ID at Atlanta in order to ease heterogeneous application 
interop for things like chat.

Sure, there were many options available to us.  We discussed them in 
great detail and chose a solution that was strongly patterned on 
WebSockets (and to good effect, from what I've seen in practice).  
Options like my original proposals for effectively "raw" unidirectional 
SCTP with SDP negotiation were firmly rejected in favor of bidirectional 
channels with low-overhead creation - and I agreed with the consensus on 
the list.

*Can* we reopen all of this?  Sure!  We *can* reopen ANYTHING (including 
consensus calls).  *Should* we?  No, if we ever want to make progress, 
unless there is some technical problem with the solution.  The details I 
was trying to resolve here and finalize were the outcome of conflicting 
requests to make small changes to channel creation from the Interim 
*last June*.  If people had issues with the general approach, they 
should have been presented then (or earlier on the list).

"Rough consensus and running code"?  We certainly had rough consensus a 
long time ago on most of this (and more IMO).  Running code?  We have a 
largely debugged implementation today in Firefox that's in-use in our 
Social API stuff, in 3D games, and other prototype applications.  We 
worked closely with Michael Tuexen, Randall Stewart and others to polish 
the open user-space SCTP library.

To be clear:  My revised proposal after the discussion in the room and 
on the list is to resolve the startup issues by firing onopen 
immediately and thus allowing 0-RTT opens, removing the need for special 
SDP parameters other than the m=application line and a=sctpmap line 
(which are needed to specify an SCTP/DTLS association, and are part of 
the existing MMUSIC draft).

I think we have a *workable* solution that addresses the end-user 
requirements and expectations, and is flexible enough to support complex 
future uses, and will allow for straightforward heterogeneous 
application interop.  Let's move on and make progress where we *haven't* 
been able to eliminate alternatives yet (or where they keep expanding 
instead of being pruned away).

On to the detailed response:

> This is an application choice.

Not unless you change the semantics of the JS API I believe.  If you're 
exposing glare to the application in some manner that's complexity for 
them to manage (and in a case that's hard for them to test).  It's easy 
to imagine applications making mistakes or ignoring the possibility here 
if it's exposed.

> that they can do this before setting up the session.

Sure, that's the standard "fast-path" solution.  It's still 1 RTT and a 
lot of processing, and blocks other renegotiations while it's in-flight 
(that's fairly minor, but it would block adding more channels during 
that RTT).  Remember RTT isn't always tens of milliseconds.  Sometimes 
you're on a satellite link with 500+ms of RTT, sometimes you're on the 
other side of the globe with 200+ms RTT, sometimes you're fighting 
congestion or bufferbloat (it happens, and some apps like this may be 
pure-data apps) and you have crazy RTT's like 1 second+.  And if you 
have a non-colocated TURN server (say AUS->AUS via TURN in the US) you 
can have a lot of RTT.  TURN will be expensive; do not expect every app 
to have fully geo-dispersed TURN networks!  However, these are largely 
nits - it's still min 1 RTT an heavy string processing.

> some extra muck on top of the SCTP association.  Not many applications

Ok, good - I couldn't see how that argument made sense.

> What information do they convey that isn't already negotiated through

It's an alternative to negotiating it through other channels.  In the 
proposal I just made here on the list, it gets you consistency with 
WebSockets and bidirectional symmetric channels (both also doable by 
other methods like pure-SDP), and 0-RTT opens (not possible in SDP while 
retaining the first set of JS-API-level features).

> of properties through SDP is perfectly sufficient.

Sure, many apps will have (when talking to themselves) a fixed set of 
channels set up at the start, which was what I was attempting to 
optimize given the W3 constraint to wait for a truly-acknowledged 
'onopen' ala WebSockets.  My alternative proposed here is to fire onopen 
immediately (since DataChannels are declarative) and allow 0-RTT opens, 
obviating the need the SDP enhancements presented at the meeting.

We already do have people querying if DataChannels could be used for 
things like GFC avoidance for things like proxied browsing, which (if 
it's doable, which I haven't verified but seems plausible if the user 
grants the app special permissions), which would imply a need for 
low-overhead channel creation.

> applications will use the same values for all new streams.

There are lots of applications I envision (such as games) that will want 
a small mix of reliable and unreliable (or partially-reliable) channels, 
and others that want a mix of priorities (which we haven't talked about 
much, but would allow specifying if a data channel should be higher or 
lower priority than media streams, and perhaps more granularity.  
Control information (low BW) may be higher, file transfer may be lower, 
for example.

-- 
Randell Jesup
[email-masked]

---

From: Stefan Håkansson LK <[email-masked]>
Date: Wed, 13 Feb 2013 16:13:03 +0100

Without going into details, I'd like to support Randell's main message: 
we discussed this at length a long time ago, arrived at a solution that 
seem to support the use-cases, and even have implementations.

I haven't been convinced we should reopen all this again.

Stefan

On 2013-02-13 11:36, Randell Jesup wrote:
>>> implementing
> lower priority than media streams, and perhaps more granularity. Control
> information (low BW) may be higher, file transfer may be lower, for
> example.
>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 13 Feb 2013 14:03:50 -0800

None of what I suggest would change the API.  At most, it would have
removed the in-band handshake messages in exchange for loosening some
of the guarantees.  And I've been trained to value the deletion of
code highly.  That seemed like a good trade.

And timing?  It wasn't until you presented at the interim that I
realized just how little value the in-band handshake was adding.

In terms of the specifics of your fast open proposal, what do you do
with the message(s) that arrive on channels that you reject?  How does
this surface in the API?

I'll do a blow-by-blow on your points below, if you want to continue
the conversation.  If we're exchanging rhetoric bombs, I see little
point.

On 13 February 2013 02:36, Randell Jesup <[email-masked]> wrote:
> We've been here before.  ALL of this has been argued over in great detail A
> YEAR AGO.  I'm sorry if some people were not involved at the time, and I'm
> fine with technical criticism of details of the solutions chosen.  However,
> while we did not have formal consensus calls (I think), there certainly was
> list (and in many cases room) consensus on these details, such as
> bidirectional channels and adding the WebSockets 'protocol' ID at Atlanta in
> order to ease heterogeneous application interop for things like chat.
>
> Sure, there were many options available to us.  We discussed them in great
> detail and chose a solution that was strongly patterned on WebSockets (and
> to good effect, from what I've seen in practice).  Options like my original
> proposals for effectively "raw" unidirectional SCTP with SDP negotiation
> were firmly rejected in favor of bidirectional channels with low-overhead
> creation - and I agreed with the consensus on the list.
>
> unless there is some technical problem with the solution.  The details I was
> trying to resolve here and finalize were the outcome of conflicting requests
> to make small changes to channel creation from the Interim *last June*.  If
> people had issues with the general approach, they should have been presented
> then (or earlier on the list).
>
> "Rough consensus and running code"?  We certainly had rough consensus a long
> time ago on most of this (and more IMO).  Running code?  We have a largely
> debugged implementation today in Firefox that's in-use in our Social API
> stuff, in 3D games, and other prototype applications.  We worked closely
> with Michael Tuexen, Randall Stewart and others to polish the open
> user-space SCTP library.
>
> To be clear:  My revised proposal after the discussion in the room and on
> the list is to resolve the startup issues by firing onopen immediately and
> thus allowing 0-RTT opens, removing the need for special SDP parameters
> other than the m=application line and a=sctpmap line (which are needed to
> specify an SCTP/DTLS association, and are part of the existing MMUSIC
> draft).
>
> future uses, and will allow for straightforward heterogeneous application
> interop.  Let's move on and make progress where we *haven't* been able to
> eliminate alternatives yet (or where they keep expanding instead of being
> pruned away).
>
>
>>> use
> exposing glare to the application in some manner that's complexity for them
> to manage (and in a case that's hard for them to test).  It's easy to
> imagine applications making mistakes or ignoring the possibility here if
> it's exposed.
>
> Sure, that's the standard "fast-path" solution.  It's still 1 RTT and a lot
> of processing, and blocks other renegotiations while it's in-flight (that's
> fairly minor, but it would block adding more channels during that RTT).
> Remember RTT isn't always tens of milliseconds.  Sometimes you're on a
> satellite link with 500+ms of RTT, sometimes you're on the other side of the
> globe with 200+ms RTT, sometimes you're fighting congestion or bufferbloat
> (it happens, and some apps like this may be pure-data apps) and you have
> crazy RTT's like 1 second+.  And if you have a non-colocated TURN server
> (say AUS->AUS via TURN in the US) you can have a lot of RTT.  TURN will be
> expensive; do not expect every app to have fully geo-dispersed TURN
> networks!  However, these are largely nits - it's still min 1 RTT an heavy
> string processing.
>
> WebSockets and bidirectional symmetric channels (both also doable by other
> methods like pure-SDP), and 0-RTT opens (not possible in SDP while retaining
> the first set of JS-API-level features).
>
> channels set up at the start, which was what I was attempting to optimize
> given the W3 constraint to wait for a truly-acknowledged 'onopen' ala
> WebSockets.  My alternative proposed here is to fire onopen immediately
> (since DataChannels are declarative) and allow 0-RTT opens, obviating the
> need the SDP enhancements presented at the meeting.
>
> We already do have people querying if DataChannels could be used for things
> like GFC avoidance for things like proxied browsing, which (if it's doable,
> which I haven't verified but seems plausible if the user grants the app
> special permissions), which would imply a need for low-overhead channel
> creation.
>
> There are lots of applications I envision (such as games) that will want a
> small mix of reliable and unreliable (or partially-reliable) channels, and
> others that want a mix of priorities (which we haven't talked about much,
> but would allow specifying if a data channel should be higher or lower
> priority than media streams, and perhaps more granularity.  Control
> information (low BW) may be higher, file transfer may be lower, for example.
>
> --
> Randell Jesup
> [email-masked]
>

---

From: Cullen Jennings <[email-masked]>
Date: Wed, 13 Feb 2013 15:24:14 -0700

To help this move quickly, could someone just draw out the various call flows and shows the pro's con's of them so that everyone is on the same page?

---

From: Martin Thomson <[email-masked]>
Date: Wed, 13 Feb 2013 14:58:07 -0800

> To help this move quickly, could someone just draw out the various call flows and shows the pro's con's of them so that everyone is on the same page?

I'm not sure that this will help, or even cover all the nuances effectively...

in-band negotiation only:
http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIHN0YXR1cyBxdW8KCkFsaWNlLT5Cb2I6IE9mZmVyCm5vdGUgcmlnaHQgb2YgABQFQm9iIHRoaW5rcyBhYm91dCBpdApCb2ItPgA5BTogQW5zdwAyCG92ZXIgAFEFADYGSUNFLCBEVExTLCBTQ1RQLCBldGMuLi4Aaw5wZW4gKCJsYWJlbCIsIHN0cmVhbSBYLACBKApldHRpbmdzKQCBBhhjYW4gcmVzcG9uZCBvbiBhbnkgYXZhaWxhYmxlAEkHAIElDU9wZW5SACsFc2UAaBJZKQCCCw1Mb2NrSXRJAIEZCgCBAAcAgVsQAIJYCGlzIHJlYWR5AIJQDWRhdGE&s=napkin

SDP negotiation only:
http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIFNEUCBvbmx5Cgpub3RlIGxlZnQgb2YgQWxpY2U6AAEGIGNyZWF0ZXMALAgKABgFLT5Cb2I6IE9mZmVyADYGcmlnaAA4BQAUBUJvYiBnZXRzICdkYXRhAGgHJyBldmVudApCb2ItPgBcCG5zdwA7CG92ZXIAbgcAWQVJQ0UsIERUTFMsIFNDVFAsIGV0Yy4uLgB1DQCBSgUoc3RyZWFtIFgpAHgUABcGcyBhcmUgbGlua2VkIGJhc2VkIG9uIG5lZ290aWF0ZWQgbGFiZWwgaW4gc3RhdHVzIHF1bwCBHQ1tb3IAgjcHAGcIWSkAgXUYAII6D1RoaXMgbQCCHAV1c2UgdGhlIGV4aXN0aW5nAIMDDQCCBhQAgVQZUSk&s=napkin

Randell's 0RTT in-band option:
http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIGZhc3QgaW4tYmFuZAoKQWxpY2UtPkJvYjogT2ZmZXIKQm9iLT4AEgU6IEFuc3dlcgpub3RlIG92ZXIgACoFIAApBUlDRSwgRFRMUywgU0NUUCwgZXRjLi4uAEQOcGVuICgibGFiZWwiLCBzdHJlYW0gWCwAgQQJc2V0dGluZ3MpAHwNZGF0YQBvBnJpZ2h0IG9mAG0Gb25kYXRhAIFBCCsgb25vcGVuAAQFbWVzc2FnZSBldmVudHMAgTgNT3BlblJlc3BvbnNlAHsSWQBtDkxvY2tJdEkAgSwKKQo&s=napkin

No negotiation option:
http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIG5vIG5lZ290aWF0aW9uIG9wdGlvbgoKCkFsaWNlLT5Cb2I6IE9mZmVyCkJvYi0-ABIFOiBBbnN3ZXIKbm90ZSBvdmVyIAAqBSAAKQVJQ0UsIERUTFMsIFNDVFAsIGV0Yy4uLgBFDgCAfwUoc3RyZWFtIFgpAFANcmVwbHkAEQwAYgZsZWZ0IG9mAGUGOiBjcmVhdGVEYXRhQwCBRAcoWSkAShpZKQCBKAZyaWdoAEIFAIFVBTMgZXZlbnRzIG9uZGF0YQCCDQgrIG9ub3BlbgAEBW1lc3NhZ2UAgQgbAFQIAIF6EERyYXdiYWNrOiBCb2IgYW5kAIIgB20AgH8FaGF2ZSBkaWZmZXJlbnQgbGFiZWxzL3Byb3BlcnRpZXMAgkgWU29sdXRpb246AIMuCWUAg0QIcyBpZiB5b3UgY2FyZQCDBhZDb25zdHJhaW50OiAAgjAHcyB1c2UgdGhlIHNhbWUgAIMMB251bWJlciBvbiBib3RoIGVuZHMsIG5vAIEfCA&s=napkin

What we really have at the moment is both in-band + SDP.  I was
proposing that we go to SDP only, and maybe also allow the zero
negotiation option at the expense of consistency.  (Not just because
eventual consistency is web-scale.)

---

From: Randell Jesup <[email-masked]>
Date: Thu, 14 Feb 2013 04:04:56 -0500

> I'm not sure that this will help, or even cover all the nuances effectively...

Thanks, this should help people.

> http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIHN0YXR1cyBxdW8KCkFsaWNlLT5Cb2I6IE9mZmVyCm5vdGUgcmlnaHQgb2YgABQFQm9iIHRoaW5rcyBhYm91dCBpdApCb2ItPgA5BTogQW5zdwAyCG92ZXIgAFEFADYGSUNFLC…
Adjusted and cleaned up.  Note one confusion was the assumption that 
there's label-glare-resolution; there isn't.  The response and ack 
messages carry the stream numbers (explicitly or implicitly), not 
labels.  Fixed.

http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIHN0YXR1cyBxdW8KCkFsaWNlLT5Cb2I6IE9mZmVyCm5vdGUgcmlnaHQgb2YgABQFQm9iIHRoaW5rcyBhYm91dCBpdApCb2ItPgA5BTogQW5zdwAyCG92ZXIgAFEFADYGSUNFLCBEVExTLCBTQ1RQLCBldGMuLi4Aaw5wZW4gKCJsYWJlbCIsIHN0cmVhbSBYLACBKApldHRpbmdzKQCBBhhjYW4gcmVzcG9uZCBvbiBhbnkgYXZhaWxhYmxlAEkHAIElDU9wZW5SACsFc2UgKABnCgB0B1kAVBVvbkRhdGFDAIJABgCCLQ1Mb2NrSXRJbgBBCgCBIwdsZWYAgkIFAIIiB29ub3BlbiBldmVudACCbg1kYXRhAF0WACYLAIJnDGRhdGE&s=napkin

> http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIFNEUCBvbmx5Cgpub3RlIGxlZnQgb2YgQWxpY2U6AAEGIGNyZWF0ZXMALAgKABgFLT5Cb2I6IE9mZmVyADYGcmlnaAA4BQAUBUJvYiBnZXRzICdkYXRhAGgHJyBldmVudApCb2…

Added onopen events, detail on second open

http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIFNEUCBvbmx5Cgpub3RlIGxlZnQgb2YgQWxpY2U6IGNyZWF0ZURhdGFDACoGCgAUBS0-Qm9iOiBPZmZlcihsYWJlbCwgc3RyZWFtIFgsIHBhcmFtcykASwZyaWdoAE0FAC0Fb25kYXRhAHQIYW5kIG9ub3BlbiBldmVudHMKQm9iLT4AdQdBbnN3AE4RWQBQBwCBGQ8AOgwAgUMGb3ZlcgCBQAYAdAZJQ0UsIERUTFMsIFNDVFAsIGV0Yy4uLgCBQw0AghQFKACBQQgpAIEBDW1vcgCCMwcAGQgAdBcAghAjAIFURgCBZyIAgUMZUSk&s=napkin

> http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIGZhc3QgaW4tYmFuZAoKQWxpY2UtPkJvYjogT2ZmZXIKQm9iLT4AEgU6IEFuc3dlcgpub3RlIG92ZXIgACoFIAApBUlDRSwgRFRMUywgU0NUUCwgZXRjLi4uAEQOcGVuICgibG…

Adjusted.  Same comment as in-band above

http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIGZhc3QgaW4tYmFuZAoKQWxpY2UtPkJvYjogT2ZmZXIKQm9iLT4AEgU6IEFuc3dlcgpub3RlIG92ZXIgACoFIAApBUlDRSwgRFRMUywgU0NUUCwgZXRjLi4uAEQOcGVuICgibGFiZWwiLCBzdHJlYW0gWCwAgQQJc2V0dGluZ3MpAF4GbGVmdCBvZgBhBjogb25vcGVuIGV2ZW50AIEdDWRhdGEAgRAGcmlnaAAuBQCBPQVvbmRhdGEAgWIIKwA5CCsgb25tZXNzYWdlAEcGcwCBWQ1PcGVuUmVzcG9uc2UgKACBHwZYAIElCVkpAIIGDQB2BQCCKgxMb2NrSXRJbgAxCSkK&s=napkin

> http://www.websequencediagrams.com/?lz=dGl0bGUgZGF0YSBjaGFubmVsIG5vIG5lZ290aWF0aW9uIG9wdGlvbgoKCkFsaWNlLT5Cb2I6IE9mZmVyCkJvYi0-ABIFOiBBbnN3ZXIKbm90ZSBvdmVyIAAqBSAAKQVJQ0UsIERUTFMsIFNDVFAsIGV0Yy4uLg…

Not sure what's going on here with Stream X - is there a missing 
assumption of SDP negotiation of Stream X?  The strong exposure of 
Stream numbers here implies they're surfaced to the application, no?  Or 
is it totally dependent on ordering of opens, and in the glare case they 
get cross-connected as one DataChannel with no notification of this 
(neither side gets onDataChannel).

For StreamY from bob->alice (the "reply" direction): what are the 
properties?  This also implies that the JS API has to change to let you 
set transport properties on a channel that came from onDataChannel.

Obviously there's no way to know anything about an incoming 
"onDataChannel" event not due to SDP; I'm sure your comment would be "if 
that matters, negotiate it".   How does the application cause 
negotiation to happen?  (More JS API change I assume).

I think there are unexplored interactions between SDP negotiation (and 
stream number selection) and this (dynamic no-negotiation creation).  
You might need to fail SDP requests to open stream X if the answerer has 
opened a channel on Stream X before seeing the SDP, or have the answerer 
pick the stream (but that causes problems when data from the answerer 
arrives before the Answer).

> eventual consistency is web-scale.)

I'm not sure exactly what the last statement here means.

-- 
Randell Jesup
[email-masked]

---

From: Randell Jesup <[email-masked]>
Date: Thu, 14 Feb 2013 04:44:44 -0500

> code highly.  That seemed like a good trade.

I think the no-negotiation proposal would require various API changes if 
you work out the details.

I understand the wish to reduce code.  (You do realize we're running 
over a lightweight stack like SCTP over DTLS over ICE/TURN over UDP, 
right?  ;-)

However, I'm not sure that you're actually reducing code by shifting to 
SDP (I think you're just moving the code/complexity, as the existing 
structures for negotiating m= lines can't be reused here I believe).  
And I think the SDP+no-negotiation-open proposal ends up with yet more 
complexity (and importantly, more application (JS) complexity).

The least complex IMHO is the 0-RTT in-band option, though it's similar 
in complexity to the current "pure" inband (without accelerated 
call-start creation via SDP - i.e. 1.5RTT for all opens).

> realized just how little value the in-band handshake was adding.

Which Interim?  This one (where I wasn't presenting the in-band 
protocol, though discussion moved there), or Stockholm, where it was 
presented (and again at Atlanta where we added the 'protocol' field, 
which was about the only major commentary).   I realize someone can (and 
will) object at any stage; I just wish objections of this fundamental 
nature were made (a lot) earlier.

> with the message(s) that arrive on channels that you reject?  How does

There is no rejection.  Creation of DataChannels (per the JS API) is 
purely declarative.  If you (as an application) wish to 'reject' a 
channel, either throw the object away or call .close() on it if you want 
to be nice to the sender.

> the conversation.  If we're exchanging rhetoric bombs, I see little

No, I'm quite willing to continue the conversation; to an extent (how 
much to be determined by the WG) the snake has snuck out of the bag and 
we now have to deal with the comments (both yours and Justin/Peter's).  
I will concede I have an interest in retaining a solution similar to the 
one I've proposed (in-band or preferably 0-RTT), as I have it coded in 
Firefox, used in applications and largely debugged and on-track for 
release to production in 12-18 weeks or so (and major changes might 
cause problems with that and/or future version incompatibilities).  
That's the impact of revisiting issues; we considered DataChannels a 
critical component to have from the start of WebRTC and put a lot of 
effort into first discussing it on the lists and then implementing it.  
We began implementation a year ago, and have tracked changes from the 
lists and drafts since then.   But that isn't the only consideration.

Partly my comments were aimed at all instances where we go back (and go 
back again) with progress being elusive, not just this one issue.

-- 
Randell Jesup
[email-masked]

---

From: Martin Thomson <[email-masked]>
Date: Thu, 14 Feb 2013 14:22:15 -0800

On 14 February 2013 01:04, Randell Jesup <[email-masked]> wrote:
> Not sure what's going on here with Stream X - is there a missing assumption
> of SDP negotiation of Stream X?

Yes, I was in a hurry and assumed you'd guess that.

> The strong exposure of Stream numbers here
> implies they're surfaced to the application, no?

Stream numbers are already exposed as soon as you have SDP
negotiation.  This assumes that you use the same number in both
directions for the one channel.

> Or is it totally dependent
> on ordering of opens, and in the glare case they get cross-connected as one
> DataChannel with no notification of this (neither side gets onDataChannel).

In the glare case, yes, streams can get cross-connected.

> properties?  This also implies that the JS API has to change to let you set
> transport properties on a channel that came from onDataChannel.

Properties would be set to some defaults by the browser.  And yes, the
properties should be mutable - SCTP certainly doesn't prevent that (I
covered this in my first email).

> Obviously there's no way to know anything about an incoming "onDataChannel"
> event not due to SDP; I'm sure your comment would be "if that matters,
> negotiate it".   How does the application cause negotiation to happen?
> (More JS API change I assume).

Yes, as above: properties have to be assigned defaults for the
ondatachannel event.  and yes, my response would be "if properties
matter, negotiate them".

An application can negotiate by doing offer/answer.

> stream number selection) and this (dynamic no-negotiation creation).  You
> might need to fail SDP requests to open stream X if the answerer has opened
> a channel on Stream X before seeing the SDP, or have the answerer pick the
> stream (but that causes problems when data from the answerer arrives before
> the Answer).

I don't think that this is a concern.  Once you allow for mismatched
channel properties, this all becomes easy.  The answer can use the
channel it has open to stream X.

One thing that might help with consistency is to define how browsers
select stream identifiers.  e.g., start at the lowest available
identifier.  This should help applications do zero-negotiation uses
without surprising behaviour.

>>   (Not just because

Sorry, that's a random synapse misfire.  I've been doing too much
eventual consistency stuff recently.  If you can suffer the
digression: http://www.youtube.com/watch?v=b2F-DItXtZs

---

From: Martin Thomson <[email-masked]>
Date: Thu, 14 Feb 2013 14:34:31 -0800

I should probably collate responses.

On 14 February 2013 01:44, Randell Jesup <[email-masked]> wrote:
>> None of what I suggest would change the API.
>
> I think the no-negotiation proposal would require various API changes if you
> work out the details.

Sure, some changes, but nothing that would prevent channels from being
used interchangeably with websockets.  That is, once they are
established.

> I understand the wish to reduce code.  (You do realize we're running over a
> lightweight stack like SCTP over DTLS over ICE/TURN over UDP, right?  ;-)

Presumably you bought all those other parts of the stack.

> However, I'm not sure that you're actually reducing code by shifting to SDP
> (I think you're just moving the code/complexity, as the existing structures
> for negotiating m= lines can't be reused here I believe).  And I think the
> SDP+no-negotiation-open proposal ends up with yet more complexity (and
> importantly, more application (JS) complexity).

I was under the impression that the SDP code was already needed.  That
was the premise behind making the suggestion - if we're not using SDP
to negotiate channels ever, then I might be tempted to revise that.

> The least complex IMHO is the 0-RTT in-band option, though it's similar in
> complexity to the current "pure" inband (without accelerated call-start
> creation via SDP - i.e. 1.5RTT for all opens).

The least complex is to have the application just use channels with no
in-band messages at all.  But we can't do that because we need to have
messages tagged as being "binary" or "text" to further propagate the
mistake that the websockets design made.

> Partly my comments were aimed at all instances where we go back (and go back
> again) with progress being elusive, not just this one issue.

Yeah, I understand the frustration.  I used to get frustrated with
this sort of thing too.

---

From: Michael Tuexen <[email-masked]>
Date: Thu, 14 Feb 2013 23:58:35 +0100

> mistake that the websockets design made.
You could use the PPID of SCTP and would not need the in-band messages...

However, assuming datachannel are bidirectional, I really think we need some
sort of signaling to set them up to avoid collisions. The JS user should
have a clearly defined behavior. So I think the 1.5 RTT solution is the base.
The additional SDP solution is only an acceleration for providing initial
datachannels in 0-RTT. However, allowing the 0-RTT in-band option provides
the same speed-up and isn't restricted to the initial data channels.
So the purely in-band solution with the 0-RTT option seems to be the best
for me. But as Randell pointed out: We had this discussion already and I'm
not sure what we get if we open up it again. New arguments doesn't seem
to come up...

Best regards
Michael

---

From: Martin Thomson <[email-masked]>
Date: Thu, 14 Feb 2013 17:13:01 -0800

> You could use the PPID of SCTP and would not need the in-band messages...

Interesting thought.  I'm not sure that I know how to do that.  I
presume that this would require signaling to establish that PPID X is
binary and PPID Y is text, amirite?

> sort of signaling to set them up to avoid collisions.

Collision of what?  The problem that the 1.5 RTT solves is not a
collision problem.  It's a problem of a mismatch of configuration and
expectations on the two ends of the channel.  If you remove the
expectations (negotiate if you care), and don't worry about matching
configuration (make configuration mutable, and again: negotiate if you
happen to care), what then?

---

From: Michael Tuexen <[email-masked]>
Date: Fri, 15 Feb 2013 03:59:12 +0100

> binary and PPID Y is text, amirite?
You register at IANA PPID X for binary and PPID Y (Y != X) for text.
No signaling required. 
> expectations on the two ends of the channel.  If you remove the
I expect each data channel consisting of a pair of streams. Each stream
is contained in at most one data channel.

I consider each side managing only its outgoing streams. Therefore if
each side opens a data channel at about the same time, you end up
with two data channels. Assume that there are no data channels before that
and that you don't reserve any stream, chances are that each data channel
consists of out going stream with stream id 0 and incoming stream with
stream id 1.

Best regards
Michael

---

From: Martin Thomson <[email-masked]>
Date: Fri, 15 Feb 2013 09:14:02 -0800

> You register at IANA PPID X for binary and PPID Y (Y != X) for text.

Great!  That removes the need for an in-band protocol entirely. (I
missed the IANA bit when I read through the description.)

> is contained in at most one data channel.

Correct. The difference between what you have now and what I am
proposing is simple: you match arbitrary stream X to arbitrary stream
Y in the opposite direction through signaling or control messages.  I
am proposing to match stream X to stream X always.  Thus, if you send
on stream 7, this creates a data channel on the other end that also
sends on stream 7.

---

From: Ted Hardie <[email-masked]>
Date: Fri, 15 Feb 2013 10:04:10 -0800

> consists of out going stream with stream id 0 and incoming stream with

Sorry for being dense, but if you get an INIT where the Stream
Identifiers in the data
chunk are already in use, why wouldn't you error out?  Alternatively,
can existing
implementations keep that straight as a tuple of SCTP association,
stream identifier?
If the latter, then occasionally having two data channels instead of
one does not
seem to be that big a deal; am I missing something?

regards,

Ted

---

From: Michael Tuexen <[email-masked]>
Date: Fri, 15 Feb 2013 21:55:32 +0100

> on stream 7, this creates a data channel on the other end that also
I think I understand what you are proposing. But what happens, if
both sides at about the same time open want to open a data channel.
For both sides outgoing stream X is free, so they use this. So the
endpoints end up with one data channel instead of two.

For me, the endpoints trying to set up two data channels, and finally
having only a single one is a bad thing. You could argue, that this
comes up only in specific situations. That might be true, but for
an application writer this would mean that his code works most
of the time, but sometimes not. This is a bad thing for me.

Best regards
Michael

---

From: Michael Tuexen <[email-masked]>
Date: Fri, 15 Feb 2013 22:02:35 +0100

> chunk are already in use, why wouldn't you error out?  Alternatively,
Martin suggests to have no control protocol for opening data channels.
So there is nothing like an INIT message on a stream.
> seem to be that big a deal; am I missing something?
He would occasionally end up with one data channel instead of two.
Systems, not behaving as expected *occasionally*, is a bad thing for
me. I consider this a bug and it much harder to debug if it only
occurs occasionally. It is even worse, if the developer hasn't made
any mistake...

For me, it should be clear how a data channel is set up, used,
and teared down. Yes, things can go wrong on the wire (connection
drop or so), but the API provides error handling. But we shouldn't
come up with a solution which works most of the time. For specific
applications this might be most of the time or even always.

Best regards
Michael

---

From: Martin Thomson <[email-masked]>
Date: Fri, 15 Feb 2013 13:15:56 -0800

> endpoints end up with one data channel instead of two.

Actually, I'd go further than that.  I'd require that browser
implement the same algorithm for selecting the stream to use.  That
implies that in all cases other than the rarest race conditions, you
get the same data channel.

---

From: "Matthew Kaufman (SKYPE)" <[email-masked]>
Date: Fri, 15 Feb 2013 21:56:12 +0000

None if this would be a problem if we weren't making the mistake of using SCTP, which itself made the mistake of doing full-duplex channels instead of unidirectional channels with optional one-to-one or even many-to-one associations (as RTMFP has, as an example)

Matthew Kaufman

(Sent from my iPhone)

---

From: Michael Thornburgh <[email-masked]>
Date: Fri, 15 Feb 2013 14:57:05 -0800

in using RTMFP we recognize two different bidirectional channel modes:

  1) one (or more) return/response flows to an initial flow from one end

  2) truly symmetric bidirectional peer-to-peer channels

for (1), we use RTMFP's "Return Flow Association" facility (draft-thornburgh-adobe-rtmfp-04 sections 2.3.11.1.2, 3.6.1.1, 3.6.2.1, 3.6.3.1) to signal unambiguously at the transport layer when a new flow is in return/response to one from the other end.  associations can only be made to open flows.  unlike SCTP streams, RTMFP flows can be opened and closed at any time in a session.

for (2), we place a channel identifier marking in the flow metadata or initial message (or portions thereof in both places) of the flows from each end. the application makes the bidirectional association using these identifier markings.  there's no glare problem here since bidirectional communication is desired: if one end is opening but the other isn't, then the receiving end opens its half-connection in response (or rejects the incoming half-connection if it's not wanted); if both ends open their half-connections simultaneously, then you're done (on receipt of the incoming half-connection, you see that you already have the outgoing side open).  also in this case we typically send an application-layer ack message of the other end's half-connection open to signal the channel is fully bidirectional.

in both cases, this all happens end-to-end.  unidirectional flows are open immediately and data can be sent on them right away (if rejected by the other end, the sender will receive an exception).

unidirectional flows with return/response association allows you to build arbitrarily complex trees of flows.  we have found this lends itself to cleanly and naturally modeling the kinds of P2P communication we do in Flash Player, especially in our P2P overlay/mesh modes (like application-layer multicast).

-michael thornburgh

> From: [email-masked] [mailto:[email-masked]] On Behalf Of Matthew Kaufman (SKYPE) [[email-masked]]
> Sent: Friday, February 15, 2013 1:56 PM
> 
> None if this would be a problem if we weren't making the mistake of using SCTP, which itself made the
> mistake of doing full-duplex channels instead of unidirectional channels with optional one-to-one or
> even many-to-one associations (as RTMFP has, as an example)
> 
> Matthew Kaufman
> 
> (Sent from my iPhone)
>

---

From: Ted Hardie <[email-masked]>
Date: Fri, 15 Feb 2013 16:58:12 -0800

> So there is nothing like an INIT message on a stream.
The presence of the data channel is sort-of a self-INIT, though; if you get a
data channel that re-uses existing Stream Identifiers, you could still error out
(not pleasantly mind).  But this is likely moot, see below>

> occurs occasionally. It is even worse, if the developer hasn't made

That this could result in one data channel where two were wanted is what I
was missing; I agree that this would be bad, whether occasional or not.  Having
a second data channel turn up when you were expecting one has a much
easier fix.

regards,

Ted

---

From: Randell Jesup <[email-masked]>
Date: Sat, 16 Feb 2013 01:34:38 -0500

> None if this would be a problem if we weren't making the mistake of using SCTP, which itself made the mistake of doing full-duplex channels instead of unidirectional channels with optional one-to-o…

SCTP only has unidirectional streams.

If you're referring to the DataChannel protocol, there was a strong wish 
on the mailing list (and W3) for websockets-like bidirectional channels, 
so we built a simple protocol to allow us to set up bidirectional pairs 
of SCTP streams to create channels.

-- 
Randell Jesup
[email-masked]

---

From: Randell Jesup <[email-masked]>
Date: Sat, 16 Feb 2013 01:56:57 -0500

> happen to care), what then?

The 1.5 RTT solution was due to the W3 and IETF at Stockholm saying they 
wanted OnOpen events to only fire when we knew the other side had 
received them, IIRC, like WebSockets.

My 0-RTT solution I've (re-)proposed doesn't loosen any of the 
consistency guarantees; it merely fires onOpen as soon as the channel is 
created*.  You can send immediately.  This also means there's no need to 
signal channels in the SDP.  The only minor impact is that until the 
openResponse is received (1 RTT), packets are sent with the in-order 
flag.  There are some minor details that would need to change from the 
current protocol definition, but nothing of significance.

* createDataChannel before createOffer will not fire onOpen until the 
SCTP association comes up and onConnection has fired.

I think the "just send on the next channel and ignore glare and 
accidental channel merges" is just handing a loaded gun to the 
application writer, where it normally works fine but occasionally in 
hard-to-test ways it malfunctions.

If you want bidirectional channels, you either negotiate (SDP) or you 
use something like this (which allows mis-matched streams to build a 
channel).

-- 
Randell Jesup
[email-masked]

---

From: Michael Tuexen <[email-masked]>
Date: Sat, 16 Feb 2013 16:23:21 +0100

> None if this would be a problem if we weren't making the mistake of using SCTP, which itself made the mistake of doing full-duplex channels instead of unidirectional channels with optional one-to-o…
SCTP streams uni-directional. That is why we use a simple protocol to realize bi-directional
data channels by combining two uni-directional streams.
SCTP association, however, are point-to-point. The API (1-to-many style) allows sending
a single messages (a single send() call) on all associations belonging to that socket.

Best regards
Michael

---

From: "Matthew Kaufman (SKYPE)" <[email-masked]>
Date: Sat, 16 Feb 2013 15:30:18 +0000

You're right of course... I just can't keep straight which of the things are poor choices and which are reasonable choices that have been bastardized to the point of being poor choices.

If we're going to use SCTP, and it has perfectly good unidirectional channels, why can't we just expose those to users of the W3C WEBRTC API?

Apparently this "we built a simple protocol to allow us to set up bidirectional pairs of SCTP streams to create channels" isn't as simple as it first looked, so we should be revisiting the original assumption, not creating a complicated protocol just because we can.

Matthew Kaufman

Sent from my iPad

On Feb 15, 2013, at 10:40 PM, "Randell Jesup" <[email-masked]> wrote:

> If you're referring to the DataChannel protocol, there was a strong wish on the mailing list (and W3) for websockets-like bidirectional channels, so we built a simple protocol to allow us to set up bidirectional pairs of SCTP streams to create channels.
> 
> -- 
> Randell Jesup
> [email-masked]
>

---

From: "Matthew Kaufman (SKYPE)" <[email-masked]>
Date: Sat, 16 Feb 2013 15:33:23 +0000

Can you describe the "simple protocol to realize bi-directional data channels by combining two uni-directional streams" without referring to any of what now appear to be unresolved issues?

Matthew Kaufman

Sent from my iPad

---

From: Randell Jesup <[email-masked]>
Date: Sat, 16 Feb 2013 12:15:24 -0500

> Can you describe the "simple protocol to realize bi-directional data channels by combining two uni-directional streams" without referring to any of what now appear to be unresolved issues?

Let me try to succinctly summarize the low-level protocol (details are 
in the draft).  This is the wireline protocol, which can support 0 RTT 
usage.  It's pretty darn simple as protocols go.

This assumes the association has been created.

1) when one side wishes to open a channel with a given set of 
characteristics (label, IANA websockets-protocol, reliability options), 
it selects an unused outgoing stream X and sends Open on stream X.

1a) the Channel is now open on the sender's side and can be used for 
send(); but note that until an OpenResponse is received, the in-order 
bit will be set on any data packets

2) when an Open request is received (on any stream not already in-use), 
a reverse-direction outgoing stream Y is selected.  An OpenResponse(X) 
is sent on stream Y, and the application is notified a stream has been 
created.

2a) the Channel is now open on the receiver's side and can be used for 
send(), but note that until an ACK is received, the in-order bit will be 
set on any data packets.

3) when an OpenResponse(X) is received on an unused channel (Y), it's 
paired with X, and an ACK is sent on X.  The in-order bit is no longer 
forced on.

4) when an ACK is received on a channel, the in-order bit will no longer 
be forced on when sending data.

And that is basically it.

-- 
Randell Jesup
[email-masked]

---

From: Michael Tuexen <[email-masked]>
Date: Sat, 16 Feb 2013 18:58:05 +0100

> If we're going to use SCTP, and it has perfectly good unidirectional channels, why can't we just expose those to users of the W3C WEBRTC API?
Making data channels unidirectional and even making reliability settings a per message property
(so exposing the SCTP API) would be very simple and make the additional protocol superfluous.

However, WebRTC and RTCWEB groups preferred to make the API similar to Websockets...
> Apparently this "we built a simple protocol to allow us to set up bidirectional pairs of SCTP streams to create channels" isn't as simple as it first looked, so we should be revisiting the original…
At least for me, this is a very simple protocol. Even if we add some error handling. Very easy to understand
and from implementing it, very easy to implement.

Best regards
Michael

---

From: Michael Tuexen <[email-masked]>
Date: Sat, 16 Feb 2013 19:03:50 +0100

On Feb 16, 2013, at 6:15 PM, Randell Jesup wrote:

> Let me try to succinctly summarize the low-level protocol (details are in the draft).  This is the wireline protocol, which can support 0 RTT usage.  It's pretty darn simple as protocols go.
> 
> 1) when one side wishes to open a channel with a given set of characteristics (label, IANA websockets-protocol, reliability options), it selects an unused outgoing stream X and sends Open on stream X.
> 
> 1a) the Channel is now open on the sender's side and can be used for send(); but note that until an OpenResponse is received, the in-order bit will be set on any data packets
> 
> 2) when an Open request is received (on any stream not already in-use), a reverse-direction outgoing stream Y is selected.  An OpenResponse(X) is sent on stream Y, and the application is notified a stream has been created.
> 
> 2a) the Channel is now open on the receiver's side and can be used for send(), but note that until an ACK is received, the in-order bit will be set on any data packets.
> 
> 3) when an OpenResponse(X) is received on an unused channel (Y), it's paired with X, and an ACK is sent on X.  The in-order bit is no longer forced on.
> 
> 4) when an ACK is received on a channel, the in-order bit will no longer be forced on when sending data.
> 
> 
... already including the 0 RTT optimization.

Without it:
(a) Endpoint A selects one of its outgoing streams, sends an OpenRequest on it containing the label and reliability parameter.
(b) Endpoint B selects one if its outgoing streams, send an OpenResponse on it containing the incoming stream identifier on
    which the OpenRequest was received.
(c) Endpoint A sends an OpenAck.

(a) is used to "negotiate" the parameters of the data channel.
(b) is used to tie together the streams in both directions.

That is all. A simple three way handshake.
Randell's optimizations allow to send userdata right after (a).

Best regards
Michael

---

From: Tim Panton <[email-masked]>
Date: Mon, 18 Feb 2013 11:45:46 +0000

> get the same data channel.

I'd remind everyone that in the case of the data-channel there are _no_ 
cases where the endpoints don't know what the other end is supposed to be doing.

There are no statically programmed legacy devices which support the data channel.

Endpoints can be assumed to be dynamic javascript clients programmed to interoperate with each other, 
most often with the same javascript loaded from the same source and sharing a signalling channel.

We run the risk of over thinking this.

T.

---

From: Harald Alvestrand <[email-masked]>
Date: Mon, 18 Feb 2013 13:39:22 +0100

> None if this would be a problem if we weren't making the mistake of using SCTP, which itself made the mistake of doing full-duplex channels instead of unidirectional channels with optional one-to-o…

Correction: SCTP has unidirectional channels. This WG made the decision 
that it wanted something that looked like WebSockets, which are 
bidirectional. This required something to be layered on top of SCTP; 
that's what we're currently discussing.

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 18 Feb 2013 12:32:42 -0500

> However, WebRTC and RTCWEB groups preferred to make the API similar to Websockets...

So why not provide two levels of API:

1) a low level one that exposed "pure SCTP" with one-way streams

2) a "websocket compatible" API layered on (1).

	Thanks,
	Paul

---

From: Martin Thomson <[email-masked]>
Date: Mon, 18 Feb 2013 11:22:35 -0800

> 2) a "websocket compatible" API layered on (1).

This isn't really necessary.  There's a trade-off that I think can be
made without losing much.

http://tools.ietf.org/html/draft-thomson-rtcweb-data-00

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 18 Feb 2013 18:25:25 -0500

> most often with the same javascript loaded from the same source and sharing a signalling channel.

I disagree.

For the cases RTCWEB cares about, presumably at last one end is a 
javascript client. But the other end may not be. There can be many cases 
where one end is a server.

The case *I* care about right now is where one end is a CLUE server, and 
the other end is an RTCWEB browser client. CLUE needs a data channel, 
and we are aiming at one compatible with RTCWEB, in part precisely to 
make this case a possibility. And while RTCWEB doesn't care, CLUE wants 
to be able to use the same channel machinery with *neither* end is a 
browser.

Obviously this doesn't exist yet, so we are flexible about the details. 
But we need for it not to depend on being javascript to javascript.

	Thanks,
	Paul

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 18 Feb 2013 18:44:25 -0500

> http://tools.ietf.org/html/draft-thomson-rtcweb-data-00

Yeah, that seems sufficient.

	Thanks,
	Paul

---

From: Stefan Håkansson LK <[email-masked]>
Date: Tue, 19 Feb 2013 09:50:14 +0100

> where one end is a server.

The normal way for a web application to communicate with a server is 
using http. Recently, more optimized means have been defined, WebSocket 
and Server-Sent Events.

Of course you could terminate a rtcweb data channel in a server, but I'm 
not sure how much that really buys you over using WebSockets in practice 
(sure, WebSockets only support reliable delivery, so perhaps for low 
latency needs there could be a gain).

But that said, why couldn't the server do the same things the client 
would do in JS over the currently defined data channel if you really 
want to use the rtcweb data channel for client-server communication?

---

From: Randell Jesup <[email-masked]>
Date: Tue, 19 Feb 2013 09:58:28 -0500

On 2/19/2013 3:50 AM, Stefan Håkansson LK wrote:
> using http. Recently, more optimized means have been defined, 
> WebSocket and Server-Sent Events.
>
> Of course you could terminate a rtcweb data channel in a server, but 
> I'm not sure how much that really buys you over using WebSockets in 
> practice (sure, WebSockets only support reliable delivery, so perhaps 
> for low latency needs there could be a gain).

If you have any sort of central mixer usecase (Hangouts?) it makes lots 
of sense for the server to implement DataChannels.  Also for any case 
where the server is proxying them, since (eventually) we'll have them 
set not to conflict congestion-wise (or be controllable in priority).

-- 
Randell Jesup
[email-masked]

---

From: Paul Kyzivat <[email-masked]>
Date: Wed, 20 Feb 2013 14:32:28 -0500

> want to use the rtcweb data channel for client-server communication?

The case I am thinking about is CLUE.

Ignoring RTCWEB, a clue session is a specialized sip session.
There could be two endpoints connected by SIP, or there could be two or 
more endpoints in a star configuration with an MCU, each having a SIP 
session.

Those sessions, endpoint-endpoint, or endpoint-mcu, need clue-specific 
data channel.

Now lets introduce RTCWEB into that picture. For simplicity, lets just 
consider the MCU case, where *one* of the endpoints is a browser. How 
will that work?

Clearly there must be a web server, that is only needed for the RTCWEB 
endpoints. It may or may not be collocated with the MCU.

Then we have two choices:

1) we implement clue endpoint code in javascript to run in the browser. 
The webserver acts as a source of the javascript, and as a gateway to 
sip. The javascript implements the clue protocol over the data channel, 
selects and establishes media streams, etc.

2) we implement clue endpoint code in the webserver on behalf of the 
endpoint. It implements the the clue protocol over a data channel, etc. 
It then uses proprietary signaling between itself and the browser to 
manipulate all the streams and displays.

I see (1) as the preferred path. IIUC what you are suggesting looks more 
like (2). In (2) the web server must be much more knowledgeable about 
CLUE. It also could be slow if things start happening in the data 
channel that must be mapped to http to be communicated to the browser.

	Thanks,
	Paul

---

From: Harald Alvestrand <[email-masked]>
Date: Wed, 20 Feb 2013 20:40:20 +0100

On 02/20/2013 08:32 PM, Paul Kyzivat wrote:
> There could be two endpoints connected by SIP, or there could be two 
> or more endpoints in a star configuration with an MCU, each having a 
> SIP session.
>
> 1) we implement clue endpoint code in javascript to run in the 
> browser. The webserver acts as a source of the javascript, and as a 
> gateway to sip. The javascript implements the clue protocol over the 
> data channel, selects and establishes media streams, etc.
>
> endpoint. It implements the the clue protocol over a data channel, 
> etc. It then uses proprietary signaling between itself and the browser 
> to manipulate all the streams and displays.
>
> I see (1) as the preferred path. IIUC what you are suggesting looks 
> more like (2). In (2) the web server must be much more knowledgeable 
> about CLUE. It also could be slow if things start happening in the 
> data channel that must be mapped to http to be communicated to the 
> browser.

I would think that in the 2) case, "the webserver" would be "a gateway 
media server". There's absolutely no reason I can think of to colocate 
the webserver with the gateway media server.

Similarly, in the 1) case, "the webserver" should be "the SIP gateway" - 
there's some more reason to colocate them here, as SIP-over-HTTPS or 
SIP-over-Websockets makes some sense (and is already implemented by 
some), and is a little easier to deal with on a same-origin basis - but 
there's no necessary link between the Web server that serves the page 
and the SIP server that mediates the signalling.

That said, I also think it's more likely that designs based on 1) would 
be preferable.