Skip to content

Conversation

@lgrahl
Copy link
Collaborator

@lgrahl lgrahl commented Oct 26, 2017

Recent changes in the W3C spec will ensure that a TypeError is thrown in case
a data channel message is being sent that is too large for the other peer to
receive. However, that size limitation needs to be available to the sender or
it's an annoying guessing game.

This PR adds both access to maxMessageSize and throws a TypeError in case
the message is too large for the other peer to receive.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If your company signed a CLA, they designated a Point of Contact who decides which employees are authorized to participate. You may need to contact the Point of Contact for your company and ask to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the project maintainer to go/cla#troubleshoot.
  • In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again.

@googlebot
Copy link

CLAs look good, thanks!

// Note: 65535 bytes is the default value from the SDP spec. Also,
// every implementation we know supports receiving 65535 bytes.
var maxMessageSize = 65535;
var match = arguments[0].sdp.match(/a=max-message-size:\s*(\d+)/);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might consider requiring sdp and using matchPrefix -- its a sub-dependency of the edge shim currently so wouldn't increase "binary size"

@lgrahl
Copy link
Collaborator Author

lgrahl commented Oct 26, 2017

This PR has a few issues I've detected. I'll tick them one by one and then it's ready to be merged (from my side):

  • The local maximum message size needs to be determined, too. Chrome for example will fail beyond 256 KiB even if the remote maximum message size is above that.
  • Even though Firefox<=56 to Firefox<=56 is capable of sending large messages to one another, this PR will prevent that from being possible. This one is tricky... I resolved this in a rather hacky way by looking for mozilla...THIS_IS_SDPARTA in the remote description's SDP.
  • a=max-message-size:0 would fail at the moment.
  • Tests needed.
  • Use matchPrefix instead of regular expressions (where possible).

@lgrahl
Copy link
Collaborator Author

lgrahl commented Oct 28, 2017

The new tests should be fine now but Travis is still failing (in other tests) - ideas?

@lgrahl
Copy link
Collaborator Author

lgrahl commented Oct 28, 2017

FWIW, here's a list of determined maxMessageSize values:

  • FF<=56 to FF<=56: 1073741823 bytes (slightly incorrect but fine)
  • FF<=56 to FF>=57: 1073741823 bytes (slightly incorrect but fine)
  • FF<=56 to Chrome: 16384 bytes
  • FF<=56 to RAWRTC: 16384 bytes (very incorrect but fine)
  • FF>=57 to FF<=56: 1073741823 bytes (slightly incorrect but fine)
  • FF>=57 to FF>=57: 1073741823 bytes
  • FF>=57 to Chrome: 65535 bytes
  • FF>=57 to RAWRTC: 1073741823 bytes
  • Chrome to FF<=56: 65535 bytes
  • Chrome to FF>=57: 65535 bytes
  • Chrome to Chrome: 65535 bytes
  • Chrome to RAWRTC: 65535 bytes
  • RAWRTC to FF<=56: 65535 bytes
  • RAWRTC to FF>=57: 1073741823 bytes
  • RAWRTC to Chrome: 65535 bytes
  • RAWRTC to RAWRTC: unlimited (0)

Couldn't test Safari as I don't own any Apple products.
If you want to know why the incorrect's are fine, just ping me.

@lgrahl
Copy link
Collaborator Author

lgrahl commented Oct 31, 2017

There's one last quirk remaining: I don't know why FF >= 57 doesn't raise an exception in the tests when sending a message that's too large. It does behave correctly when testing this by hand.

@lgrahl
Copy link
Collaborator Author

lgrahl commented Nov 3, 2017

I'm done. Can be reviewed. Some FF stable test timed out on Travis and needs to be restarted (runs fine locally).

Copy link
Contributor

@alvestrand alvestrand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice add, and nice tests, but I worry about the tests that have started failing with AssertionError, where you just patched the expected files (test/e2e/expectations/chrome-beta).

};

