Subject: [rtcweb] Sending of zero-length messages over data channels

From: Justin Uberti <[email-masked]>
Date: Tue, 22 Jul 2014 23:58:01 -0400

In the existing data channel protocol, it's not possible to send
zero-length messages, because SCTP prohibits it.

While this may seem to be an academic point, it does represent a divergence
from WebSockets, and this difference could be meaningful to applications
who use empty messages for keepalives. Or maybe the Yo app.

Since we can't send a zero-length SCTP message, I propose we add a
PPID_EMPTY value or something similar to indicate a message with empty
content.

---

From: Michael Tuexen <[email-masked]>
Date: Wed, 23 Jul 2014 07:12:06 -0400

On 22 Jul 2014, at 23:58, Justin Uberti <[email-masked]> wrote:

> In the existing data channel protocol, it's not possible to send zero-length messages, because SCTP prohibits it.
> 
> While this may seem to be an academic point, it does represent a divergence from WebSockets, and this difference could be meaningful to applications who use empty messages for keepalives. Or maybe the Yo app.
> 
> Since we can't send a zero-length SCTP message, I propose we add a PPID_EMPTY value or something similar to indicate a message with empty content.
That works. The corresponding payload would be ignored...
One could add a sentence or two in
http://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-11#section-6.6
and in the IANA section.

Best regards
Michael
> _______________________________________________
> rtcweb mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/rtcweb

---

From: "Makaraju, Maridi Raju (Raju)" <[email-masked]>
Date: Wed, 23 Jul 2014 12:00:22 +0000

Since we can't send a zero-length SCTP message, I propose we add a PPID_EMPTY value or something similar to indicate a message with empty content.
[Raju] There is a genuine need for this and the proposal is good.
However, I am thinking of an alternate proposal to achieve the same but in a generic way.
Define a PPID_OOB (out of band) or something similar.
Apps can use this to send a message of non-zero length. For the “Yo” kind of app or empty stream-level heartbeat purpose, app can send a 1 byte length message, which other end’s app ignores.
This approach involves bit more API work for webrtc to have a variation of send(data, oobFlag) and new data type in onmessage(). IMHO, this approach allows more possibilities in future and also the same approach can be used by other SCTP use cases not involving webrtc.

BR
raju

---

From: Ted Hardie <[email-masked]>
Date: Wed, 23 Jul 2014 08:55:19 -0400

On Tue, Jul 22, 2014 at 11:58 PM, Justin Uberti <[email-masked]> wrote:

> I
​Howdy,

The keepalive problem seems to be pretty amenable to any message, whether
of zero length, single byte or something else.  Is the convergence with
websockets on zero length important enough to re-open the drafts we just
sent to the ADs?

Ted

---

From: Justin Uberti <[email-masked]>
Date: Wed, 23 Jul 2014 09:07:53 -0400

Since we have promised drop-in compatibility with WebSockets, I think we
ought to do this, and the resulting text change here should be small enough
that we could update the doc without a long re-review.

It would be unfortunate to have to have an errata section on a draft that
isn't even a RFC yet.

---

From: Michael Tuexen <[email-masked]>
Date: Wed, 23 Jul 2014 09:30:45 -0400

> Apps can use this to send a message of non-zero length. For the “Yo” kind of app or empty stream-level heartbeat purpose, app can send a 1 byte length message, which other end’s app ignores.
What do you want to check with the heartbeat purpose? If you can talk to the peer?
That doesn't need to be done for every data channel, but only once for all of them.
As far as I understand, this is done by ICE...

Best regards
Michael

---

From: Justin Uberti <[email-masked]>
Date: Wed, 23 Jul 2014 10:26:16 -0400

This would be apps that have some sort of application-level heartbeat. Of
course, you could change the apps, but that means we can't claim full
WebSockets fidelity.

On Wed, Jul 23, 2014 at 9:30 AM, Michael Tuexen <
[email-masked]> wrote:

