aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSameer Vijaykar <samvi@google.com>2022-12-02 17:07:07 +0100
committerWebRTC LUCI CQ <webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-12-05 13:34:57 +0000
commitdef85594ea34dec2c1cd8fd58835430c224899c7 (patch)
tree7efef7ec6b8f7d088d8c993f878ae562a3e9d8b4
parenta422e93d7b1d05b13dc3d1f1bc95e49785e9c55d (diff)
downloadwebrtc-def85594ea34dec2c1cd8fd58835430c224899c7.tar.gz
Resolve TURN hostname specific to network family behind field trial.
Already implemented for STUN hostname resolution, but TURN port resolves hostnames separately. Reusing the field trial key reserved in bugs.webrtc.org/14334 but with a new parameter so as to not affect ongoing rollouts. Bug: webrtc:14319, webrtc:14131 Change-Id: Idf771fb2f0de7849f8b701be8ee05a98b8d242f3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/285981 Reviewed-by: Jonas Oreland <jonaso@webrtc.org> Commit-Queue: Sameer Vijaykar <samvi@google.com> Cr-Commit-Position: refs/heads/main@{#38811}
-rw-r--r--p2p/BUILD.gn2
-rw-r--r--p2p/base/mock_dns_resolving_packet_socket_factory.h53
-rw-r--r--p2p/base/stun_port_unittest.cc43
-rw-r--r--p2p/base/turn_port.cc31
-rw-r--r--p2p/base/turn_port_unittest.cc228
5 files changed, 274 insertions, 83 deletions
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index d46955f659..ee18dd5c77 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -205,6 +205,7 @@ if (rtc_include_tests) {
"base/fake_packet_transport.h",
"base/mock_active_ice_controller.h",
"base/mock_async_resolver.h",
+ "base/mock_dns_resolving_packet_socket_factory.h",
"base/mock_ice_agent.h",
"base/mock_ice_controller.h",
"base/mock_ice_transport.h",
@@ -220,6 +221,7 @@ if (rtc_include_tests) {
":rtc_p2p",
"../api:dtls_transport_interface",
"../api:libjingle_peerconnection_api",
+ "../api:mock_async_dns_resolver",
"../api:packet_socket_factory",
"../api:sequence_checker",
"../api:turn_customizer",
diff --git a/p2p/base/mock_dns_resolving_packet_socket_factory.h b/p2p/base/mock_dns_resolving_packet_socket_factory.h
new file mode 100644
index 0000000000..8f18e9b0e1
--- /dev/null
+++ b/p2p/base/mock_dns_resolving_packet_socket_factory.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef P2P_BASE_MOCK_DNS_RESOLVING_PACKET_SOCKET_FACTORY_H_
+#define P2P_BASE_MOCK_DNS_RESOLVING_PACKET_SOCKET_FACTORY_H_
+
+#include <functional>
+#include <memory>
+
+#include "api/test/mock_async_dns_resolver.h"
+#include "p2p/base/basic_packet_socket_factory.h"
+
+namespace rtc {
+
+// A PacketSocketFactory implementation for tests that uses a mock DnsResolver
+// and allows setting expectations on the resolver and results.
+class MockDnsResolvingPacketSocketFactory : public BasicPacketSocketFactory {
+ public:
+ using Expectations = std::function<void(webrtc::MockAsyncDnsResolver*,
+ webrtc::MockAsyncDnsResolverResult*)>;
+
+ explicit MockDnsResolvingPacketSocketFactory(SocketFactory* socket_factory)
+ : BasicPacketSocketFactory(socket_factory) {}
+
+ std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAsyncDnsResolver()
+ override {
+ std::unique_ptr<webrtc::MockAsyncDnsResolver> resolver =
+ std::make_unique<webrtc::MockAsyncDnsResolver>();
+ if (expectations_) {
+ expectations_(resolver.get(), &resolver_result_);
+ }
+ return resolver;
+ }
+
+ void SetExpectations(Expectations expectations) {
+ expectations_ = expectations;
+ }
+
+ private:
+ webrtc::MockAsyncDnsResolverResult resolver_result_;
+ Expectations expectations_;
+};
+
+} // namespace rtc
+
+#endif // P2P_BASE_MOCK_DNS_RESOLVING_PACKET_SOCKET_FACTORY_H_
diff --git a/p2p/base/stun_port_unittest.cc b/p2p/base/stun_port_unittest.cc
index 59841adeef..3d56636a9b 100644
--- a/p2p/base/stun_port_unittest.cc
+++ b/p2p/base/stun_port_unittest.cc
@@ -14,6 +14,7 @@
#include "api/test/mock_async_dns_resolver.h"
#include "p2p/base/basic_packet_socket_factory.h"
+#include "p2p/base/mock_dns_resolving_packet_socket_factory.h"
#include "p2p/base/test_stun_server.h"
#include "rtc_base/gunit.h"
#include "rtc_base/helpers.h"
@@ -34,10 +35,6 @@ using ::testing::Return;
using ::testing::ReturnPointee;
using ::testing::SetArgPointee;
-using DnsResolverExpectations =
- std::function<void(webrtc::MockAsyncDnsResolver*,
- webrtc::MockAsyncDnsResolverResult*)>;
-
static const SocketAddress kLocalAddr("127.0.0.1", 0);
static const SocketAddress kIPv6LocalAddr("::1", 0);
static const SocketAddress kStunAddr1("127.0.0.1", 5000);
@@ -61,34 +58,6 @@ static const int kHighCostPortKeepaliveLifetimeMs = 2 * 60 * 1000;
constexpr uint64_t kTiebreakerDefault = 44444;
-// A PacketSocketFactory implementation that uses a mock DnsResolver and allows
-// setting expectations on the resolver and results.
-class MockDnsResolverPacketSocketFactory
- : public rtc::BasicPacketSocketFactory {
- public:
- explicit MockDnsResolverPacketSocketFactory(
- rtc::SocketFactory* socket_factory)
- : rtc::BasicPacketSocketFactory(socket_factory) {}
-
- std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAsyncDnsResolver()
- override {
- std::unique_ptr<webrtc::MockAsyncDnsResolver> resolver =
- std::make_unique<webrtc::MockAsyncDnsResolver>();
- if (expectations_) {
- expectations_(resolver.get(), &resolver_result_);
- }
- return resolver;
- }
-
- void SetExpectations(DnsResolverExpectations expectations) {
- expectations_ = expectations;
- }
-
- private:
- webrtc::MockAsyncDnsResolverResult resolver_result_;
- DnsResolverExpectations expectations_;
-};
-
class FakeMdnsResponder : public webrtc::MdnsResponderInterface {
public:
void CreateNameForAddress(const rtc::IPAddress& addr,
@@ -334,12 +303,13 @@ class StunPortWithMockDnsResolverTest : public StunPortTest {
return &socket_factory_;
}
- void SetDnsResolverExpectations(DnsResolverExpectations expectations) {
+ void SetDnsResolverExpectations(
+ rtc::MockDnsResolvingPacketSocketFactory::Expectations expectations) {
socket_factory_.SetExpectations(expectations);
}
private:
- MockDnsResolverPacketSocketFactory socket_factory_;
+ rtc::MockDnsResolvingPacketSocketFactory socket_factory_;
};
// Test that we can get an address from a STUN server specified by a hostname.
@@ -682,12 +652,13 @@ class StunIPv6PortTestWithMockDnsResolver : public StunIPv6PortTest {
return &socket_factory_;
}
- void SetDnsResolverExpectations(DnsResolverExpectations expectations) {
+ void SetDnsResolverExpectations(
+ rtc::MockDnsResolvingPacketSocketFactory::Expectations expectations) {
socket_factory_.SetExpectations(expectations);
}
private:
- MockDnsResolverPacketSocketFactory socket_factory_;
+ rtc::MockDnsResolvingPacketSocketFactory socket_factory_;
};
// Test that we can get an address from a STUN server specified by a hostname.
diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc
index 970d6adec6..3879ceb63a 100644
--- a/p2p/base/turn_port.cc
+++ b/p2p/base/turn_port.cc
@@ -26,6 +26,7 @@
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/checks.h"
+#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/socket_address.h"
@@ -33,6 +34,26 @@
namespace cricket {
+namespace {
+
+bool ResolveTurnHostnameForFamily(const webrtc::FieldTrialsView& field_trials) {
+ // Bug fix for TURN hostname resolution on IPv6.
+ // Field trial key reserved in bugs.webrtc.org/14334
+ static constexpr char field_trial_name[] =
+ "WebRTC-IPv6NetworkResolutionFixes";
+ if (!field_trials.IsEnabled(field_trial_name)) {
+ return false;
+ }
+
+ webrtc::FieldTrialParameter<bool> resolve_turn_hostname_for_family(
+ "ResolveTurnHostnameForFamily", /*default_value=*/false);
+ webrtc::ParseFieldTrial({&resolve_turn_hostname_for_family},
+ field_trials.Lookup(field_trial_name));
+ return resolve_turn_hostname_for_family;
+}
+
+} // namespace
+
using ::webrtc::SafeTask;
using ::webrtc::TaskQueueBase;
using ::webrtc::TimeDelta;
@@ -798,7 +819,7 @@ void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) {
RTC_LOG(LS_INFO) << ToString() << ": Starting TURN host lookup for "
<< address.ToSensitiveString();
resolver_ = socket_factory()->CreateAsyncDnsResolver();
- resolver_->Start(address, [this] {
+ auto callback = [this] {
// If DNS resolve is failed when trying to connect to the server using TCP,
// one of the reason could be due to DNS queries blocked by firewall.
// In such cases we will try to connect to the server with hostname,
@@ -829,7 +850,13 @@ void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) {
}
server_address_.address = resolved_address;
PrepareAddress();
- });
+ };
+ // TODO(bugs.webrtc.org/14733): remove duplicate resolution with STUN port.
+ if (ResolveTurnHostnameForFamily(field_trials())) {
+ resolver_->Start(address, Network()->family(), std::move(callback));
+ } else {
+ resolver_->Start(address, std::move(callback));
+ }
}
void TurnPort::OnSendStunPacket(const void* data,
diff --git a/p2p/base/turn_port_unittest.cc b/p2p/base/turn_port_unittest.cc
index 1d51c08f20..3f01fbef1b 100644
--- a/p2p/base/turn_port_unittest.cc
+++ b/p2p/base/turn_port_unittest.cc
@@ -22,6 +22,7 @@
#include "api/units/time_delta.h"
#include "p2p/base/basic_packet_socket_factory.h"
#include "p2p/base/connection.h"
+#include "p2p/base/mock_dns_resolving_packet_socket_factory.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/stun_port.h"
@@ -44,8 +45,16 @@
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"
+namespace {
using rtc::SocketAddress;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InvokeArgument;
+using ::testing::Return;
+using ::testing::ReturnPointee;
+using ::testing::SetArgPointee;
+
static const SocketAddress kLocalAddr1("11.11.11.11", 0);
static const SocketAddress kLocalAddr2("22.22.22.22", 0);
static const SocketAddress kLocalIPv6Addr("2401:fa00:4:1000:be30:5bff:fee5:c3",
@@ -77,6 +86,7 @@ static const SocketAddress kTurnUdpIPv6IntAddr(
"2400:4030:1:2c00:be30:abcd:efab:cdef",
cricket::TURN_SERVER_PORT);
static const SocketAddress kTurnInvalidAddr("www.google.invalid.", 3478);
+static const SocketAddress kTurnValidAddr("www.google.valid.", 3478);
static const char kCandidateFoundation[] = "foundation";
static const char kIceUfrag1[] = "TESTICEUFRAG0001";
@@ -114,9 +124,12 @@ static const cricket::ProtocolAddress kTurnPort80ProtoAddr(kTurnPort80Addr,
cricket::PROTO_TCP);
static const cricket::ProtocolAddress kTurnPort443ProtoAddr(kTurnPort443Addr,
cricket::PROTO_TCP);
-static const cricket::ProtocolAddress kTurnPortHostnameProtoAddr(
+static const cricket::ProtocolAddress kTurnPortInvalidHostnameProtoAddr(
kTurnInvalidAddr,
cricket::PROTO_UDP);
+static const cricket::ProtocolAddress kTurnPortValidHostnameProtoAddr(
+ kTurnValidAddr,
+ cricket::PROTO_UDP);
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
static int GetFDCount() {
@@ -133,6 +146,8 @@ static int GetFDCount() {
}
#endif
+} // unnamed namespace
+
namespace cricket {
class TurnPortTestVirtualSocketServer : public rtc::VirtualSocketServer {
@@ -180,8 +195,8 @@ class TurnPortTest : public ::testing::Test,
TurnPortTest()
: ss_(new TurnPortTestVirtualSocketServer()),
main_(ss_.get()),
- socket_factory_(ss_.get()),
- turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
+ turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
+ socket_factory_(ss_.get()) {
// Some code uses "last received time == 0" to represent "nothing received
// so far", so we need to start the fake clock at a nonzero time...
// TODO(deadbeef): Fix this.
@@ -280,7 +295,7 @@ class TurnPortTest : public ::testing::Test,
config.credentials = RelayCredentials(username, password);
CreateRelayPortArgs args;
args.network_thread = &main_;
- args.socket_factory = &socket_factory_;
+ args.socket_factory = socket_factory();
args.network = network;
args.username = kIceUfrag1;
args.password = kIcePwd1;
@@ -314,7 +329,7 @@ class TurnPortTest : public ::testing::Test,
RTC_CHECK(server_address.proto == PROTO_UDP);
if (!socket_) {
- socket_.reset(socket_factory_.CreateUdpSocket(
+ socket_.reset(socket_factory()->CreateUdpSocket(
rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
ASSERT_TRUE(socket_ != NULL);
socket_->SignalReadPacket.connect(this,
@@ -325,7 +340,7 @@ class TurnPortTest : public ::testing::Test,
config.credentials = RelayCredentials(username, password);
CreateRelayPortArgs args;
args.network_thread = &main_;
- args.socket_factory = &socket_factory_;
+ args.socket_factory = socket_factory();
args.network = MakeNetwork(kLocalAddr1);
args.username = kIceUfrag1;
args.password = kIcePwd1;
@@ -356,7 +371,7 @@ class TurnPortTest : public ::testing::Test,
void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
void CreateUdpPort(const SocketAddress& address) {
- udp_port_ = UDPPort::Create(&main_, &socket_factory_, MakeNetwork(address),
+ udp_port_ = UDPPort::Create(&main_, socket_factory(), MakeNetwork(address),
0, 0, kIceUfrag2, kIcePwd2, false,
absl::nullopt, &field_trials_);
// UDP port will be controlled.
@@ -436,8 +451,19 @@ class TurnPortTest : public ::testing::Test,
return true;
}
+ void TestTurnAllocateSucceeds(unsigned int timeout) {
+ ASSERT_TRUE(turn_port_);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, timeout, fake_clock_);
+ ASSERT_EQ(1U, turn_port_->Candidates().size());
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turn_port_->Candidates()[0].address().ipaddr());
+ EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ }
+
void TestReconstructedServerUrl(ProtocolType protocol_type,
absl::string_view expected_url) {
+ ASSERT_TRUE(turn_port_);
turn_port_->PrepareAddress();
ASSERT_TRUE_SIMULATED_WAIT(
turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
@@ -762,6 +788,10 @@ class TurnPortTest : public ::testing::Test,
}
protected:
+ virtual rtc::PacketSocketFactory* socket_factory() {
+ return &socket_factory_;
+ }
+
webrtc::test::ScopedKeyValueConfig field_trials_;
rtc::ScopedFakeClock fake_clock_;
// When a "create port" helper method is called with an IP, we create a
@@ -770,7 +800,6 @@ class TurnPortTest : public ::testing::Test,
std::list<rtc::Network> networks_;
std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
rtc::AutoSocketServerThread main_;
- rtc::BasicPacketSocketFactory socket_factory_;
std::unique_ptr<rtc::AsyncPacketSocket> socket_;
TestTurnServer turn_server_;
std::unique_ptr<TurnPort> turn_port_;
@@ -789,6 +818,9 @@ class TurnPortTest : public ::testing::Test,
rtc::PacketOptions options;
std::unique_ptr<webrtc::TurnCustomizer> turn_customizer_;
cricket::IceCandidateErrorEvent error_event_;
+
+ private:
+ rtc::BasicPacketSocketFactory socket_factory_;
};
TEST_F(TurnPortTest, TestTurnPortType) {
@@ -825,7 +857,8 @@ TEST_F(TurnPortTest, TestReconstructedServerUrlForTls) {
}
TEST_F(TurnPortTest, TestReconstructedServerUrlForHostname) {
- CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPortHostnameProtoAddr);
+ CreateTurnPort(kTurnUsername, kTurnPassword,
+ kTurnPortInvalidHostnameProtoAddr);
// This test follows the pattern from TestTurnTcpOnAddressResolveFailure.
// As VSS doesn't provide DNS resolution, name resolve will fail,
// the error will be set and contain the url.
@@ -840,12 +873,7 @@ TEST_F(TurnPortTest, TestReconstructedServerUrlForHostname) {
TEST_F(TurnPortTest, TestTurnAllocate) {
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}
class TurnLoggingIdValidator : public StunMessageObserver {
@@ -876,24 +904,14 @@ TEST_F(TurnPortTest, TestTurnAllocateWithLoggingId) {
turn_port_->SetTurnLoggingId("KESO");
turn_server_.server()->SetStunMessageObserver(
std::make_unique<TurnLoggingIdValidator>("KESO"));
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}
TEST_F(TurnPortTest, TestTurnAllocateWithoutLoggingId) {
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
turn_server_.server()->SetStunMessageObserver(
std::make_unique<TurnLoggingIdValidator>(nullptr));
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}
// Test bad credentials.
@@ -912,12 +930,7 @@ TEST_F(TurnPortTest, TestTurnTcpAllocate) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 3);
}
// Test case for WebRTC issue 3927 where a proxy binds to the local host address
@@ -932,12 +945,7 @@ TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 3);
// Verify that the socket actually used localhost, otherwise this test isn't
// doing what it meant to.
@@ -1525,12 +1533,7 @@ TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
kTurnUdpIPv6ProtoAddr);
- turn_port_->PrepareAddress();
- EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
- ASSERT_EQ(1U, turn_port_->Candidates().size());
- EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
- turn_port_->Candidates()[0].address().ipaddr());
- EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}
// Tests that the local and remote candidate address families should match when
@@ -1861,4 +1864,139 @@ TEST_F(TurnPortTest, TestTurnDangerousServerAllowedWithFieldTrial) {
ASSERT_TRUE(turn_port_);
}
+class TurnPortWithMockDnsResolverTest : public TurnPortTest {
+ public:
+ TurnPortWithMockDnsResolverTest()
+ : TurnPortTest(), socket_factory_(ss_.get()) {}
+
+ rtc::PacketSocketFactory* socket_factory() override {
+ return &socket_factory_;
+ }
+
+ void SetDnsResolverExpectations(
+ rtc::MockDnsResolvingPacketSocketFactory::Expectations expectations) {
+ socket_factory_.SetExpectations(expectations);
+ }
+
+ private:
+ rtc::MockDnsResolvingPacketSocketFactory socket_factory_;
+};
+
+// Test an allocation from a TURN server specified by a hostname.
+TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolved) {
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPortValidHostnameProtoAddr);
+ SetDnsResolverExpectations(
+ [](webrtc::MockAsyncDnsResolver* resolver,
+ webrtc::MockAsyncDnsResolverResult* resolver_result) {
+ EXPECT_CALL(*resolver, Start(kTurnValidAddr, _))
+ .WillOnce(InvokeArgument<1>());
+ EXPECT_CALL(*resolver, result)
+ .WillRepeatedly(ReturnPointee(resolver_result));
+ EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
+ EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET, _))
+ .WillOnce(DoAll(SetArgPointee<1>(kTurnUdpIntAddr), Return(true)));
+ });
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
+}
+
+// Test an allocation from a TURN server specified by a hostname on an IPv6
+// network.
+TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolvedIPv6Network) {
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnPortValidHostnameProtoAddr);
+ SetDnsResolverExpectations(
+ [](webrtc::MockAsyncDnsResolver* resolver,
+ webrtc::MockAsyncDnsResolverResult* resolver_result) {
+ EXPECT_CALL(*resolver, Start(kTurnValidAddr, _))
+ .WillOnce(InvokeArgument<1>());
+ EXPECT_CALL(*resolver, result)
+ .WillRepeatedly(ReturnPointee(resolver_result));
+ EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
+ EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _))
+ .WillOnce(
+ DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true)));
+ });
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
+}
+
+// Test an allocation from a TURN server specified by a hostname on an IPv6
+// network, without network family-specific resolution.
+TEST_F(TurnPortWithMockDnsResolverTest,
+ TestHostnameResolvedIPv6NetworkFamilyFieldTrialDisabled) {
+ webrtc::test::ScopedKeyValueConfig override_field_trials(
+ field_trials_, "WebRTC-IPv6NetworkResolutionFixes/Disabled/");
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnPortValidHostnameProtoAddr);
+ SetDnsResolverExpectations(
+ [](webrtc::MockAsyncDnsResolver* resolver,
+ webrtc::MockAsyncDnsResolverResult* resolver_result) {
+ // Expect to call Resolver::Start without family arg.
+ EXPECT_CALL(*resolver, Start(kTurnValidAddr, _))
+ .WillOnce(InvokeArgument<1>());
+ EXPECT_CALL(*resolver, result)
+ .WillRepeatedly(ReturnPointee(resolver_result));
+ EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
+ EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _))
+ .WillOnce(
+ DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true)));
+ });
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
+}
+
+// Test an allocation from a TURN server specified by a hostname on an IPv6
+// network, without network family-specific resolution.
+TEST_F(TurnPortWithMockDnsResolverTest,
+ TestHostnameResolvedIPv6NetworkFamilyFieldTrialParamDisabled) {
+ webrtc::test::ScopedKeyValueConfig override_field_trials(
+ field_trials_,
+ "WebRTC-IPv6NetworkResolutionFixes/"
+ "Enabled,ResolveTurnHostnameForFamily:false/");
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnPortValidHostnameProtoAddr);
+ SetDnsResolverExpectations(
+ [](webrtc::MockAsyncDnsResolver* resolver,
+ webrtc::MockAsyncDnsResolverResult* resolver_result) {
+ // Expect to call Resolver::Start without family arg.
+ EXPECT_CALL(*resolver, Start(kTurnValidAddr, _))
+ .WillOnce(InvokeArgument<1>());
+ EXPECT_CALL(*resolver, result)
+ .WillRepeatedly(ReturnPointee(resolver_result));
+ EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
+ EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _))
+ .WillOnce(
+ DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true)));
+ });
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
+}
+
+// Test an allocation from a TURN server specified by a hostname on an IPv6
+// network, with network family-specific resolution.
+TEST_F(TurnPortWithMockDnsResolverTest,
+ TestHostnameResolvedIPv6NetworkFieldTrialEnabled) {
+ webrtc::test::ScopedKeyValueConfig override_field_trials(
+ field_trials_,
+ "WebRTC-IPv6NetworkResolutionFixes/"
+ "Enabled,ResolveTurnHostnameForFamily:true/");
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnPortValidHostnameProtoAddr);
+ SetDnsResolverExpectations(
+ [](webrtc::MockAsyncDnsResolver* resolver,
+ webrtc::MockAsyncDnsResolverResult* resolver_result) {
+ // Expect to call Resolver::Start _with_ family arg.
+ EXPECT_CALL(*resolver, Start(kTurnValidAddr, /*family=*/AF_INET6, _))
+ .WillOnce(InvokeArgument<2>());
+ EXPECT_CALL(*resolver, result)
+ .WillRepeatedly(ReturnPointee(resolver_result));
+ EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
+ EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _))
+ .WillOnce(
+ DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true)));
+ });
+ TestTurnAllocateSucceeds(kSimulatedRtt * 2);
+}
+
} // namespace cricket