tor-browser

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

RTCDtlsTransport-state.html (5159B)


      1 <!doctype html>
      2 <meta charset="utf-8">
      3 <title>RTCDtlsTransport</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="RTCPeerConnection-helper.js"></script>
      7 <script>
      8 'use strict';
      9 
     10 // The following helper functions are called from RTCPeerConnection-helper.js:
     11 //   exchangeIceCandidates
     12 //   exchangeOfferAnswer
     13 //   trackFactories.audio()
     14 
     15 /*
     16    5.5.  RTCDtlsTransport Interface
     17      interface RTCDtlsTransport : EventTarget {
     18        readonly attribute RTCDtlsTransportState state;
     19        sequence<ArrayBuffer> getRemoteCertificates();
     20                 attribute EventHandler          onstatechange;
     21                 attribute EventHandler          onerror;
     22        ...
     23      };
     24 
     25      enum RTCDtlsTransportState {
     26        "new",
     27        "connecting",
     28        "connected",
     29        "closed",
     30        "failed"
     31      };
     32 
     33 */
     34 function resolveWhen(t, dtlstransport, state) {
     35  return new Promise((resolve, reject) => {
     36    if (dtlstransport.state == state) { resolve(); }
     37    dtlstransport.addEventListener('statechange', t.step_func(e => {
     38      if (dtlstransport.state == state) {
     39        resolve();
     40      }
     41    }));
     42  });
     43 }
     44 
     45 
     46 async function setupConnections(t) {
     47  const pc1 = new RTCPeerConnection();
     48  t.add_cleanup(() => pc1.close());
     49  const pc2 = new RTCPeerConnection();
     50  t.add_cleanup(() => pc2.close());
     51 
     52  pc1.addTrack(trackFactories.audio());
     53  const channels = exchangeIceCandidates(pc1, pc2);
     54  await exchangeOfferAnswer(pc1, pc2);
     55  return [pc1, pc2];
     56 }
     57 
     58 promise_test(async t => {
     59  const [pc1, pc2] = await setupConnections(t);
     60  const dtlsTransport1 = pc1.getTransceivers()[0].sender.transport;
     61  const dtlsTransport2 = pc2.getTransceivers()[0].sender.transport;
     62  assert_true(dtlsTransport1 instanceof RTCDtlsTransport);
     63  assert_true(dtlsTransport2 instanceof RTCDtlsTransport);
     64  await Promise.all([resolveWhen(t, dtlsTransport1, 'connected'),
     65                     resolveWhen(t, dtlsTransport2, 'connected')]);
     66 }, 'DTLS transport goes to connected state');
     67 
     68 promise_test(async t => {
     69  const [pc1, pc2] = await setupConnections(t);
     70 
     71  const dtlsTransport1 = pc1.getTransceivers()[0].sender.transport;
     72  const dtlsTransport2 = pc2.getTransceivers()[0].sender.transport;
     73  await Promise.all([resolveWhen(t, dtlsTransport1, 'connected'),
     74                     resolveWhen(t, dtlsTransport2, 'connected')]);
     75  let fired = false;
     76  dtlsTransport1.onstatechange = t.step_func(() => fired = true);
     77  dtlsTransport1.addEventListener('statechange', t.step_func(() => fired = true));
     78  pc1.close();
     79  assert_equals(dtlsTransport1.state, 'closed');
     80  await new Promise(r => t.step_timeout(r, 10));
     81  assert_false(fired, 'close() should not see a statechange event on close');
     82 }, 'close() causes the local transport to close immediately');
     83 
     84 promise_test(async t => {
     85  const [pc1, pc2] = await setupConnections(t);
     86  const dtlsTransport1 = pc1.getTransceivers()[0].sender.transport;
     87  const dtlsTransport2 = pc2.getTransceivers()[0].sender.transport;
     88  await Promise.all([resolveWhen(t, dtlsTransport1, 'connected'),
     89                     resolveWhen(t, dtlsTransport2, 'connected')]);
     90  pc1.close();
     91  await resolveWhen(t, dtlsTransport2, 'closed');
     92 }, 'close() causes the other end\'s DTLS transport to close');
     93 
     94 promise_test(async t => {
     95  const config = {bundlePolicy: "max-bundle"};
     96  const pc1 = new RTCPeerConnection(config);
     97  const pc2 = new RTCPeerConnection(config);
     98  t.add_cleanup(() => pc1.close());
     99  t.add_cleanup(() => pc2.close());
    100 
    101  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
    102  pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
    103 
    104  pc1.addTransceiver("video");
    105  pc1.addTransceiver("audio");
    106  await pc1.setLocalDescription(await pc1.createOffer());
    107  await pc2.setRemoteDescription(pc1.localDescription);
    108  await pc2.setLocalDescription(await pc2.createAnswer());
    109  await pc1.setRemoteDescription(pc2.localDescription);
    110 
    111  const [videoTc, audioTc] = pc1.getTransceivers();
    112  const [videoTp, audioTp] =
    113      pc1.getTransceivers().map(tc => tc.sender.transport);
    114 
    115  const [videoPc2Tp, audioPc2Tp] =
    116      pc2.getTransceivers().map(tc => tc.sender.transport);
    117 
    118  assert_equals(pc1.getTransceivers().length, 2, 'pc1 transceiver count');
    119  assert_equals(pc2.getTransceivers().length, 2, 'pc2 transceiver count');
    120  assert_equals(videoTc.sender.transport, videoTc.receiver.transport);
    121  assert_equals(videoTc.sender.transport, audioTc.sender.transport);
    122 
    123  await Promise.all([resolveWhen(t, videoTp, 'connected'),
    124                     resolveWhen(t, videoPc2Tp, 'connected')]);
    125 
    126  assert_equals(audioTc.sender, pc1.getSenders()[1]);
    127 
    128  let stoppedTransceiver = pc1.getTransceivers()[0];
    129  assert_equals(stoppedTransceiver, videoTc); // sanity
    130  let onended = new Promise(resolve => {
    131    stoppedTransceiver.receiver.track.onended = resolve;
    132  });
    133  stoppedTransceiver.stop();
    134  await onended;
    135 
    136  assert_equals(audioTc.sender, pc1.getSenders()[1]); // sanity
    137  assert_equals(audioTc.sender.transport, audioTp); // sanity
    138  assert_equals(audioTp.state, 'connected');
    139 }, 'stop bundled transceiver retains dtls transport state');
    140 
    141 </script>