Proposal for IceGatherer.getOrCreateTransport

At the last ORTC meeting, we realized that doing the following three things
at the same time is hard:

1.  Respond to STUN binding requests before the remote ufrag is known.
2.  Not buffer STUN packets in the IceGatherer.
3.  Support call forking

​I said I would propose a solution :).

​If we drop #3, all we need is to pass an IceGatherer into an IceTransport
constructor, and that makes the IceTransport able to receive the STUN
traffic for incoming binding requests and send back responses.

But if we have multiple remote ICE ufrags (as we do with call forking) ,
then we need a way to match up the remote ufrags in the incoming STUN
traffic with the remote ufrags received.  A naive approach would be to do
something like:

if (iceTransport1.remoteUfrag == signalledRemoteUfrag) {
  iceTransport1.start(... signalledRemoteUfrag ...);
}

Because it's possible for the browser to receive a STUN binding request and
send a binding response in between those two lines, in which case the
ufrags won't match.

The only solution I can come up with is to have an atomic operation that
means "give me the ice transport with the matching ufrag, or create one if
there isn't one", so that you know that the iceTransport you have has the
correct ufrag and there won't be a mismatch".


Thus:

partial interface IceGatherer {
  IceTransport getOrCreateTransport(DOMString remoteUfrag);
}

Which can then be used like so:

var iceTransport = iceGatherer.getOrCreateTransport(signalledRemoteUfrag);
iceTransport.start(.... signalledRemoteUfrag ...);


And even if there are N incoming remote ufrags, the one returned is always
going to have the given ufrag.  In a full forking situation, you might do
something like this:


IceGatherer gatherer = new IceGatherer();
// Create pool
var transports = [];
for (var = 0; i < 10; i++) {
  var transport = new IceTransport(transports.push(transport));
}
// Later, when you get the remote parameters:
var transport = gatherer.getOrCreateTransport(remoteParams.ufrag);
transports.start(gatherer, remoteParams);



The only issue I can see is that you might get a DTLS packet after
responding to a STUN binding request but before receiving signalling.  I'm
not sure if that's a serious enough problem to try and fix.  Worst case is
that DTLS takes a little longer to setup when doing call forking.  And if
did think it was a serious issue, we could have each IceTransport buffer a
few DTLS packets and that would probably be enough, with a very small
buffer.

Received on Thursday, 11 June 2015 08:48:20 UTC