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}
This commit is contained in:
Sameer Vijaykar 2022-12-02 17:07:07 +01:00 committed by WebRTC LUCI CQ
parent a422e93d7b
commit def85594ea
5 changed files with 274 additions and 83 deletions

View File

@ -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",

View File

@ -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_

View File

@ -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.

View File

@ -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,

View File

@ -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