> > While this may seem to be an academic point, it does represent a
> divergence from WebSockets, and this difference could be meaningful to
> applications who use empty messages for keepalives. Or maybe the Yo app.
> >
> > Apps can use this to send a message of non-zero length. For the “Yo”
> kind of app or empty stream-level heartbeat purpose, app can send a 1 byte
> length message, which other end’s app ignores.
> > This approach involves bit more API work for webrtc to have a variation
> of send(data, oobFlag) and new data type in onmessage(). IMHO, this
> approach allows more possibilities in future and also the same approach can
> be used by other SCTP use cases not involving webrtc.
> >
> > BR
> > raju

---

From: "Makaraju, Maridi Raju (Raju)" <[email-masked]>
Date: Wed, 23 Jul 2014 14:57:44 +0000

> > In the existing data channel protocol, it's not possible to send zero-
> length messages, because SCTP prohibits it.
> >
> > Apps can use this to send a message of non-zero length. For the "Yo" kind
> of app or empty stream-level heartbeat purpose, app can send a 1 byte length
> message, which other end's app ignores.
<Raju2> 
Yes, heartbeats to the peer will be taken care by SCTP heartbeats and/or DTLS heartbeats and/or ICE.
But, that does not guarantee data channel level liveliness.
Generic heartbeats are just one of the use cases for PPID_OOB proposal. Other use cases for this include... app can send low-frequency OOB data to the peer within the same data channel instead of creating a new one. This way the OOB will not interfere with syntax+semantics of the main app protocol used in that data channel.
</Raju2>

BR
Raju

---

From: Justin Uberti <[email-masked]>
Date: Thu, 24 Jul 2014 13:38:00 -0400

Changing the send() API defeats the purpose of trying to provide full
WebSockets compatibility.

I think the PPID_EMPTY approach (probably PPID_EMPTY_TEXT and
PPID_EMPTY_BINARY, to be precise) is a simple and complete solution.

On Wed, Jul 23, 2014 at 8:00 AM, Makaraju, Maridi Raju (Raju) <
[email-masked]> wrote:

> *[Raju] There is a genuine need for this and the proposal is good. *
>
> *However, I am thinking of an alternate proposal to achieve the same but
> in a generic way. *
>
> *Define a PPID_OOB (out of band) or something similar.*
>
> *Apps can use this to send a message of non-zero length. For the “Yo” kind
> of app or empty stream-level heartbeat purpose, app can send a 1 byte
> length message, which other end’s app ignores.*
>
> *This approach involves bit more API work for webrtc to have a variation
> be used by other SCTP use cases not involving webrtc.*
>
>
>
> *BR*
>
> *raju*
>

---

From: "Makaraju, Maridi Raju (Raju)" <[email-masked]>
Date: Thu, 24 Jul 2014 18:10:51 +0000

Changing the send() API defeats the purpose of trying to provide full WebSockets compatibility.
<Raju> I understand the desire to make the API compatible to websocket API. But, unlike websocket TCP transport, the data channels the underlying transport (SCTP) has the flexibility for PPID, which can be utilized to achieve the same goal, with the added advantage of using the same approach for other use cases (like OOB data delivery).

IHMO, PPID_EMPTY approach is not straight forward either as at SCTP level you still have to send some dummy data (unless SCTP is enhanced) of some size (=1 or implementation dependent?), which is not obvious to the user. Will the ‘bufferedAmount’ be increased appropriately with the dummy data sent? Even if it is accounted for, the application has to know this and be mindful of the “mysterious” increase (1 byte or n bytes?) in ‘bufferedAmount’, something very unique to SCTP.

PPID_OOB approach is transparent to the user as user sends the data, so it is automatically accounted in ‘bufferedAmount’.

</Raju>

I think the PPID_EMPTY approach (probably PPID_EMPTY_TEXT and PPID_EMPTY_BINARY, to be precise) is a simple and complete solution.

---

From: Justin Uberti <[email-masked]>
Date: Thu, 24 Jul 2014 14:16:22 -0400

On Thu, Jul 24, 2014 at 2:10 PM, Makaraju, Maridi Raju (Raju) <
[email-masked]> wrote:

