[webrtc-pc] transceiver.stop() needs more work (avoid BUNDLE footgun) (#2150)

jan-ivar has just created a new issue for https://github.com/w3c/webrtc-pc:

== transceiver.stop() needs more work (avoid BUNDLE footgun) ==
Most API complaints I hear are from people negotiating manually. It's hard to get right, and steeped in historical reasons (needing to munge SDP, Chrome's `negotiationneeded` not working). So let's check in on `negotiationneeded`:

button.onclick = () => pc.getTransceivers()[0].stop();

pc.onnegotiationneeded = async e => {
  await pc1.setLocalDescription(await pc1.createOffer());
  await pc2.setRemoteDescription(pc1.localDescription);
  await pc2.setLocalDescription(await pc2.createAnswer());
  await pc1.setRemoteDescription(pc2.localDescription);
Clicking the button will most likely stop only the first transceiver, but once in a blue moon it will stop all of them. That's broken. 😞

Quick reason: `stop()` on the first transceiver marks this BUNDLE transport as a goner on next negotiation; hardly noticeable in `"stable"` state, since a new one pops up on next negotiation. But in `"have-remote-offer"` state, there's no allowance for creating or finding a replacement transport in the answer. The BUNDLE spec has painted us in a corner here.

I think we must address this.

### Proposal

`transceiver.stop()` is already a bit weird, in that it's both instant *and* a negotiated property. I think we can solve this by making `transceiver.[[Stopped]]` more like `transceiver.[[Direction]]`. That is: postpone the effects—and more importantly, the expectations—of stop until negotiation. This should gives us the leeway to avoid rejecting the BUNDLE transport and instead leave the negotiationneeded flag set for next round. This might mean needing a new method—perhaps `transceiver.reject()`—if we're interested in the old behavior.

Please view or discuss this issue at https://github.com/w3c/webrtc-pc/issues/2150 using your GitHub account

Received on Thursday, 28 March 2019 15:10:43 UTC