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>