tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RTCPeerConnection-iceConnectionState-disconnected.https.html (3119B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <meta name="timeout" content="long">
      4 <title>RTCPeerConnection.prototype.iceConnectionState - disconnection</title>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="RTCPeerConnection-helper.js"></script>
      8 <script>
      9  'use strict';
     10  promise_test(async t => {
     11    const caller = new RTCPeerConnection();
     12    t.add_cleanup(() => caller.close());
     13    const callee = new RTCPeerConnection();
     14    t.add_cleanup(() => callee.close());
     15 
     16    const stream = await getNoiseStream({audio:true});
     17    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     18    const [track] = stream.getTracks();
     19    caller.addTrack(track, stream);
     20    exchangeIceCandidates(caller, callee);
     21    await exchangeOfferAnswer(caller, callee);
     22 
     23    await listenToIceConnected(caller);
     24 
     25    callee.close();
     26    await waitForIceStateChange(caller, ['disconnected', 'failed']);
     27    // TODO: this should eventually transition to failed but that takes
     28    // somewhat long (15-30s) so is not testable.
     29  }, 'ICE goes to disconnected if the other side goes away');
     30 
     31  promise_test(async t => {
     32    const caller = new RTCPeerConnection();
     33    t.add_cleanup(() => caller.close());
     34    const callee = new RTCPeerConnection();
     35    t.add_cleanup(() => callee.close());
     36    caller.addTransceiver('audio', {direction: 'sendrecv'});
     37    exchangeIceCandidates(caller, callee);
     38    await exchangeOfferAnswer(caller, callee);
     39    await listenToIceConnected(caller);
     40 
     41    // Now, we pull a fast one, and convince callee to abandon the transport
     42    // without telling caller.
     43    await caller.setLocalDescription();
     44    await callee.setRemoteDescription(caller.localDescription);
     45    const staleAnswer = await callee.createAnswer();
     46    await callee.setRemoteDescription({type: 'rollback', sdp: ''});
     47 
     48    const mlineRegex = /m=audio [0-9]+ /;
     49    const mungedOfferSdp = caller.localDescription.sdp
     50      .replace(mlineRegex, 'm=audio 0 ')
     51      .replace('BUNDLE', 'BUNGLE'); // Avoid "But that mid is rejected!" errors
     52 
     53    // callee gets the munged reoffer with a rejected m-section, caller gets a
     54    // stale answer that was made before callee saw the rejected m-section.
     55    await callee.setRemoteDescription({type: 'offer', sdp: mungedOfferSdp});
     56    await callee.setLocalDescription();
     57    await caller.setRemoteDescription(staleAnswer);
     58    assert_equals(await nextIceConnectionState(caller), 'disconnected');
     59 
     60    // Now, let's fix this with an ICE restart! callee has already negotiated
     61    // a rejection of the first m-section, so it will tolerate it being
     62    // revived.
     63    caller.restartIce();
     64    await caller.setLocalDescription();
     65    await callee.setRemoteDescription(caller.localDescription);
     66    await callee.setLocalDescription();
     67    await caller.setRemoteDescription(callee.localDescription);
     68    assert_equals(await nextIceConnectionState(caller), 'checking');
     69    assert_equals(await nextIceConnectionState(caller), 'connected');
     70  }, 'ICE restart when ICE is disconnected results in checking, then connected');
     71 
     72 </script>