tor-browser

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

rtx-codecs.https.html (4872B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>RTX codec integrity checks</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="../RTCPeerConnection-helper.js"></script>
      7 <script src="../third_party/sdp/sdp.js"></script>
      8 <script>
      9 'use strict';
     10 
     11 // Tests for conformance to rules for RTX codecs.
     12 // Basic rule: Offers and answers must contain RTX codecs, and the
     13 // RTX codecs must have an a=fmtp line that points to a non-RTX codec.
     14 
     15 // Helper function for doing one round of offer/answer exchange
     16 // between two local peer connections.
     17 // Calls setRemoteDescription(offer/answer) before
     18 // setLocalDescription(offer/answer) to ensure the remote description
     19 // is set and candidates can be added before the local peer connection
     20 // starts generating candidates and ICE checks.
     21 async function doSignalingHandshake(localPc, remotePc, options={}) {
     22  let offer = await localPc.createOffer();
     23  // Modify offer if callback has been provided
     24  if (options.modifyOffer) {
     25    offer = await options.modifyOffer(offer);
     26  }
     27 
     28  // Apply offer.
     29  await remotePc.setRemoteDescription(offer);
     30  await localPc.setLocalDescription(offer);
     31 
     32  let answer = await remotePc.createAnswer();
     33  // Modify answer if callback has been provided
     34  if (options.modifyAnswer) {
     35    answer = await options.modifyAnswer(answer);
     36  }
     37 
     38  // Apply answer.
     39  await localPc.setRemoteDescription(answer);
     40  await remotePc.setLocalDescription(answer);
     41 }
     42 
     43 function verifyRtxReferences(description) {
     44  const mediaSection = SDPUtils.getMediaSections(description.sdp)[0];
     45  const rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
     46  for (const codec of rtpParameters.codecs) {
     47    if (codec.name === 'rtx') {
     48      assert_own_property(codec.parameters, 'apt', 'rtx codec has apt parameter');
     49      const referenced_codec = rtpParameters.codecs.find(
     50        c => c.payloadType === parseInt(codec.parameters.apt));
     51      assert_true(referenced_codec !== undefined, `Found referenced codec`);
     52    }
     53  }
     54 }
     55 
     56 
     57 
     58 promise_test(async t => {
     59  const pc = new RTCPeerConnection();
     60  const offer = await generateVideoReceiveOnlyOffer(pc);
     61  verifyRtxReferences(offer);
     62 }, 'Initial offer should have sensible RTX mappings');
     63 
     64 async function negotiateAndReturnAnswer(t) {
     65  const pc1 = new RTCPeerConnection();
     66  const pc2 = new RTCPeerConnection();
     67  t.add_cleanup(() => pc1.close());
     68  t.add_cleanup(() => pc2.close());
     69  let [track, streams] = await getTrackFromUserMedia('video');
     70  const sender = pc1.addTrack(track);
     71  await doSignalingHandshake(pc1, pc2);
     72  return pc2.localDescription;
     73 }
     74 
     75 promise_test(async t => {
     76  const answer = await negotiateAndReturnAnswer(t);
     77  verifyRtxReferences(answer);
     78 }, 'Self-negotiated answer should have sensible RTX parameters');
     79 
     80 promise_test(async t => {
     81  const sampleOffer = `v=0
     82 o=- 1878890426675213188 2 IN IP4 127.0.0.1
     83 s=-
     84 t=0 0
     85 a=group:BUNDLE video
     86 a=msid-semantic: WMS
     87 m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99
     88 c=IN IP4 0.0.0.0
     89 a=rtcp:9 IN IP4 0.0.0.0
     90 a=ice-ufrag:RGPK
     91 a=ice-pwd:rAyHEAKC7ckxQgWaRZXukz+Z
     92 a=ice-options:trickle
     93 a=fingerprint:sha-256 8C:29:0A:8F:11:06:BF:1C:58:B3:CA:E6:F1:F1:DC:99:4C:6C:89:E9:FF:BC:D4:38:11:18:1F:40:19:C8:49:37
     94 a=setup:actpass
     95 a=mid:video
     96 a=recvonly
     97 a=rtcp-mux
     98 a=rtpmap:97 rtx/90000
     99 a=fmtp:97 apt=98
    100 a=rtpmap:98 VP8/90000
    101 a=rtcp-fb:98 ccm fir
    102 a=rtcp-fb:98 nack
    103 a=rtcp-fb:98 nack pli
    104 a=rtcp-fb:98 goog-remb
    105 a=rtcp-fb:98 transport-cc
    106 `;
    107  const pc = new RTCPeerConnection();
    108  let [track, streams] = await getTrackFromUserMedia('video');
    109  const sender = pc.addTrack(track);
    110  await pc.setRemoteDescription({type: 'offer', sdp: sampleOffer});
    111  const answer = await pc.createAnswer();
    112  verifyRtxReferences(answer);
    113 }, 'A remote offer generates sensible RTX references in answer');
    114 
    115 promise_test(async t => {
    116  const sampleOffer = `v=0
    117 o=- 1878890426675213188 2 IN IP4 127.0.0.1
    118 s=-
    119 t=0 0
    120 a=group:BUNDLE video
    121 a=msid-semantic: WMS
    122 m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99
    123 c=IN IP4 0.0.0.0
    124 a=rtcp:9 IN IP4 0.0.0.0
    125 a=ice-ufrag:RGPK
    126 a=ice-pwd:rAyHEAKC7ckxQgWaRZXukz+Z
    127 a=ice-options:trickle
    128 a=fingerprint:sha-256 8C:29:0A:8F:11:06:BF:1C:58:B3:CA:E6:F1:F1:DC:99:4C:6C:89:E9:FF:BC:D4:38:11:18:1F:40:19:C8:49:37
    129 a=setup:actpass
    130 a=mid:video
    131 a=recvonly
    132 a=rtcp-mux
    133 a=rtpmap:96 VP8/90000
    134 a=rtpmap:97 rtx/90000
    135 a=fmtp:97 apt=98
    136 a=rtpmap:98 VP8/90000
    137 a=rtcp-fb:98 ccm fir
    138 a=rtcp-fb:98 nack
    139 a=rtcp-fb:98 nack pli
    140 a=rtcp-fb:98 goog-remb
    141 a=rtcp-fb:98 transport-cc
    142 a=rtpmap:99 rtx/90000
    143 a=fmtp:99 apt=96
    144 `;
    145  const pc = new RTCPeerConnection();
    146  let [track, streams] = await getTrackFromUserMedia('video');
    147  const sender = pc.addTrack(track);
    148  await pc.setRemoteDescription({type: 'offer', sdp: sampleOffer});
    149  const answer = await pc.createAnswer();
    150  verifyRtxReferences(answer);
    151 }, 'A remote offer with duplicate codecs generates sensible RTX references in answer');
    152 
    153 </script>