> *<Raju> I understand the desire to make the API compatible to websocket
> API. But, unlike websocket TCP transport, the data channels the underlying
> transport (SCTP) has the flexibility for PPID, which can be utilized to
> achieve the same goal, with the added advantage of using the same approach
> for other use cases (like OOB data delivery). *
>
>
>
> *IHMO, PPID_EMPTY approach is not straight forward either as at SCTP level
> you still have to send some dummy data (unless SCTP is enhanced) of some
> size (=1 or implementation dependent?), which is not obvious to the user.
> Will the ‘bufferedAmount’ be increased appropriately with the dummy data
> sent? Even if it is accounted for, the application has to know this and be
> mindful of the “mysterious” increase (1 byte or n bytes?) in
> ‘bufferedAmount’, something very unique to SCTP.*
>

We will send 1 byte, and this will not be reflected in bufferedAmount, same
as WebSockets.

>
>
> *PPID_OOB approach is transparent to the user as user sends the data, so
> it is automatically accounted in ‘bufferedAmount’.*
>
>
>
> *</Raju>*
>
>
>

---

From: "Makaraju, Maridi Raju (Raju)" <[email-masked]>
Date: Thu, 24 Jul 2014 19:19:44 +0000

>We will send 1 byte, and this will not be reflected in bufferedAmount, same as WebSockets.
<Raju> I could be wrong, but I am not sure how 1 dummy byte can be sent over Websockets?! I do not see any special frame type defined at http://www.iana.org/assignments/websocket/websocket.xml for this dummy byte purpose; without that how does the other end know to ignore it? My understanding is Websocket protocol allows zero-length frames by default.
Also, the webkit bug fix for websocket https://bugs.webkit.org/show_bug.cgi?id=65592 talks about handling zero length payload as opposed to sending a dummy byte.

In conclusion, I think websocket API supports zero length because websocket protocol supports zero-length data frames. So, it does not have the issue of ‘bufferedAmount’ discrepancy.

</Raju>
BR
Raju

---

From: Justin Uberti <[email-masked]>
Date: Thu, 24 Jul 2014 15:27:55 -0400

On Thu, Jul 24, 2014 at 3:19 PM, Makaraju, Maridi Raju (Raju) <
[email-masked]> wrote:

> *<Raju> I could be wrong, but I am not sure how 1 dummy byte can be sent
> over Websockets?! I do not see any special frame type defined at
> http://www.iana.org/assignments/websocket/websocket.xml
> <http://www.iana.org/assignments/websocket/websocket.xml> for this dummy
> byte purpose; without that how does the other end know to ignore it? My
> understanding is Websocket protocol allows zero-length frames by default.*
>
> *Also, the webkit bug fix for websocket*
> https://bugs.webkit.org/show_bug.cgi?id=65592 *talks about handling zero
> length payload as opposed to sending a dummy byte.*
>
>
>
> *In conclusion, I think websocket API supports zero length because
> websocket protocol supports zero-length data frames. So, it does not have
> the issue of ‘bufferedAmount’ discrepancy. *
>
>
>

Yes, that is what I meant.

---

From: "Makaraju, Maridi Raju (Raju)" <[email-masked]>
Date: Thu, 24 Jul 2014 20:25:37 +0000

Yes, that is what I meant.
<Raju>
Ok, good. Websocket is not sending any dummy bytes, so bufferedAmount is always accurate.
I am still not convinced that to keep data channel API consistent with websocket API we need to introduce of dummy byte!?
How about keeping consistency of what goes on wire vs. what user sent? websocket preserves that, where as data channel won’t.
IMHO opinion, sending such a dummy byte may have other consequences:

1.       App is not aware of what’s going on? send() probably meant to be called with non-empty data, but some error leg could have caused it become empty, but still a byte will be sent out!!

2.       Debugging becomes bit more complex and not intuitive. WebRTC is already complex, why add more complexity?

3.       Interop issues. The more the exceptions the more the interop issues you see as some implementations may overlook these or implement them later.

It’s usually a bad idea to send a dummy byte on wire, without the application direct involvement.
IMHO, if doing PPID_OOB is more effort and can’t fit in webrtc 1.0 then it would be better to delay and do it in more proper way than taking a shortcut with PPID_EMPTY. With PPID_OOB approach underlying signaling protocol can negotiate OOB before using it; though such negotiation is not mandatory, but this approach allows such possibility.

I then, rest my case! ☺

</Raju>