tor-browser

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

RTCSctpTransport-maxMessageSize.html (11735B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>RTCSctpTransport.prototype.maxMessageSize</title>
      4 <link rel="help" href="https://w3c.github.io/webrtc-pc/#rtcsctptransport-interface">
      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 
     11 // This test has an assert_unreached() that requires that the variable
     12 // canSendSize (initiated below) must be 0 or greater than 2. The reason
     13 // is that we need two non-zero values for testing the following two cases:
     14 //
     15 // * if remote MMS `1` < canSendSize it should result in `1`.
     16 // * renegotiation of the above case with remoteMMS `2` should result in `2`.
     17 //
     18 // This is a bit unfortunate but shouldn't have any practical impact.
     19 
     20 // Helper class to read SDP attributes and generate SDPs with modified attribute values
     21 class SDPAttributeHelper {
     22  constructor(attrName, valueRegExpStr) {
     23    this.attrName = attrName;
     24    this.re = new RegExp(`^a=${attrName}:(${valueRegExpStr})\\r\\n`, 'm');
     25  }
     26 
     27  getValue(sdp) {
     28    const matches = sdp.match(this.re);
     29    return matches ? matches[1] : null;
     30  }
     31 
     32  sdpWithValue(sdp, value) {
     33    const matches = sdp.match(this.re);
     34    const sdpParts = sdp.split(matches[0]);
     35    const attributeLine = arguments.length > 1 ? `a=${this.attrName}:${value}\r\n` : '';
     36    return `${sdpParts[0]}${attributeLine}${sdpParts[1]}`;
     37  }
     38 
     39  descWithValue(desc, value) {
     40    const {type, sdp} = desc;
     41    return {type, sdp: this.sdpWithValue(sdp, value)};
     42  }
     43 
     44  descWithoutAttribute(desc) {
     45    return this.descWithValue(desc);
     46  }
     47 }
     48 
     49 promise_test(async (t) => {
     50  const offerer = new RTCPeerConnection();
     51  t.add_cleanup(() => offerer.close());
     52  const answerer = new RTCPeerConnection();
     53  t.add_cleanup(() => answerer.close());
     54 
     55  const channel = offerer.createDataChannel("chat");
     56 
     57  await offerer.setLocalDescription();
     58  await answerer.setRemoteDescription(offerer.localDescription);
     59  await answerer.setLocalDescription();
     60  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
     61  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be greater than zero');
     62 
     63  await offerer.setRemoteDescription(answerer.localDescription);
     64  assert_not_equals(offerer.sctp, null, 'RTCSctpTransport must be available');
     65  assert_greater_than(offerer.sctp.maxMessageSize, 0, 'maxMessageSize should be greater than zero');
     66 
     67  assert_equals(offerer.sctp.maxMessageSize, answerer.sctp.maxMessageSize, 'Offerer and answerer should have the same maxMessageSize');
     68 }, 'Verify that maxMessageSize is greater than zero');
     69 
     70 const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+');
     71 let canSendSize = null;
     72 const remoteSize1 = 1;
     73 const remoteSize2 = 2;
     74 
     75 promise_test(async (t) => {
     76  const offerer = new RTCPeerConnection();
     77  t.add_cleanup(() => offerer.close());
     78  const answerer = new RTCPeerConnection();
     79  t.add_cleanup(() => answerer.close());
     80 
     81  const channel = offerer.createDataChannel("chat");
     82 
     83  assert_equals(offerer.sctp, null, 'RTCSctpTransport must be null');
     84 
     85  await offerer.setLocalDescription();
     86  assert_not_equals(mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
     87    'SDP should have max-message-size attribute');
     88  await answerer.setRemoteDescription(
     89    mmsAttributeHelper.descWithValue(offerer.localDescription, 0));
     90  await answerer.setLocalDescription();
     91 
     92  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available in the offerer');
     93  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive in the offerer');
     94  canSendSize = answerer.sctp.maxMessageSize;
     95 
     96  if (canSendSize < remoteSize2) {
     97    assert_unreached(
     98      'This test needs canSendSize to be at least 2 for further "below" and "above" tests');
     99  }
    100 }, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0');
    101 
    102 promise_test(async (t) => {
    103  assert_not_equals(canSendSize, null, 'canSendSize needs to be determined');
    104 
    105  const offerer = new RTCPeerConnection();
    106  t.add_cleanup(() => offerer.close());
    107  const answerer = new RTCPeerConnection();
    108  t.add_cleanup(() => answerer.close());
    109 
    110  const channel = offerer.createDataChannel("chat");
    111 
    112  assert_equals(offerer.sctp, null, 'RTCSctpTransport must be null');
    113 
    114  await offerer.setLocalDescription();
    115  assert_not_equals(mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    116    'SDP should have max-message-size attribute');
    117 
    118  // Remove the max-message-size SDP attribute
    119  await answerer.setRemoteDescription(
    120    mmsAttributeHelper.descWithoutAttribute(offerer.localDescription));
    121  await answerer.setLocalDescription();
    122 
    123  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    124  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    125  // Test outcome depends on canSendSize value
    126  if (canSendSize !== 0) {
    127    assert_equals(answerer.sctp.maxMessageSize, Math.min(65536, canSendSize),
    128      'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65536, canSendSize)');
    129  } else {
    130    assert_equals(answerer.sctp.maxMessageSize, 65536,
    131      'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65536');
    132  }
    133 }, 'Remote offer SDP missing max-message-size attribute');
    134 
    135 promise_test(async (t) => {
    136  assert_not_equals(canSendSize, null, 'canSendSize needs to be determined');
    137 
    138  const offerer = new RTCPeerConnection();
    139  t.add_cleanup(() => offerer.close());
    140  const answerer = new RTCPeerConnection();
    141  t.add_cleanup(() => answerer.close());
    142 
    143  const channel = offerer.createDataChannel("chat");
    144 
    145  assert_equals(offerer.sctp, null, 'RTCSctpTransport must be null');
    146 
    147  await offerer.setLocalDescription();
    148  assert_not_equals(mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    149    'SDP should have max-message-size attribute');
    150 
    151  await answerer.setRemoteDescription(
    152    mmsAttributeHelper.descWithValue(offerer.localDescription, remoteSize1));
    153  await answerer.setLocalDescription();
    154 
    155  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    156  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    157  assert_equals(answerer.sctp.maxMessageSize, remoteSize1,
    158    'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
    159 }, 'max-message-size with a (non-zero) value provided by the remote peer');
    160 
    161 promise_test(async (t) => {
    162  assert_not_equals(canSendSize, null, 'canSendSize needs to be determined');
    163 
    164  const offerer = new RTCPeerConnection();
    165  t.add_cleanup(() => offerer.close());
    166  const answerer = new RTCPeerConnection();
    167  t.add_cleanup(() => answerer.close());
    168 
    169  const channel = offerer.createDataChannel("chat");
    170 
    171  assert_equals(offerer.sctp, null, 'RTCSctpTransport must be null');
    172 
    173  await offerer.setLocalDescription();
    174  assert_not_equals(mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    175    'SDP should have max-message-size attribute');
    176 
    177  await answerer.setRemoteDescription(
    178    mmsAttributeHelper.descWithValue(offerer.localDescription, remoteSize1));
    179  await answerer.setLocalDescription();
    180  await offerer.setRemoteDescription(answerer.localDescription);
    181 
    182  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    183  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    184  assert_equals(answerer.sctp.maxMessageSize, remoteSize1,
    185    'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
    186 
    187  // Start new O/A exchange that updates max-message-size to remoteSize2
    188  await offerer.setLocalDescription();
    189  assert_not_equals(
    190    mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    191    'SDP should have max-message-size attribute');
    192 
    193  await answerer.setRemoteDescription(
    194    mmsAttributeHelper.descWithValue(offerer.localDescription, remoteSize2));
    195  await answerer.setLocalDescription();
    196  await offerer.setRemoteDescription(answerer.localDescription);
    197 
    198  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    199  assert_not_equals(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should never be 0');
    200  assert_equals(answerer.sctp.maxMessageSize, remoteSize2,
    201    'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)');
    202 
    203  // Start new O/A exchange that updates max-message-size to zero
    204  await offerer.setLocalDescription();
    205  assert_not_equals(
    206    mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    207    'SDP should have max-message-size attribute');
    208 
    209  await answerer.setRemoteDescription(
    210    mmsAttributeHelper.descWithValue(offerer.localDescription, 0));
    211  await answerer.setLocalDescription();
    212  await offerer.setRemoteDescription(answerer.localDescription);
    213 
    214  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    215  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    216  assert_equals(answerer.sctp.maxMessageSize, canSendSize,
    217    'maxMessageSize should be canSendSize');
    218 
    219  // Start new O/A exchange that updates max-message-size to remoteSize1 again
    220  await offerer.setLocalDescription();
    221  assert_not_equals(
    222    mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    223    'SDP should have max-message-size attribute');
    224 
    225  await answerer.setRemoteDescription(
    226    mmsAttributeHelper.descWithValue(offerer.localDescription, remoteSize1));
    227  await answerer.setLocalDescription();
    228  await offerer.setRemoteDescription(answerer.localDescription);
    229 
    230  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    231  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    232  assert_equals(answerer.sctp.maxMessageSize, remoteSize1,
    233    'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)');
    234 }, 'Renegotiate max-message-size with various values provided by the remote peer');
    235 
    236 promise_test(async (t) => {
    237  assert_not_equals(canSendSize, null, 'canSendSize needs to be determined');
    238  const largerThanCanSendSize = canSendSize === 0 ? 0 : canSendSize + 1;
    239 
    240  const offerer = new RTCPeerConnection();
    241  t.add_cleanup(() => offerer.close());
    242  const answerer = new RTCPeerConnection();
    243  t.add_cleanup(() => answerer.close());
    244 
    245  const channel = offerer.createDataChannel("chat");
    246 
    247  assert_equals(offerer.sctp, null, 'RTCSctpTransport must be null');
    248 
    249  await offerer.setLocalDescription();
    250  assert_not_equals(mmsAttributeHelper.getValue(offerer.localDescription.sdp), null,
    251    'SDP should have max-message-size attribute');
    252 
    253  await answerer.setRemoteDescription(
    254    mmsAttributeHelper.descWithValue(offerer.localDescription, largerThanCanSendSize));
    255  await answerer.setLocalDescription();
    256  await offerer.setRemoteDescription(answerer.localDescription);
    257 
    258  assert_not_equals(answerer.sctp, null, 'RTCSctpTransport must be available');
    259  assert_greater_than(answerer.sctp.maxMessageSize, 0, 'maxMessageSize should be positive');
    260  // Test outcome depends on canSendSize value
    261  if (canSendSize !== 0) {
    262    assert_equals(answerer.sctp.maxMessageSize, canSendSize,
    263      'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize');
    264  } else {
    265    assert_equals(answerer.sctp.maxMessageSize, Number.POSITIVE_INFINITY,
    266      'A remote value of zero and canSendSize zero should result in "infinity"');
    267  }
    268 }, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer');
    269 
    270 </script>