var getFirefoxVersion = function(description) {
// TODO: Is there a better solution for detecting Firefox?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is for detecting the remote browser's Firefox version, please call it detectRemoteFirefoxVersion. For local browser, we have utils.detectBrowser().

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

var getCanSendMaxMessageSize = function(description, remoteIsFirefox) {
// Every implementation we know can send at least 64 KiB.
// Note: Although Chrome is technically able to send up to 256 KiB, the
// data does not reach the other peer reliably.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have an issue number for Chrome here, please add it. (If not, please please please file one!)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll check if there is one already or file it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked here

PASS addTrack throws an exception if the track has already been added
PASS addTrack throws an exception if the track has already been added via addStream
PASS addTrack throws an exception if addStream is called with a stream containing a track already added
ERR addTrack throws an exception if addStream is called with a stream containing a track already added AssertionError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have these tests started failling with the patch?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it wasn't my intention to commit this. There was an issue with tests but @fippo told me it might have been a new Chrome beta version. I'll rebase against master and we'll see if it works.

/^a=max-message-size:\s*(\d+)\s*$/gm, '');
description.sdp = description.sdp.replace(
/(^m=application\s+\d+\s+[\w\/]*SCTP.*$)/m,
'$1\r\na=max-message-size:' + maxMessageSize);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this insert a second max-message-size line into your SDP if it already has one?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the replace in line 40 will remove the entire a=max-message-size line if there is one.

it('send largest possible single message', () => {
// Note: Patching to 65535 here as anything beyond that will take too long.
const maxMessageSize = 65535;
const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this test always fail if the negotiated size is < 65535?

Copy link
Collaborator Author

@lgrahl lgrahl Nov 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The short answer is yes, but it's a little bit more complicated than that. Every implementation supports 64 KiB unless one that doesn't handle EOR correctly fiddles with usrsctp's buffer sizes (256 KiB send/receive buffer by default results in the partial delivery size of 64 KiB) which no one has done so far. But there's at least one case where the negotiated size is 16 KiB (Firefox to Chrome). That's not a problem here because these tests will always create a peer connection with the same browser.

// Note: 65535 bytes is the default value from the SDP spec. Also,
// every implementation we know supports receiving 65535 bytes.
var maxMessageSize = 65535;
var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is the sdp package imported? I don't understand why this works ;-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does github not show it in the diff? Also note that you need to add it to package.json, currently it is a child dependeny

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I didn't add it. It was already there. It looks like it is in package.json already? https://github.com/webrtc/adapter/blob/master/package.json#L23

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need new 👓

Copy link
Collaborator Author

@lgrahl lgrahl Nov 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. Me too. 😁 And it's better to double-check.

@lgrahl lgrahl force-pushed the dc-max-message-size branch from ba8c0fa to 7ac36d9 Compare November 9, 2017 11:56
@lgrahl
Copy link
Collaborator Author

lgrahl commented Nov 9, 2017

Rebased against master.

}

var sctpInDescription = function(description) {
var match = description.sdp.match(/m=application\s+\d+\s+[\w/]*SCTP/);
Copy link
Member

@fippo fippo Nov 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about this:

      var sections = SDPUtils.splitSections(description.sdp);
      sections.shift();
      return sections.some(function(mediaSection) {
        var mLine = SDPUtils.parseMLine(mediaSection);
        return mLine && mLine.kind === 'application'
            && mLine.protocol === 'DTLS/SCTP';
      });

if we have SDPUtils anyway... needs a min version of 2.4.0 however

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I don't mind either solutions. Be aware that it may not always be DTLS/SCTP but also UDP/DTLS/SCTP and TCP/DTLS/SCTP, see: https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-4.2

@alvestrand
Copy link
Contributor

Someone modified the DTMF test to use a transceiver. Transceivers aren't in Chrome stable.
I don't understand how this could be caused by this PR, so perhaps mainline is busted?

@fippo
Copy link
Member

fippo commented Nov 11, 2017

@alvestrand no. The transceiver check fails (https://travis-ci.org/webrtc/adapter/jobs/299697848#L2760) but that is in the expectation file.

The DTMF/addTrack test which fails against expectation has been flaky (on travis) for quite some time. More so with experimental webplatform features if I recall correctly. Hitting rerun (which requires commit bit unfortunately) a couple of times usually solves it :-/

(I would only do so after squashing)

@lgrahl
Copy link
Collaborator Author

lgrahl commented Nov 28, 2017

Anything left preventing this from being merged?

@KaptenJansson
Copy link
Collaborator

Set for major release since this a new shim?

@fippo
Copy link
Member

fippo commented Dec 8, 2017

minor version is for new features. Unless 🐔 🐔 🐔

@lgrahl
Copy link
Collaborator Author

lgrahl commented Dec 16, 2017

Ping.

Edit: I just found a minor bug: The default MMS should be 65536 instead of 65535... always gets me. 😒 Will push a fix.

Edit: This also affects FF >= 57. If we can't get a backport fix, this PR will need updating once more.

@lgrahl
Copy link
Collaborator Author

lgrahl commented Dec 21, 2017

FF 57 will not be fixed, so I'll add a fix to this PR.
I'll also add some further tests to go through a lot of negotiated MMS cases because they're pretty complicated now.

@lgrahl
Copy link
Collaborator Author

lgrahl commented Dec 21, 2017

Some tests disconnected and need to be restarted. (Some still fail in other places but I guess you know that already as it's also happening on master.)

Fix handle maxMessageSize 0 case properly
Fix handle corner case for maxMessageSize when sending from FF to FF
Fix handle yet another corner case for maxMessageSize when sending from FF < 57 (uses 16 KiB chunks)
… well

There's a bug in the implementation of FF 57, so DOMError is raised instead of TypeError. I hope we can land a hotfix for that but it shouldn't prevent us from merging this now.
…ror (apparently, I've misinterpreted the spec and this is how it should be done)

Fix max message size tests
…l maximum message size at all)

Remove MMS 0 case test (not really applicable to an e2e test)
…n various combinations

Fix default remote maximum message size for Firefox
Fix default remote message size for Firefox 57
Don't apply the 'send' shim to Firefox >= 57
Export commonShim to window.adapter as well
@lgrahl lgrahl force-pushed the dc-max-message-size branch from b88320b to ded8522 Compare December 21, 2017 23:04
@lgrahl
Copy link
Collaborator Author

lgrahl commented Dec 21, 2017

Rebased against master.
Currently investigating why the test runner doesn't catch the exception raised by the native send call of Firefox >= 57.

Add a MMS test for subsequent data channels

The send shim has been re-enabled for Firefox >= 57 due to the following bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
@lgrahl
Copy link
Collaborator Author

lgrahl commented Dec 26, 2017

Resolved the problem with the test. It turned out to be a bug in Firefox and I had to dramatically decrease the maximum message size.

Please, don't be irritated by me adding more commits. It's just that I didn't want to hold back these changes. It's good to merge now (from my side) and I'll backlog further changes in another branch until this is getting merged.

Edit: URL fixed.

@fippo
Copy link
Member

fippo commented Dec 26, 2017

finding bugs by writing code... 👍 👍 👍

@KaptenJansson
Copy link
Collaborator

@alvestrand any thoughts?

@alvestrand
Copy link
Contributor

Looks good to me, and the "update branch" button worked (for a wonder). I'll merge it once the checks complete.

@KaptenJansson KaptenJansson merged commit ba25960 into webrtcHacks:master Jan 16, 2018
@lgrahl lgrahl deleted the dc-max-message-size branch March 29, 2018 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants