{"title":"Lennart Grahl's Blog","link":[{"@attributes":{"href":"https:\/\/lgrahl.de\/","rel":"alternate"}},{"@attributes":{"href":"https:\/\/lgrahl.de\/feeds\/all.atom.xml","rel":"self"}}],"id":"https:\/\/lgrahl.de\/","updated":"2017-11-03T23:55:00+01:00","subtitle":"Software Engineer","entry":[{"title":"Large Data Channel Messages for Firefox","link":{"@attributes":{"href":"https:\/\/lgrahl.de\/articles\/large-dc-messages-firefox.html","rel":"alternate"}},"published":"2017-11-03T23:55:00+01:00","updated":"2017-11-03T23:55:00+01:00","author":{"name":"Lennart Grahl"},"id":"tag:lgrahl.de,2017-11-03:\/articles\/large-dc-messages-firefox.html","summary":"<p>At the moment, you have to be careful about the maximum message size you can send over a WebRTC data channel. Especially if the data channel has been established between Firefox and Chrome. With help from Randell Jesup, Nils Ohlmeier and plenty of other helpful guys from the <em>#media<\/em> Mozilla IRC channel, I've added <em>EOR<\/em> handling and determination of the maximum message size to Firefox data channels. In this article, I'll explain the technical details and the benefits of this addition.<\/p>","content":"<p>At the moment, you have to be careful about the maximum message size you can\nsend over a WebRTC data channel. Especially if the data channel has been\nestablished between Firefox and Chrome. With help from Randell Jesup, Nils\nOhlmeier and plenty of other helpful guys from the <em>#media<\/em> Mozilla IRC\nchannel, I've added <em>EOR<\/em> handling to Firefox data channels (tracked in\n<a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=979417\">bug 979417<\/a>) which will land in Firefox 57. So, what does this\nactually mean and what are the benefits?<\/p>\n<h2>EOR... what?<\/h2>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Stream_Control_Transmission_Protocol\">SCTP<\/a> is the transport protocol used for exchanging WebRTC data channel\nmessages. Its API provides an <em>EOR<\/em> flag which stands for <em>end of record<\/em> and\ntells us whether a message is partial or complete. Thus, every implementation\nneeds to pay attention to this flag or message integrity will be violated.\nWhich sadly is the case for all popular data channel implementations at the\nmoment and results in harsh size limitations for data channel messages. For\nmore technical information on this and how one can work around this, take a\nlook at my <a href=\"https:\/\/lgrahl.de\/articles\/demystifying-webrtc-dc-size-limit.html\">previous blog posting<\/a>. But do\nnot worry, determining that size limitation will be a lot easier, soon.<\/p>\n<p>Unfortunately, none of the browsers today support the\n<a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-tsvwg-sctp-ndata-11\">SCTP ndata extension<\/a> yet, so a single data channel message will\nmonopolise the whole SCTP assocation. This phenomenom is also known as\n<em>head-of-line blocking<\/em> and makes sending large messages quite painful if other\nchannels need to keep exchanging messages frequently, for example in a\nreal-time chat with file-sending capability. All messages exchanged in the chat\nwould arrive after the lengthy process of sending a gigantic file has been\ncompleted.<\/p>\n<p>While the ndata extension is currently in the specification process, it's\nmaking good progress and there's no excuse for holding back proper EOR handling\nanymore. Personally, I believe this should have never been an excuse for not\nhandling EOR as it has so many undesired side effects. Since I've gained\nexperience in writing a standalone data channel implementation with proper EOR\nhandling (called <a href=\"https:\/\/github.com\/rawrtc\/rawrtc\">RAWRTC<\/a>), it was a logical choice to apply this to at\nleast one of the browsers.<\/p>\n<h2>Exchanging Large Messages<\/h2>\n<p>With EOR handling, one major benefit is of course being able to send and\nreceive large messages. But hold on a second... sending large messages from\nFirefox to Firefox was possible before, wasn't it? Yep, that's true, with help\nof the deprecated PPID-based fragmentation\/reassembly mechanism. However, no\none else implemented this. A detection algorithm has been added, so Firefox\nwill fall back to use PPID-based fragmentation\/reassembly when needed: In case\nthe maximum message size attribute in the remote description's SDP is missing\nand 256 incoming streams have been negotiated for the SCTP association, it is\nassumed that the other peer is an older Firefox browser. It is not the cleanest\nof solutions but it should be adequate and will be removed once Firefox ESR has\nEOR support as well.<\/p>\n<p>Thanks to EOR handling, Firefox will support receiving up to 1 GiB messages.\nWhy is there a limitation? Well, theoretically we can support much more but the\nlimiting factor is available memory and the fact that the <code>RTCDataChannel<\/code> API\nof WebRTC is <em>too high-level<\/em>, meaning it's not possible to send or receive a\nmessage in chunks. Therefore, when you want to send a large file as a whole,\nthere's an enormous <a href=\"https:\/\/www.techopedia.com\/definition\/24131\/backpressure\">backpressure<\/a> due to the fact that the\nfile's data needs to be in memory when calling the <code>send<\/code> method. Changing this\nrequires changes to the W3C WebRTC specification.<\/p>\n<p>Nevertheless, this size limitation may be increased in the future. But having a\nsize limit requires knowledge about this limitation. More precisely, that value\nmust be available before an application even tries to send a message or it\nwould be a guessing game...<\/p>\n<h2>Maximum Message Size Indication<\/h2>\n<p>In the W3C WebRTC spec, there's an <code>RTCSctpTransport<\/code> object which has a\n<a href=\"https:\/\/cdn.rawgit.com\/w3c\/webrtc-pc\/f4061e8ad0be1b849c863a01ebc391669d92d7f2\/webrtc.html#dom-rtcsctptransport-maxmessagesize\">field called <code>maxMessageSize<\/code><\/a>. It maps to the attribute\nfrom the SDP and is exactly what a user application needs to look for. So, the\nfollowing example should work, right?<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">pc<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"ow\">new<\/span><span class=\"w\"> <\/span><span class=\"nx\">RTCPeerConnection<\/span><span class=\"p\">(...);<\/span>\n<span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">dc<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"nx\">pc<\/span><span class=\"p\">.<\/span><span class=\"nx\">createDataChannel<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;test&#39;<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">negotiated<\/span><span class=\"o\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">id<\/span><span class=\"o\">:<\/span><span class=\"w\"> <\/span><span class=\"mf\">1<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"nx\">dc<\/span><span class=\"p\">.<\/span><span class=\"nx\">onopen<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">()<\/span><span class=\"w\"> <\/span><span class=\"p\">=&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"nx\">pc<\/span><span class=\"p\">.<\/span><span class=\"nx\">sctp<\/span><span class=\"p\">.<\/span><span class=\"nx\">maxMessageSize<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">dc<\/span><span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">(<\/span><span class=\"ow\">new<\/span><span class=\"w\"> <\/span><span class=\"nb\">Uint8Array<\/span><span class=\"p\">(<\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"p\">));<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"c1\">\/\/ Create and exchange offer\/answer here.<\/span>\n<span class=\"c1\">\/\/ ...<\/span>\n<\/code><\/pre><\/div>\n\n<p>But sadly, it doesn't because Firefox and all other browsers currently do not\nsupport the object API that has been borrowed from the\n<a href=\"http:\/\/draft.ortc.org\">ORTC specification<\/a>. So, what can be done to retrieve this\ninformation? The answer lies within the SDP blob. Check this out:<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">pc<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"ow\">new<\/span><span class=\"w\"> <\/span><span class=\"nx\">RTCPeerConnection<\/span><span class=\"p\">(...);<\/span>\n<span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nx\">dc<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"nx\">pc<\/span><span class=\"p\">.<\/span><span class=\"nx\">createDataChannel<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;test&#39;<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">negotiated<\/span><span class=\"o\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">id<\/span><span class=\"o\">:<\/span><span class=\"w\"> <\/span><span class=\"mf\">1<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"nx\">dc<\/span><span class=\"p\">.<\/span><span class=\"nx\">onopen<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">()<\/span><span class=\"w\"> <\/span><span class=\"p\">=&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">dc<\/span><span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">(<\/span><span class=\"ow\">new<\/span><span class=\"w\"> <\/span><span class=\"nb\">Uint8Array<\/span><span class=\"p\">(<\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"p\">));<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"nx\">mySignaling<\/span><span class=\"p\">.<\/span><span class=\"nx\">onRemoteDescription<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"nx\">description<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">=&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"c1\">\/\/ Parse a=max-message-size<\/span>\n<span class=\"w\">    <\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"mf\">65535<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"kd\">const<\/span><span class=\"w\"> <\/span><span class=\"nx\">match<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"nx\">description<\/span><span class=\"p\">.<\/span><span class=\"nx\">sdp<\/span><span class=\"p\">.<\/span><span class=\"nx\">match<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/a=max-message-size:\\s*(\\d+)\/g<\/span><span class=\"p\">);<\/span>\n<span class=\"w\">    <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"nx\">match<\/span><span class=\"w\"> <\/span><span class=\"o\">!==<\/span><span class=\"w\"> <\/span><span class=\"kc\">null<\/span><span class=\"w\"> <\/span><span class=\"o\">&amp;&amp;<\/span><span class=\"w\"> <\/span><span class=\"nx\">match<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"w\"> <\/span><span class=\"o\">&gt;=<\/span><span class=\"w\"> <\/span><span class=\"mf\">2<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">        <\/span><span class=\"nx\">maximumMessageSize<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"nb\">parseInt<\/span><span class=\"p\">(<\/span><span class=\"nx\">match<\/span><span class=\"p\">[<\/span><span class=\"mf\">1<\/span><span class=\"p\">]);<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\">\/\/ Set remote description<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">...<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"c1\">\/\/ Create and exchange offer\/answer here.<\/span>\n<span class=\"c1\">\/\/ ...<\/span>\n<\/code><\/pre><\/div>\n\n<p>Now we know how much data we can send. In case an application sends a message\nthat exceeds this limitation, the <code>send<\/code> method will raise an error as\ndescribed in the next section.<\/p>\n<p>But you definitely don\u2019t want to do that ugly SDP inspection yourselves, so\nsupport in adapter.js <a href=\"https:\/\/github.com\/webrtc\/adapter\/pull\/702\">is about to be added<\/a>. I encourage you to\nupdate to the latest adapter version once that PR has been merged as it also\nsorts out various other incompatibility nits regarding the maximum message size\nfor many browser interoperability cases.<\/p>\n<h2>Explicit Errors<\/h2>\n<p>These changes will not only make it possible to send and receive large data\nchannel messages, but will also let you know if the other peer is capable of\nreceiving a message that has been passed to the <code>send<\/code> method in form of a\n<code>TypeError<\/code> exception <a href=\"https:\/\/cdn.rawgit.com\/w3c\/webrtc-pc\/f4061e8ad0be1b849c863a01ebc391669d92d7f2\/webrtc.html#dfn-send\">as specified<\/a> (formerly, the data\nchannel has been closed implicitly in case of such an error). This ensures\nbackwards compatibility to implementations that do not handle EOR at the moment\nas all implementations are capable of handling 64 KiB sized messages.<\/p>\n<h2>Other Browsers<\/h2>\n<p>Now, it's your turn Chromium. <span class=\"e1a-blush e1a-small\"><\/span> Let's\nraise the limit - at least well beyond 64 KiB.<\/p>\n<hr>\n<p>An edited version of this article has also been released on\n<a href=\"https:\/\/blog.mozilla.org\/webrtc\/large-data-channel-messages\/\">Mozilla's WebRTC blog<\/a>.<\/p>","category":[{"@attributes":{"term":"WebRTC"}},{"@attributes":{"term":"webrtc"}},{"@attributes":{"term":"datachannel"}},{"@attributes":{"term":"sctp"}},{"@attributes":{"term":"eor"}}]},{"title":"Demystifying WebRTC's Data Channel Message Size Limitations","link":{"@attributes":{"href":"https:\/\/lgrahl.de\/articles\/demystifying-webrtc-dc-size-limit.html","rel":"alternate"}},"published":"2016-12-01T15:10:00+01:00","updated":"2017-06-30T18:50:00+02:00","author":{"name":"Lennart Grahl"},"id":"tag:lgrahl.de,2016-12-01:\/articles\/demystifying-webrtc-dc-size-limit.html","summary":"<p>WebRTC's data channels have a message size limitation. But where does this limitation come from? I've read through most of Firefox's and Chromium's data channel code. In this article, I'll show you my results and give some recommendation what you can do to reliably work around this issue.<\/p>","content":"<p>Many application developers who utilise WebRTC data channel know that there is\na message size limitation. <a href=\"http:\/\/viblast.com\/blog\/2015\/2\/5\/webrtc-data-channel-message-size\">Some<\/a> have experimentally\ntried to find the maximum message size. However, it seems that noone has ever\nlooked deep enough to find out why that message size limitation exists in the\nfirst place and why sending messages from Firefox to Chromium in particular\ndictates a bizarrely low message size. So, I've read through most of Firefox's\nand Chromium's SCTP data channel implementations. And here are my results.<\/p>\n<h2>Chromium<\/h2>\n<p>Chromium unintentionally fragments messages. Rather than implementing\n<a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-rtcweb-data-channel-13#section-6.6\">fragmentation\/reassembly on the (now deprecated) SCTP PPID (payload protocol\nidentifier) level<\/a> Chromium simply passes the data as is to the\n<a href=\"https:\/\/github.com\/sctplab\/usrsctp\">usrsctp<\/a> (the SCTP implementation used by both Chromium and Firefox)\nstack. Now, behaviour depends on usrsctp: When a message is greater than 256\nKiB (which is usrsctp's default maximum buffer size), Chromium simply closes\nthe data channel, because usrsctp returns <code>EMSGSIZE<\/code> when calling\n<code>usrsctp_sendv<\/code> which the Chromium code is not able to handle. It simply closes\nthe data channel in that case. Messages up to 256 KiB are split up into very\nsmall packets by usrsctp. These packets are then encrypted and sent on the DTLS\nlayer to the recipient.<\/p>\n<p>On the receiver side, usrsctp buffers the small chunks until the buffer reaches\nthe partial delivery point (which is ~64 KiB at default). It then passes the\nstill incomplete message to the browser. Chromium is supposed to buffer the\nmessage and wait for the EOR (end of record) flag which indicates that a\nmessage is complete. However, Chromium ignores that flag and simply delivers\nthe incomplete message to the user application, violating the message-oriented\nprinciple.<\/p>\n<p>Furthermore, Chromium does not check the return code of <code>usrsctp_sendv<\/code> for\n<code>EAGAIN<\/code> which means that sending a data channel message via Chromium can\npotentially lead to arbitrarily dropped packets when the internal buffer of\nusrsctp is full. Theoretically this means that you do not know how much data\nyou can reliably send. However, I've not encountered this particular type of\nerror so far, so there's probably enough time for usrsctp between send calls to\ndeliver buffered data and clear the buffers. Still, be aware that this might be\nan issue.<\/p>\n<h2>Firefox<\/h2>\n<p>Current Firefox versions have two modes for sending data:<\/p>\n<ol>\n<li>\n<p>If the data channel is reliable <strong>and<\/strong> ordered, Firefox uses a <a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-rtcweb-data-channel-13#section-6.6\">deprecated\nfragmentation\/reassembly on SCTP PPID level<\/a>. In this mode, Firefox\ncan send an unlimited amount of data to another Firefox browser (or someone who\nhas also implemented that deprecated fragmentation and reassembly mechanism).\nThis has an unintended side-effect for Chromium browsers explained in the\nfollowing section.<\/p>\n<\/li>\n<li>\n<p>If the data channel is not reliable <strong>or<\/strong> not ordered, Firefox behaves the\nsame as Chromium, including the EOR bug. However, Firefox does not close the\ndata channel on <code>EMSGSIZE<\/code> and also handles <code>EAGAIN<\/code>. Older Firefox versions\nsimply discard messages on <code>EMSGSIZE<\/code> without raising an error event at all\n(ouch!). Read the <em>Chromium<\/em> section above for details on the EOR bug.<\/p>\n<\/li>\n<\/ol>\n<h2>Demystifying the 16 KiB Firefox to Chromium Message Size Limit<\/h2>\n<p>First of all, this only applies to ordered <strong>and<\/strong> reliable channels! For\nunordered <strong>or<\/strong> unreliable channels, the limit remains 64 KiB.<\/p>\n<p>To demistify why Firefox cannot send more than 16 KiB to Chromium as stated\n<a href=\"http:\/\/viblast.com\/blog\/2015\/2\/5\/webrtc-data-channel-message-size\">here<\/a>, you'll have to understand that Chromium does not\nimplement the deprecated fragmentation\/reassembly implemented by Firefox for\nordered <strong>and<\/strong> reliable channels.\nAs Firefox fragments the messages into 16 KiB chunks, it sends the first chunks\nwith a different SCTP PPID (<code>52<\/code> for <em>Binary Partial<\/em> or <code>54<\/code> for <em>String\nPartial<\/em>) than the last one (<code>53<\/code> for <em>Binary<\/em> or <code>51<\/code> for <em>String<\/em>).\nHowever, Chromium uses the same handling mechanism for packets with PPID <code>52<\/code>\nand <code>54<\/code> or <code>53<\/code> and <code>51<\/code>, so it receives the packets one by one as sent by\nFirefox. Thus, the application gets 16 KiB messages because that's the chunk\nsize Firefox uses to fragment the message. Chromium just does not reassemble it.<\/p>\n<h2>Can We Fix It?<\/h2>\n<p>Well, yes, but we'll have to be patient. The following subsections indicate\nwhat browser vendors have to do to get rid of the size limitation or at least\nincrease the limit.<\/p>\n<h3>&gt; 16 KiB<\/h3>\n<p>Either Firefox needs to drop support for the already deprecated\nfragmentation\/reassembly at SCTP PPID level or Chromium needs to implement it.\nThis is particularly annoying because it's not as easy to fix as the latter one\nbut remains the lowest common denominator for Firefox and Chromium\ninteroperation until it has been resolved.<\/p>\n<h3>&gt; 64 KiB<\/h3>\n<p>Both Firefox and Chromium have to obey the EOR flag to receive messages as they\nwere sent. This is an easy fix.<\/p>\n<h3>&gt; 256 KiB<\/h3>\n<p>While the browsers could simply increase the buffer of usrsctp, this is not a\ngood idea. A better solution would be to use the EOR flag when passing messages\nto usrsctp via a call to <code>usrsctp_sendv<\/code>. Again, should be an easy fix.<\/p>\n<p>But there's another problem and this is most probably the reason why it hasn't\nbeen done yet: A very big data channel message would lead to head-of-line\nblocking for messages sent by other data channels. To solve that problem, the\n<a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-tsvwg-sctp-ndata-08\">SCTP ndata specification<\/a> has been created. Now, browser vendors\nwait until it is stable before it's being activated in the browsers. This will\ntake a bit of time.<\/p>\n<h2>Contribution<\/h2>\n<p>Thanks to Michael T\u00fcxen for answering my questions regarding usrsctp.<\/p>\n<h2>TL;DR, Gimme Instructions!<\/h2>\n<p>My tests and the code of both Chromium and Firefox indicate that it's safe to\nsend 64 KiB of data between current versions of Firefox and Chromium <strong>unless<\/strong>\nyou're sending from Firefox to Chromium on an ordered <strong>and<\/strong> reliable data\nchannel where 16 KiB is the maximum message size. You'll have to fragment and\nreassemble on application level.<\/p>\n<p>For full support for both reliable and unreliable, ordered and unordered\nchannels, use the <a href=\"https:\/\/github.com\/saltyrtc\/saltyrtc-meta\/blob\/master\/Chunking.md\">SaltyRTC's chunking specification<\/a>\nwhich has been implemented for <a href=\"https:\/\/github.com\/saltyrtc\/chunked-dc-js\">JavaScript<\/a> and\n<a href=\"https:\/\/github.com\/saltyrtc\/chunked-dc-java\">Java<\/a>. Set the chunk size to <code>16384<\/code> if you want to be safe.\nOtherwise, use a chunk size of <code>65536<\/code> in case you're sure that there'll never\nbe a Firefox browser talking to a Chromium browser. You could also implement a\ndetection mechanism for that. If you're doing that, the maximum message size\nneeds to be distributed to the other peer because the problem occurs on the\nreceiver's side.<\/p>\n<p>And while you're at it, consider using <a href=\"https:\/\/github.com\/saltyrtc\/saltyrtc-meta\">SaltyRTC for seriously secure\nsignalling<\/a> to protect your WebRTC\npeer-to-peer connection. <span class=\"e1a-slight_smile e1a-small\"><\/span><\/p>\n<h6>Update - Thu, 30 Jul 2017<\/h6>\n<p>The bug has been filed as <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=979417\">bug 979417<\/a> for Firefox and as\n<a href=\"https:\/\/bugs.chromium.org\/p\/webrtc\/issues\/detail?id=7774\">issue 7774<\/a> for Chromium.<\/p>\n<h6>Update - Fri, 03 Nov 2017<\/h6>\n<p>A <a href=\"https:\/\/lgrahl.de\/articles\/large-dc-messages-firefox.html\">bugfix for this issue<\/a> has been shipped as part\nof Firefox 57. From that version on, messages of 64 KiB can be exchanged safely\nbetween Chromium and Firefox.<\/p>\n<h6>Update - Sun, 19 Aug 2018<\/h6>\n<p>Jeroen de Borst picked up the issue that has been\n<a href=\"https:\/\/bugs.chromium.org\/p\/webrtc\/issues\/detail?id=7774\">filed for Chromium<\/a> and raised the receive limit to 256 KiB.\nWhile this is hardly pushing the limit of whats possible, it is a considerable\nimprovement. Unfortunately the violation of message integrity has not been\naddressed which means that messages larger than 256 KiB will still be delivered\nin chunks. Furthermore, Chromium does not signal the maximum message size which\nmeans that the remote peer is unable to figure out the effective maximum\nmessage size it may use to send data.<\/p>\n<h2>RAWRTC<\/h2>\n<p>There's a standalone WebRTC data channel implementation called <strong>RAWRTC<\/strong>\nwritten by me in C that you can use to send and receive messages of arbitrary\nsize. Browser interoperation works great as well. With the <a href=\"https:\/\/lgrahl.de\/articles\/large-dc-messages-firefox.html\">changes to Firefox\n57<\/a> it's possible to send large application messages\nfrom and to the Firefox browser as well.<\/p>\n<p><a href=\"https:\/\/github.com\/rawrtc\/rawrtc\">Check RAWRTC out on GitHub!<\/a> <span class=\"e1a-hugging e1a-small\"><\/span><\/p>","category":[{"@attributes":{"term":"WebRTC"}},{"@attributes":{"term":"webrtc"}},{"@attributes":{"term":"datachannel"}},{"@attributes":{"term":"chunking"}},{"@attributes":{"term":"saltyrtc"}}]},{"title":"Bachelor Thesis - SaltyRTC - Seriously Secure WebRTC","link":{"@attributes":{"href":"https:\/\/lgrahl.de\/articles\/ba-thesis-saltyrtc.html","rel":"alternate"}},"published":"2015-10-19T10:00:00+02:00","updated":"2017-08-06T19:20:00+02:00","author":{"name":"Lennart Grahl"},"id":"tag:lgrahl.de,2015-10-19:\/articles\/ba-thesis-saltyrtc.html","summary":"<p>In my bachelor thesis, I'm going through the WebRTC protocol, in particular its weakest link - the <em>Signalling Channel<\/em>. This work presents a solution that uses the <em>Networking and Cryptography library<\/em> (NaCl) to provide a secure implementation of the <em>Signalling Channel<\/em> called <em>SaltyRTC<\/em>.<\/p>","content":"<h2>Download<\/h2>\n<p><a href=\"https:\/\/lgrahl.de\/pub\/ba-thesis-saltyrtc-by-lennart-grahl-revised-v1.pdf\">ba-thesis-saltyrtc-by-lennart-grahl-revised-v1.pdf<\/a><\/p>\n<h2>Abstract<\/h2>\n<p><i>WebRTC is an API definition by the World Wide Web Consortium (W3C) which \nobtained a high popularity among browser-to-browser applications. One of the \ncore reasons for that popularity is the simplicity it provides to set up a \npeer-to-peer connection. Although it is often mainly used for audio and video \ncommunication, there is also a <em>Data Channel<\/em> that allows arbitrary \nbidirectional data transfers between two peers. <em>Datagram Transport Layer \nSecurity<\/em> (DTLS), which is based on <em>Transport Layer Security<\/em> (TLS), is being \nused as WebRTC's security layer.<\/p>\n<p>In the recent past, plenty of vulnerabilities in TLS have been revealed and it \nis reasonable to assume that there are more to come. In addition, WebRTC API \nusers have no control over the key pair generation, nor how the public keys are \nbeing exchanged between the peers. However, even more problematic is that \nWebRTC requires an implementation of a <em>Signalling Channel<\/em> to exchange \nmetadata that is required to set up a peer-to-peer connection. This metadata \nalready contains security-relevant information that no third party should be \nable to read or modify, unless it is absolutely necessary for the use case.<\/p>\n<p>This work presents a solution that uses the <em>Networking and Cryptography \nlibrary<\/em> (NaCl) to provide another security layer for WebRTC Data Channels and \na secure implementation of the <em>Signalling Channel<\/em>. The developed software \ncollection is called <em>SaltyRTC<\/em> and will be released on GitHub soon.<\/i><\/p>\n<h2>Contribution<\/h2>\n<p>Thanks to the guys at <a href=\"https:\/\/threema.ch\/\">Threema<\/a> who let me fiddle around \nwith WebRTC freely and gave me the possibility to create a <em>Threema Web Client<\/em> \nprototype.<\/p>\n<h6>Update - Mon, 24 Oct 2016<\/h6>\n<p>The described <em>SaltyRTC<\/em> protocol has since been carefully improved and is now \nofficially specified <a href=\"https:\/\/github.com\/saltyrtc\/saltyrtc-meta\">here<\/a>.<\/p>\n<h6>Update - Wed, 15 Feb 2017<\/h6>\n<p>Nearly two years later, the official <a href=\"https:\/\/threema.ch\/en\/blog\/posts\/threema-web-is-here\">Threema Web Client<\/a> has been\nreleased which is based on technologies established for the prototype\nincluding the <em>SaltyRTC<\/em> signalling protocol.\n<span class=\"e1a-tada e1a-small\"><\/span><\/p>","category":[{"@attributes":{"term":"WebRTC"}},{"@attributes":{"term":"webrtc"}},{"@attributes":{"term":"datachannel"}},{"@attributes":{"term":"saltyrtc"}},{"@attributes":{"term":"threema"}}]}]}