diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html')
-rw-r--r-- | dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html b/dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html new file mode 100644 index 0000000000..16f8f39978 --- /dev/null +++ b/dom/media/webrtc/tests/mochitests/test_peerConnection_gatherWithStun300IPv6.html @@ -0,0 +1,283 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> + <script type="application/javascript" src="iceTestUtils.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "857668", + title: "RTCPeerConnection check STUN gathering with STUN/300 responses (IPv6)" + }); + + /* This is pretty hairy, so some background: + * Spec is here: https://datatracker.ietf.org/doc/html/rfc8489#section-10 + * STUN/300 responses allow a server to redirect STUN requests to one or + more other servers, as ALTERNATE-SERVER attributes. + * The server specifies the IP address, IP version, and port for each + ALTERNATE-SERVER. + * The spec allows multiple rounds of redirects, and requires the client to + remember the servers it has already tried to avoid redirect loops. + * For TURNS, the TURN server can also supply an ALTERNATE-DOMAIN attribute, + which the client MUST use for the TLS handshake on the new target. The + client does _not_ use this as an FQDN; it always uses the address in the + ALTERNATE-SERVER. ALTERNATE-DOMAIN is meaningless in the non-TLS case. + * STUN/300 with ALTERNATE-SERVER is only defined for the TURN Allocate + message type (at least in the context of ICE). Clients are supposed to + treat STUN/300 as an unrecoverable error in all other cases. The TURN spec + does _not_ spell out how a client should handle multiple ALTERNATE-SERVERs. + We just take the first one that we have not already tried, and that is the + same IP version that we started with. This is because switching the IP + version is problematic for ICE. + * The test TURN server opens extra ports that will respond with redirects to + the _real_ ports, but the address remains the same. This is because we + cannot know ahead of time whether the machine we're running on has more + than one IP address of each version. This means the test TURN server is not + useful for testing cases where the address changes. Also, the test TURN + server does not currently know how to respond with multiple + ALTERNATE-SERVERs. + * To test cases where the _address_ changes, we instead use a feature in the + NAT simulator to respond with fake redirects when the destination address + matches an address that we configure with a pref. This feature can add + multiple ALTERNATE-SERVERs. + * The test TURN server's STUN/300 responses have a proper MESSAGE-INTEGRITY, + but the NAT simulator's do _not_. For now, we want both cases to work, + because some servers respond with STUN/300 without including + MESSAGE-INTEGRITY. This is a spec violation, even though the spec + contradicts itself in non-normative language elsewhere. + * Right now, neither the NAT simulator nor the test TURN server support + ALTERNATE-DOMAIN. + */ + + // These are the ports the test TURN server will respond with redirects on. + // The test TURN server tells us what these are in the JSON it spits out when + // we start it. + let turnRedirectPort; + let turnsRedirectPort; + + // These are the addresses that we will configure the NAT simulator to + // redirect to. We do DNS lookups of the host in iceServersArray (provided + // by the test TURN server), and put the results here. On some platforms this + // will be 127.0.0.1 and ::1, but on others we may use a real address. + let redirectTargetV6; + + // Test TURN server tells us these in the JSON it spits out when we start it + let username; + let credential; + + // This is the address we will configure the NAT simulator to respond with + // redirects for. We use an address from TEST-NET since it is really unlikely + // we'll see that on a real machine, and also because we do not have + // special-case code in nICEr for TEST-NET (like we do for link-local, for + // example). + const redirectAddressV6 = '::ffff:198.51.100.1'; + + const tests = [ + async function baselineV6Cases() { + await checkSrflx([{urls:[`stun:[${redirectTargetV6}]`]}]); + await checkRelayUdp([{urls:[`turn:[${redirectTargetV6}]`], username, credential}]); + await checkRelayTcp([{urls:[`turn:[${redirectTargetV6}]?transport=tcp`], username, credential}]); + await checkRelayUdpTcp([{urls:[`turn:[${redirectTargetV6}]`, `turn:[${redirectTargetV6}]?transport=tcp`], username, credential}]); + }, + + async function stunV6Redirect() { + // This test uses the test TURN server, because nICEr drops responses + // without MESSAGE-INTEGRITY on the floor _unless_ they are a STUN/300 to + // an Allocate request. If we tried to use the NAT simulator for this, we + // would have to wait for nICEr to time out, since the NAT simulator does + // not know how to do MESSAGE-INTEGRITY. + await checkNoSrflx( + [{urls:[`stun:[${redirectTargetV6}]:${turnRedirectPort}`]}]); + }, + + async function turnV6UdpPortRedirect() { + await checkRelayUdp([{urls:[`turn:[${redirectTargetV6}]:${turnRedirectPort}`], username, credential}]); + }, + + async function turnV6TcpPortRedirect() { + await checkRelayTcp([{urls:[`turn:[${redirectTargetV6}]:${turnRedirectPort}?transport=tcp`], username, credential}]); + }, + + async function turnV6UdpTcpPortRedirect() { + await checkRelayUdpTcp([{urls:[`turn:[${redirectTargetV6}]:${turnRedirectPort}`, `turn:[${redirectTargetV6}]:${turnRedirectPort}?transport=tcp`], username, credential}]); + }, + + async function turnV6UdpAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayUdp([{urls:[`turn:[${redirectAddressV6}]`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6TcpAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayTcp([{urls:[`turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpTcpAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayUdpTcp([{urls:[`turn:[${redirectAddressV6}]`, `turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpEmptyRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', '']); + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6TcpEmptyRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', '']); + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpTcpEmptyRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', '']); + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]`, `turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpAddressAndPortRedirect() { + // This should result in two rounds of redirection; the first is by + // address, the second is by port. + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayUdp([{urls:[`turn:[${redirectAddressV6}]:${turnRedirectPort}`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6TcpAddressAndPortRedirect() { + // This should result in two rounds of redirection; the first is by + // address, the second is by port. + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayTcp([{urls:[`turn:[${redirectAddressV6}]:${turnRedirectPort}?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpTcpAddressAndPortRedirect() { + // This should result in two rounds of redirection; the first is by + // address, the second is by port. + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectTargetV6}`]); + await checkRelayUdpTcp([{urls:[`turn:[${redirectAddressV6}]:${turnRedirectPort}`, `turn:[${redirectAddressV6}]:${turnRedirectPort}?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpRedirectLoop() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6}`]); + // If we don't detect the loop, gathering will not finish + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6TcpRedirectLoop() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6}`]); + // If we don't detect the loop, gathering will not finish + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpTcpRedirectLoop() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6}`]); + // If we don't detect the loop, gathering will not finish + await checkNoRelay([{urls:[`turn:[${redirectAddressV6}]`, `turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpMultipleAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6},${redirectTargetV6}`]); + await checkRelayUdp([{urls:[`turn:[${redirectAddressV6}]`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6TcpMultipleAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6},${redirectTargetV6}`]); + await checkRelayTcp([{urls:[`turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + + async function turnV6UdpTcpMultipleAddressRedirect() { + await pushPrefs( + ['media.peerconnection.nat_simulator.redirect_address', `${redirectAddressV6}`], + ['media.peerconnection.nat_simulator.redirect_targets', `${redirectAddressV6},${redirectTargetV6}`]); + await checkRelayUdpTcp([{urls:[`turn:[${redirectAddressV6}]`, `turn:[${redirectAddressV6}]?transport=tcp`], username, credential}]); + await SpecialPowers.popPrefEnv(); + }, + ]; + + runNetworkTest(async () => { + const turnServer = iceServersArray.find(server => "username" in server); + username = turnServer.username; + credential = turnServer.credential; + // Special props, non-standard + turnRedirectPort = turnServer.turn_redirect_port; + turnsRedirectPort = turnServer.turns_redirect_port; + // Just use the first url. It might make sense to look for TURNS first, + // since that will always use a hostname, but on CI we don't have TURNS + // support anyway (see bug 1323439). + const turnHostname = getTurnHostname(turnServer.urls[0]); + + await pushPrefs( + ['media.peerconnection.ice.obfuscate_host_addresses', false], + ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'], + ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT'], + ['media.peerconnection.ice.loopback', true], + ['media.getusermedia.insecure.enabled', true]); + + if (await ipv6Supported()) { + redirectTargetV6 = await dnsLookupV6(turnHostname); + if (redirectTargetV6 == '' && turnHostname == 'localhost') { + // Our testers don't seem to have IPv6 DNS resolution for localhost + // set up... + redirectTargetV6 = '::1'; + } + + if (redirectTargetV6 != '') { + for (const test of tests) { + info(`Running test: ${test.name}`); + await test(); + info(`Done running test: ${test.name}`); + } + } else { + ok(false, `This machine has an IPv6 address, but ${turnHostname} does not resolve to an IPv6 address`); + } + } else { + ok(false, 'This machine appears to not have an IPv6 address'); + } + + await SpecialPowers.popPrefEnv(); + }, { useIceServer: true }); + +</script> +</pre> +</body> +</html> |