From f8998cf8c46a078d5a6d4fd5d3a52f9ad9eb6199 Mon Sep 17 00:00:00 2001 From: Honghai Zhang Date: Mon, 14 Oct 2019 11:27:50 -0700 Subject: [PATCH] Add a turn port prune policy to keep the first ready turn port. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:11026 Change-Id: I6222e9613ee4ce2dcfbb717e2430ea833c0dc373 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/155542 Commit-Queue: Honghai Zhang Reviewed-by: Qingsi Wang Reviewed-by: Patrik Höglund Reviewed-by: Jonas Oreland Cr-Commit-Position: refs/heads/master@{#29470} --- api/BUILD.gn | 1 + api/peer_connection_interface.h | 13 +- api/transport/enums.h | 7 ++ p2p/base/p2p_transport_channel_unittest.cc | 14 ++- p2p/base/port_allocator.cc | 17 ++- p2p/base/port_allocator.h | 19 ++- p2p/base/port_allocator_unittest.cc | 24 ++-- p2p/base/regathering_controller_unittest.cc | 2 +- p2p/client/basic_port_allocator.cc | 45 +++++-- p2p/client/basic_port_allocator.h | 5 +- p2p/client/basic_port_allocator_unittest.cc | 119 ++++++++++++------ pc/peer_connection.cc | 17 ++- pc/peer_connection.h | 2 +- pc/peer_connection_interface_unittest.cc | 8 +- .../api/org/webrtc/PeerConnection.java | 15 +++ sdk/android/src/jni/pc/ice_candidate.cc | 19 +++ sdk/android/src/jni/pc/ice_candidate.h | 4 + sdk/android/src/jni/pc/peer_connection.cc | 4 + test/peer_scenario/scenario_connection.cc | 3 +- 19 files changed, 257 insertions(+), 81 deletions(-) diff --git a/api/BUILD.gn b/api/BUILD.gn index 58fd04eef2..4eed48c8e8 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -181,6 +181,7 @@ rtc_static_library("libjingle_peerconnection_api") { "task_queue", "transport:bitrate_settings", "transport:datagram_transport_interface", + "transport:enums", "transport:network_control", "transport/media:audio_interfaces", "transport/media:media_transport_interface", diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index f526c37f42..12c51626e9 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -99,6 +99,7 @@ #include "api/stats_types.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/bitrate_settings.h" +#include "api/transport/enums.h" #include "api/transport/media/media_transport_interface.h" #include "api/transport/network_control.h" #include "api/turn_customizer.h" @@ -394,7 +395,7 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { int max_ipv6_networks = cricket::kDefaultMaxIPv6Networks; // Exclude link-local network interfaces - // from considertaion for gathering ICE candidates. + // from consideration for gathering ICE candidates. bool disable_link_local_networks = false; // If set to true, use RTP data channels instead of SCTP. @@ -479,8 +480,18 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { // If set to true, only one preferred TURN allocation will be used per // network interface. UDP is preferred over TCP and IPv6 over IPv4. This // can be used to cut down on the number of candidate pairings. + // Deprecated. TODO(webrtc:11026) Remove this flag once the downstream + // dependency is removed. bool prune_turn_ports = false; + // The policy used to prune turn port. + PortPrunePolicy turn_port_prune_policy = NO_PRUNE; + + PortPrunePolicy GetTurnPortPrunePolicy() const { + return prune_turn_ports ? PRUNE_BASED_ON_PRIORITY + : turn_port_prune_policy; + } + // If set to true, this means the ICE transport should presume TURN-to-TURN // candidate pairs will succeed, even before a binding response is received. // This can be used to optimize the initial connection time, since the DTLS diff --git a/api/transport/enums.h b/api/transport/enums.h index b1d5770cb9..eb33e919a9 100644 --- a/api/transport/enums.h +++ b/api/transport/enums.h @@ -27,6 +27,13 @@ enum class IceTransportState { kClosed, }; +enum PortPrunePolicy { + NO_PRUNE, // Do not prune. + PRUNE_BASED_ON_PRIORITY, // Prune lower-priority ports on the same network. + KEEP_FIRST_READY // Keep the first ready port and prune the rest + // on the same network. +}; + } // namespace webrtc #endif // API_TRANSPORT_ENUMS_H_ diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index 5a060a85ef..8f7fd4aa8a 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -171,7 +171,7 @@ cricket::BasicPortAllocator* CreateBasicPortAllocator( cricket::BasicPortAllocator* allocator = new cricket::BasicPortAllocator(network_manager); allocator->Initialize(); - allocator->SetConfiguration(stun_servers, turn_servers, 0, false); + allocator->SetConfiguration(stun_servers, turn_servers, 0, webrtc::NO_PRUNE); return allocator; } } // namespace @@ -2036,9 +2036,11 @@ TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) { auto& allocator_2 = GetEndpoint(1)->allocator_; int pool_size = 1; allocator_1->SetConfiguration(allocator_1->stun_servers(), - allocator_1->turn_servers(), pool_size, false); + allocator_1->turn_servers(), pool_size, + webrtc::NO_PRUNE); allocator_2->SetConfiguration(allocator_2->stun_servers(), - allocator_2->turn_servers(), pool_size, false); + allocator_2->turn_servers(), pool_size, + webrtc::NO_PRUNE); const PortAllocatorSession* pooled_session_1 = allocator_1->GetPooledSession(); const PortAllocatorSession* pooled_session_2 = @@ -2079,9 +2081,11 @@ TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) { auto& allocator_2 = GetEndpoint(1)->allocator_; int pool_size = 1; allocator_1->SetConfiguration(allocator_1->stun_servers(), - allocator_1->turn_servers(), pool_size, false); + allocator_1->turn_servers(), pool_size, + webrtc::NO_PRUNE); allocator_2->SetConfiguration(allocator_2->stun_servers(), - allocator_2->turn_servers(), pool_size, false); + allocator_2->turn_servers(), pool_size, + webrtc::NO_PRUNE); const PortAllocatorSession* pooled_session_1 = allocator_1->GetPooledSession(); const PortAllocatorSession* pooled_session_2 = diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc index a9d7cb6493..b30416fdd3 100644 --- a/p2p/base/port_allocator.cc +++ b/p2p/base/port_allocator.cc @@ -116,6 +116,7 @@ void PortAllocator::set_restrict_ice_credentials_change(bool value) { restrict_ice_credentials_change_ = value; } +// Deprecated bool PortAllocator::SetConfiguration( const ServerAddresses& stun_servers, const std::vector& turn_servers, @@ -123,6 +124,20 @@ bool PortAllocator::SetConfiguration( bool prune_turn_ports, webrtc::TurnCustomizer* turn_customizer, const absl::optional& stun_candidate_keepalive_interval) { + webrtc::PortPrunePolicy turn_port_prune_policy = + prune_turn_ports ? webrtc::PRUNE_BASED_ON_PRIORITY : webrtc::NO_PRUNE; + return SetConfiguration(stun_servers, turn_servers, candidate_pool_size, + turn_port_prune_policy, turn_customizer, + stun_candidate_keepalive_interval); +} + +bool PortAllocator::SetConfiguration( + const ServerAddresses& stun_servers, + const std::vector& turn_servers, + int candidate_pool_size, + webrtc::PortPrunePolicy turn_port_prune_policy, + webrtc::TurnCustomizer* turn_customizer, + const absl::optional& stun_candidate_keepalive_interval) { CheckRunOnValidThreadIfInitialized(); // A positive candidate pool size would lead to the creation of a pooled // allocator session and starting getting ports, which we should only do on @@ -132,7 +147,7 @@ bool PortAllocator::SetConfiguration( (stun_servers != stun_servers_ || turn_servers != turn_servers_); stun_servers_ = stun_servers; turn_servers_ = turn_servers; - prune_turn_ports_ = prune_turn_ports; + turn_port_prune_policy_ = turn_port_prune_policy; if (candidate_pool_frozen_) { if (candidate_pool_size != candidate_pool_size_) { diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h index f29877c5b9..eb04cc2a1f 100644 --- a/p2p/base/port_allocator.h +++ b/p2p/base/port_allocator.h @@ -16,6 +16,7 @@ #include #include +#include "api/transport/enums.h" #include "p2p/base/port.h" #include "p2p/base/port_interface.h" #include "rtc_base/helpers.h" @@ -360,6 +361,7 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { // created or destroyed as necessary. // // Returns true if the configuration could successfully be changed. + // Deprecated bool SetConfiguration(const ServerAddresses& stun_servers, const std::vector& turn_servers, int candidate_pool_size, @@ -367,6 +369,13 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { webrtc::TurnCustomizer* turn_customizer = nullptr, const absl::optional& stun_candidate_keepalive_interval = absl::nullopt); + bool SetConfiguration(const ServerAddresses& stun_servers, + const std::vector& turn_servers, + int candidate_pool_size, + webrtc::PortPrunePolicy turn_port_prune_policy, + webrtc::TurnCustomizer* turn_customizer = nullptr, + const absl::optional& + stun_candidate_keepalive_interval = absl::nullopt); const ServerAddresses& stun_servers() const { CheckRunOnValidThreadIfInitialized(); @@ -555,9 +564,15 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { // TODO(qingsi): Remove this after Chromium migrates to the new method. void set_candidate_filter(uint32_t filter) { SetCandidateFilter(filter); } + // Deprecated (by the next method). bool prune_turn_ports() const { CheckRunOnValidThreadIfInitialized(); - return prune_turn_ports_; + return turn_port_prune_policy_ == webrtc::PRUNE_BASED_ON_PRIORITY; + } + + webrtc::PortPrunePolicy turn_port_prune_policy() const { + CheckRunOnValidThreadIfInitialized(); + return turn_port_prune_policy_; } // Gets/Sets the Origin value used for WebRTC STUN requests. @@ -634,7 +649,7 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { int candidate_pool_size_ = 0; // Last value passed into SetConfiguration. std::vector> pooled_sessions_; bool candidate_pool_frozen_ = false; - bool prune_turn_ports_ = false; + webrtc::PortPrunePolicy turn_port_prune_policy_ = webrtc::NO_PRUNE; // Customizer for TURN messages. // The instance is owned by application and will be shared among diff --git a/p2p/base/port_allocator_unittest.cc b/p2p/base/port_allocator_unittest.cc index 56061686b5..70946a3d81 100644 --- a/p2p/base/port_allocator_unittest.cc +++ b/p2p/base/port_allocator_unittest.cc @@ -37,13 +37,13 @@ class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { void SetConfigurationWithPoolSize(int candidate_pool_size) { EXPECT_TRUE(allocator_->SetConfiguration( cricket::ServerAddresses(), std::vector(), - candidate_pool_size, false)); + candidate_pool_size, webrtc::NO_PRUNE)); } void SetConfigurationWithPoolSizeExpectFailure(int candidate_pool_size) { EXPECT_FALSE(allocator_->SetConfiguration( cricket::ServerAddresses(), std::vector(), - candidate_pool_size, false)); + candidate_pool_size, webrtc::NO_PRUNE)); } std::unique_ptr CreateSession( @@ -114,16 +114,16 @@ TEST_F(PortAllocatorTest, CreateSession) { TEST_F(PortAllocatorTest, SetConfigurationUpdatesIceServers) { cricket::ServerAddresses stun_servers_1 = {stun_server_1}; std::vector turn_servers_1 = {turn_server_1}; - EXPECT_TRUE( - allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 0, false)); + EXPECT_TRUE(allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 0, + webrtc::NO_PRUNE)); EXPECT_EQ(stun_servers_1, allocator_->stun_servers()); EXPECT_EQ(turn_servers_1, allocator_->turn_servers()); // Update with a different set of servers. cricket::ServerAddresses stun_servers_2 = {stun_server_2}; std::vector turn_servers_2 = {turn_server_2}; - EXPECT_TRUE( - allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 0, false)); + EXPECT_TRUE(allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 0, + webrtc::NO_PRUNE)); EXPECT_EQ(stun_servers_2, allocator_->stun_servers()); EXPECT_EQ(turn_servers_2, allocator_->turn_servers()); } @@ -179,14 +179,16 @@ TEST_F(PortAllocatorTest, SetConfigurationRecreatesPooledSessionsWhenIceServersChange) { cricket::ServerAddresses stun_servers_1 = {stun_server_1}; std::vector turn_servers_1 = {turn_server_1}; - allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 1, false); + allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 1, + webrtc::NO_PRUNE); EXPECT_EQ(stun_servers_1, allocator_->stun_servers()); EXPECT_EQ(turn_servers_1, allocator_->turn_servers()); // Update with a different set of servers (and also change pool size). cricket::ServerAddresses stun_servers_2 = {stun_server_2}; std::vector turn_servers_2 = {turn_server_2}; - allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 2, false); + allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 2, + webrtc::NO_PRUNE); EXPECT_EQ(stun_servers_2, allocator_->stun_servers()); EXPECT_EQ(turn_servers_2, allocator_->turn_servers()); auto session_1 = TakePooledSession(); @@ -207,7 +209,8 @@ TEST_F(PortAllocatorTest, SetConfigurationDoesNotRecreatePooledSessionsAfterFreezeCandidatePool) { cricket::ServerAddresses stun_servers_1 = {stun_server_1}; std::vector turn_servers_1 = {turn_server_1}; - allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 1, false); + allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 1, + webrtc::NO_PRUNE); EXPECT_EQ(stun_servers_1, allocator_->stun_servers()); EXPECT_EQ(turn_servers_1, allocator_->turn_servers()); @@ -215,7 +218,8 @@ TEST_F(PortAllocatorTest, allocator_->FreezeCandidatePool(); cricket::ServerAddresses stun_servers_2 = {stun_server_2}; std::vector turn_servers_2 = {turn_server_2}; - allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 2, false); + allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 2, + webrtc::NO_PRUNE); EXPECT_EQ(stun_servers_2, allocator_->stun_servers()); EXPECT_EQ(turn_servers_2, allocator_->turn_servers()); auto session = TakePooledSession(); diff --git a/p2p/base/regathering_controller_unittest.cc b/p2p/base/regathering_controller_unittest.cc index d583ef8dad..cee4a67b0a 100644 --- a/p2p/base/regathering_controller_unittest.cc +++ b/p2p/base/regathering_controller_unittest.cc @@ -70,7 +70,7 @@ class RegatheringControllerTest : public ::testing::Test, std::vector turn_servers(1, turn_server); allocator_->set_flags(kOnlyLocalPorts); allocator_->SetConfiguration(stun_servers, turn_servers, 0 /* pool size */, - false /* prune turn ports */); + webrtc::NO_PRUNE); allocator_session_ = allocator_->CreateSession( "test", cricket::ICE_CANDIDATE_COMPONENT_RTP, kIceUfrag, kIcePwd); // The gathering will take place on the current thread and the following diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc index 3608fe1c21..b49e2f842b 100644 --- a/p2p/client/basic_port_allocator.cc +++ b/p2p/client/basic_port_allocator.cc @@ -161,7 +161,7 @@ BasicPortAllocator::BasicPortAllocator( RTC_DCHECK(network_manager_ != nullptr); RTC_DCHECK(socket_factory_ != nullptr); SetConfiguration(ServerAddresses(), std::vector(), 0, - false, customizer); + webrtc::NO_PRUNE, customizer); Construct(); } @@ -185,8 +185,8 @@ BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager, : network_manager_(network_manager), socket_factory_(socket_factory) { InitRelayPortFactory(nullptr); RTC_DCHECK(relay_port_factory_ != nullptr); - SetConfiguration(stun_servers, std::vector(), 0, false, - nullptr); + SetConfiguration(stun_servers, std::vector(), 0, + webrtc::NO_PRUNE, nullptr); Construct(); } @@ -242,7 +242,7 @@ void BasicPortAllocator::AddTurnServer(const RelayServerConfig& turn_server) { std::vector new_turn_servers = turn_servers(); new_turn_servers.push_back(turn_server); SetConfiguration(stun_servers(), new_turn_servers, candidate_pool_size(), - prune_turn_ports(), turn_customizer()); + turn_port_prune_policy(), turn_customizer()); } void BasicPortAllocator::InitRelayPortFactory( @@ -273,7 +273,7 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( allocation_started_(false), network_manager_started_(false), allocation_sequences_created_(false), - prune_turn_ports_(allocator->prune_turn_ports()) { + turn_port_prune_policy_(allocator->turn_port_prune_policy()) { allocator_->network_manager()->SignalNetworksChanged.connect( this, &BasicPortAllocatorSession::OnNetworksChanged); allocator_->network_manager()->StartUpdating(); @@ -378,8 +378,8 @@ void BasicPortAllocatorSession::StartGettingPorts() { network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START); - RTC_LOG(LS_INFO) << "Start getting ports with prune_turn_ports " - << (prune_turn_ports_ ? "enabled" : "disabled"); + RTC_LOG(LS_INFO) << "Start getting ports with turn_port_prune_policy " + << turn_port_prune_policy_; } void BasicPortAllocatorSession::StopGettingPorts() { @@ -967,9 +967,14 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port, if (CandidatePairable(c, port) && !data->has_pairable_candidate()) { data->set_has_pairable_candidate(true); - if (prune_turn_ports_ && port->Type() == RELAY_PORT_TYPE) { - pruned = PruneTurnPorts(port); + if (port->Type() == RELAY_PORT_TYPE) { + if (turn_port_prune_policy_ == webrtc::KEEP_FIRST_READY) { + pruned = PruneNewlyPairableTurnPort(data); + } else if (turn_port_prune_policy_ == webrtc::PRUNE_BASED_ON_PRIORITY) { + pruned = PruneTurnPorts(port); + } } + // If the current port is not pruned yet, SignalPortReady. if (!data->pruned()) { RTC_LOG(LS_INFO) << port->ToString() << ": Port ready."; @@ -1015,6 +1020,28 @@ Port* BasicPortAllocatorSession::GetBestTurnPortForNetwork( return best_turn_port; } +bool BasicPortAllocatorSession::PruneNewlyPairableTurnPort( + PortData* newly_pairable_port_data) { + RTC_DCHECK_RUN_ON(network_thread_); + RTC_DCHECK(newly_pairable_port_data->port()->Type() == RELAY_PORT_TYPE); + // If an existing turn port is ready on the same network, prune the newly + // pairable port. + const std::string& network_name = + newly_pairable_port_data->port()->Network()->name(); + + for (PortData& data : ports_) { + if (data.port()->Network()->name() == network_name && + data.port()->Type() == RELAY_PORT_TYPE && data.ready() && + &data != newly_pairable_port_data) { + RTC_LOG(LS_INFO) << "Port pruned: " + << newly_pairable_port_data->port()->ToString(); + newly_pairable_port_data->Prune(); + return true; + } + } + return false; +} + bool BasicPortAllocatorSession::PruneTurnPorts(Port* newly_pairable_turn_port) { RTC_DCHECK_RUN_ON(network_thread_); // Note: We determine the same network based only on their network names. So diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h index 29c514f34b..10188bafca 100644 --- a/p2p/client/basic_port_allocator.h +++ b/p2p/client/basic_port_allocator.h @@ -262,6 +262,7 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, Port* GetBestTurnPortForNetwork(const std::string& network_name) const; // Returns true if at least one TURN port is pruned. bool PruneTurnPorts(Port* newly_pairable_turn_port); + bool PruneNewlyPairableTurnPort(PortData* newly_pairable_turn_port); BasicPortAllocator* allocator_; rtc::Thread* network_thread_; @@ -274,8 +275,8 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, std::vector sequences_; std::vector ports_; uint32_t candidate_filter_ = CF_ALL; - // Whether to prune low-priority ports, taken from the port allocator. - bool prune_turn_ports_; + // Policy on how to prune turn ports, taken from the port allocator. + webrtc::PortPrunePolicy turn_port_prune_policy_; SessionState state_ = SessionState::CLEARED; friend class AllocationSequence; diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc index 9d97dc9849..31877ff8ab 100644 --- a/p2p/client/basic_port_allocator_unittest.cc +++ b/p2p/client/basic_port_allocator_unittest.cc @@ -571,7 +571,8 @@ class BasicPortAllocatorTest : public FakeClockBase, allocator_.reset(new BasicPortAllocator(&network_manager_)); allocator_->Initialize(); allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), 0, true); + allocator_->turn_servers(), 0, + webrtc::PRUNE_BASED_ON_PRIORITY); AddTurnServers(kTurnUdpIntIPv6Addr, rtc::SocketAddress()); AddTurnServers(kTurnUdpIntAddr, rtc::SocketAddress()); @@ -603,13 +604,15 @@ class BasicPortAllocatorTest : public FakeClockBase, rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0))); } - void TestUdpTurnPortPrunesTcpTurnPort() { + void TestTurnPortPrunesWithUdpAndTcpPorts( + webrtc::PortPrunePolicy prune_policy, + bool tcp_pruned) { turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP); AddInterface(kClientAddr); allocator_.reset(new BasicPortAllocator(&network_manager_)); allocator_->Initialize(); allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), 0, true); + allocator_->turn_servers(), 0, prune_policy); AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr); allocator_->set_step_delay(kMinimumStepDelay); allocator_->set_flags(allocator().flags() | @@ -627,8 +630,11 @@ class BasicPortAllocatorTest : public FakeClockBase, // |ready_ports|, so we only need to verify the content in one of them. EXPECT_EQ(2U, ports_.size()); EXPECT_EQ(1, CountPorts(ports_, "local", PROTO_UDP, kClientAddr)); - EXPECT_EQ(1, CountPorts(ports_, "relay", PROTO_UDP, kClientAddr)); - EXPECT_EQ(0, CountPorts(ports_, "relay", PROTO_TCP, kClientAddr)); + int num_udp_ports = tcp_pruned ? 1 : 0; + EXPECT_EQ(num_udp_ports, + CountPorts(ports_, "relay", PROTO_UDP, kClientAddr)); + EXPECT_EQ(1 - num_udp_ports, + CountPorts(ports_, "relay", PROTO_TCP, kClientAddr)); // Now that we remove candidates when a TURN port is pruned, |candidates_| // should only contains two candidates regardless whether the TCP TURN port @@ -640,6 +646,8 @@ class BasicPortAllocatorTest : public FakeClockBase, session_->ReadyCandidates(); EXPECT_EQ(2U, ready_candidates.size()); EXPECT_TRUE(HasCandidate(ready_candidates, "local", "udp", kClientAddr)); + + // The external candidate is always udp. EXPECT_TRUE(HasCandidate(ready_candidates, "relay", "udp", rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0))); } @@ -656,7 +664,8 @@ class BasicPortAllocatorTest : public FakeClockBase, allocator_.reset(new BasicPortAllocator(&network_manager_)); allocator_->Initialize(); allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), 0, true); + allocator_->turn_servers(), 0, + webrtc::PRUNE_BASED_ON_PRIORITY); // Have both UDP/TCP and IPv4/IPv6 TURN ports. AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr); AddTurnServers(kTurnUdpIntIPv6Addr, kTurnTcpIntIPv6Addr); @@ -1649,30 +1658,59 @@ TEST_F(BasicPortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) { rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0))); } -// Test that if prune_turn_ports is set, TCP TURN port will not be used -// if UDP TurnPort is used, given that TCP TURN port becomes ready first. +// Test that if the turn port prune policy is PRUNE_BASED_ON_PRIORITY, TCP TURN +// port will not be used if UDP TurnPort is used, given that TCP TURN port +// becomes ready first. TEST_F(BasicPortAllocatorTest, TestUdpTurnPortPrunesTcpTurnPortWithTcpPortReadyFirst) { // UDP has longer delay than TCP so that TCP TURN port becomes ready first. virtual_socket_server()->SetDelayOnAddress(kTurnUdpIntAddr, 200); virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 100); - TestUdpTurnPortPrunesTcpTurnPort(); + TestTurnPortPrunesWithUdpAndTcpPorts(webrtc::PRUNE_BASED_ON_PRIORITY, + true /* tcp_pruned */); } -// Test that if prune_turn_ports is set, TCP TURN port will not be used -// if UDP TurnPort is used, given that UDP TURN port becomes ready first. +// Test that if turn port prune policy is PRUNE_BASED_ON_PRIORITY, TCP TURN port +// will not be used if UDP TurnPort is used, given that UDP TURN port becomes +// ready first. TEST_F(BasicPortAllocatorTest, TestUdpTurnPortPrunesTcpTurnPortsWithUdpPortReadyFirst) { // UDP has shorter delay than TCP so that UDP TURN port becomes ready first. virtual_socket_server()->SetDelayOnAddress(kTurnUdpIntAddr, 100); virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 200); - TestUdpTurnPortPrunesTcpTurnPort(); + TestTurnPortPrunesWithUdpAndTcpPorts(webrtc::PRUNE_BASED_ON_PRIORITY, + true /* tcp_pruned */); } -// Tests that if prune_turn_ports is set, IPv4 TurnPort will not be used -// if IPv6 TurnPort is used, given that IPv4 TURN port becomes ready first. +// Test that if turn_port_prune policy is KEEP_FIRST_READY, the first ready port +// will be kept regardless of the priority. +TEST_F(BasicPortAllocatorTest, + TestUdpTurnPortPrunesTcpTurnPortIfUdpReadyFirst) { + // UDP has shorter delay than TCP so that UDP TURN port becomes ready first. + virtual_socket_server()->SetDelayOnAddress(kTurnUdpIntAddr, 100); + virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 200); + + TestTurnPortPrunesWithUdpAndTcpPorts(webrtc::KEEP_FIRST_READY, + true /* tcp_pruned */); +} + +// Test that if turn_port_prune policy is KEEP_FIRST_READY, the first ready port +// will be kept regardless of the priority. +TEST_F(BasicPortAllocatorTest, + TestTcpTurnPortPrunesUdpTurnPortIfTcpReadyFirst) { + // UDP has longer delay than TCP so that TCP TURN port becomes ready first. + virtual_socket_server()->SetDelayOnAddress(kTurnUdpIntAddr, 200); + virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 100); + + TestTurnPortPrunesWithUdpAndTcpPorts(webrtc::KEEP_FIRST_READY, + false /* tcp_pruned */); +} + +// Tests that if turn port prune policy is PRUNE_BASED_ON_PRIORITY, IPv4 +// TurnPort will not be used if IPv6 TurnPort is used, given that IPv4 TURN port +// becomes ready first. TEST_F(BasicPortAllocatorTest, TestIPv6TurnPortPrunesIPv4TurnPortWithIPv4PortReadyFirst) { // IPv6 has longer delay than IPv4, so that IPv4 TURN port becomes ready @@ -1683,8 +1721,9 @@ TEST_F(BasicPortAllocatorTest, TestIPv6TurnPortPrunesIPv4TurnPort(); } -// Tests that if prune_turn_ports is set, IPv4 TurnPort will not be used -// if IPv6 TurnPort is used, given that IPv6 TURN port becomes ready first. +// Tests that if turn port prune policy is PRUNE_BASED_ON_PRIORITY, IPv4 +// TurnPort will not be used if IPv6 TurnPort is used, given that IPv6 TURN port +// becomes ready first. TEST_F(BasicPortAllocatorTest, TestIPv6TurnPortPrunesIPv4TurnPortWithIPv6PortReadyFirst) { // IPv6 has longer delay than IPv4, so that IPv6 TURN port becomes ready @@ -1695,16 +1734,16 @@ TEST_F(BasicPortAllocatorTest, TestIPv6TurnPortPrunesIPv4TurnPort(); } -// Tests that if prune_turn_ports is set, each network interface -// will has its own set of TurnPorts based on their priorities, in the default -// case where no transit delay is set. +// Tests that if turn port prune policy is PRUNE_BASED_ON_PRIORITY, each network +// interface will has its own set of TurnPorts based on their priorities, in the +// default case where no transit delay is set. TEST_F(BasicPortAllocatorTest, TestEachInterfaceHasItsOwnTurnPortsNoDelay) { TestEachInterfaceHasItsOwnTurnPorts(); } -// Tests that if prune_turn_ports is set, each network interface -// will has its own set of TurnPorts based on their priorities, given that -// IPv4/TCP TURN port becomes ready first. +// Tests that if turn port prune policy is PRUNE_BASED_ON_PRIORITY, each network +// interface will has its own set of TurnPorts based on their priorities, given +// that IPv4/TCP TURN port becomes ready first. TEST_F(BasicPortAllocatorTest, TestEachInterfaceHasItsOwnTurnPortsWithTcpIPv4ReadyFirst) { // IPv6/UDP have longer delay than IPv4/TCP, so that IPv4/TCP TURN port @@ -2038,7 +2077,8 @@ TEST_F(BasicPortAllocatorTest, TestTransportInformationUpdated) { AddInterface(kClientAddr); int pool_size = 1; allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false); + allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE); const PortAllocatorSession* peeked_session = allocator_->GetPooledSession(); ASSERT_NE(nullptr, peeked_session); EXPECT_EQ_SIMULATED_WAIT(true, peeked_session->CandidatesAllocationDone(), @@ -2074,7 +2114,8 @@ TEST_F(BasicPortAllocatorTest, TestSetCandidateFilterAfterCandidatesGathered) { AddInterface(kClientAddr); int pool_size = 1; allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false); + allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE); const PortAllocatorSession* peeked_session = allocator_->GetPooledSession(); ASSERT_NE(nullptr, peeked_session); EXPECT_EQ_SIMULATED_WAIT(true, peeked_session->CandidatesAllocationDone(), @@ -2248,9 +2289,9 @@ TEST_F(BasicPortAllocatorTest, SetStunKeepaliveIntervalForPorts) { const int pool_size = 1; const int expected_stun_keepalive_interval = 123; AddInterface(kClientAddr); - allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false, - nullptr, expected_stun_keepalive_interval); + allocator_->SetConfiguration( + allocator_->stun_servers(), allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE, nullptr, expected_stun_keepalive_interval); auto* pooled_session = allocator_->GetPooledSession(); ASSERT_NE(nullptr, pooled_session); EXPECT_EQ_SIMULATED_WAIT(true, pooled_session->CandidatesAllocationDone(), @@ -2263,17 +2304,17 @@ TEST_F(BasicPortAllocatorTest, ChangeStunKeepaliveIntervalForPortsAfterInitialConfig) { const int pool_size = 1; AddInterface(kClientAddr); - allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false, - nullptr, 123 /* stun keepalive interval */); + allocator_->SetConfiguration( + allocator_->stun_servers(), allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE, nullptr, 123 /* stun keepalive interval */); auto* pooled_session = allocator_->GetPooledSession(); ASSERT_NE(nullptr, pooled_session); EXPECT_EQ_SIMULATED_WAIT(true, pooled_session->CandidatesAllocationDone(), kDefaultAllocationTimeout, fake_clock); const int expected_stun_keepalive_interval = 321; - allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false, - nullptr, expected_stun_keepalive_interval); + allocator_->SetConfiguration( + allocator_->stun_servers(), allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE, nullptr, expected_stun_keepalive_interval); CheckStunKeepaliveIntervalOfAllReadyPorts(pooled_session, expected_stun_keepalive_interval); } @@ -2285,9 +2326,9 @@ TEST_F(BasicPortAllocatorTest, AddInterface(kClientAddr); allocator_->set_flags(allocator().flags() | PORTALLOCATOR_ENABLE_SHARED_SOCKET); - allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false, - nullptr, expected_stun_keepalive_interval); + allocator_->SetConfiguration( + allocator_->stun_servers(), allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE, nullptr, expected_stun_keepalive_interval); ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP)); session_->StartGettingPorts(); EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, @@ -2303,9 +2344,9 @@ TEST_F(BasicPortAllocatorTest, AddInterface(kClientAddr); allocator_->set_flags(allocator().flags() & ~(PORTALLOCATOR_ENABLE_SHARED_SOCKET)); - allocator_->SetConfiguration(allocator_->stun_servers(), - allocator_->turn_servers(), pool_size, false, - nullptr, expected_stun_keepalive_interval); + allocator_->SetConfiguration( + allocator_->stun_servers(), allocator_->turn_servers(), pool_size, + webrtc::NO_PRUNE, nullptr, expected_stun_keepalive_interval); ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP)); session_->StartGettingPorts(); EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index c0e1831916..f019ec90fe 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -758,6 +758,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( bool prioritize_most_likely_ice_candidate_pairs; struct cricket::MediaConfig media_config; bool prune_turn_ports; + PortPrunePolicy turn_port_prune_policy; bool presume_writable_when_fully_relayed; bool enable_ice_renomination; bool redetermine_role_on_ice_restart; @@ -817,6 +818,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( enable_dtls_srtp == o.enable_dtls_srtp && ice_candidate_pool_size == o.ice_candidate_pool_size && prune_turn_ports == o.prune_turn_ports && + turn_port_prune_policy == o.turn_port_prune_policy && presume_writable_when_fully_relayed == o.presume_writable_when_fully_relayed && enable_ice_renomination == o.enable_ice_renomination && @@ -3675,6 +3677,7 @@ RTCError PeerConnection::SetConfiguration( modified_config.ice_candidate_pool_size = configuration.ice_candidate_pool_size; modified_config.prune_turn_ports = configuration.prune_turn_ports; + modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy; modified_config.surface_ice_candidates_on_ice_transport_type_changed = configuration.surface_ice_candidates_on_ice_transport_type_changed; modified_config.ice_check_min_interval = configuration.ice_check_min_interval; @@ -3746,7 +3749,7 @@ RTCError PeerConnection::SetConfiguration( rtc::Bind(&PeerConnection::ReconfigurePortAllocator_n, this, stun_servers, turn_servers, modified_config.type, modified_config.ice_candidate_pool_size, - modified_config.prune_turn_ports, + modified_config.GetTurnPortPrunePolicy(), modified_config.turn_customizer, modified_config.stun_candidate_keepalive_interval, static_cast(local_description())))) { @@ -3759,7 +3762,8 @@ RTCError PeerConnection::SetConfiguration( // triggers an ICE restart which will pick up the changes. if (modified_config.servers != configuration_.servers || modified_config.type != configuration_.type || - modified_config.prune_turn_ports != configuration_.prune_turn_ports) { + modified_config.GetTurnPortPrunePolicy() != + configuration_.GetTurnPortPrunePolicy()) { transport_controller_->SetNeedsIceRestartFlag(); } @@ -5736,8 +5740,8 @@ PeerConnection::InitializePortAllocator_n( // properties set above. port_allocator_->SetConfiguration( stun_servers, std::move(turn_servers_copy), - configuration.ice_candidate_pool_size, configuration.prune_turn_ports, - configuration.turn_customizer, + configuration.ice_candidate_pool_size, + configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer, configuration.stun_candidate_keepalive_interval); InitializePortAllocatorResult res; @@ -5750,7 +5754,7 @@ bool PeerConnection::ReconfigurePortAllocator_n( const std::vector& turn_servers, IceTransportsType type, int candidate_pool_size, - bool prune_turn_ports, + PortPrunePolicy turn_port_prune_policy, webrtc::TurnCustomizer* turn_customizer, absl::optional stun_candidate_keepalive_interval, bool have_local_description) { @@ -5771,7 +5775,8 @@ bool PeerConnection::ReconfigurePortAllocator_n( // candidate filter set above. return port_allocator_->SetConfiguration( stun_servers, std::move(turn_servers_copy), candidate_pool_size, - prune_turn_ports, turn_customizer, stun_candidate_keepalive_interval); + turn_port_prune_policy, turn_customizer, + stun_candidate_keepalive_interval); } cricket::ChannelManager* PeerConnection::channel_manager() const { diff --git a/pc/peer_connection.h b/pc/peer_connection.h index 393a1ddd91..428c2e8f5e 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -907,7 +907,7 @@ class PeerConnection : public PeerConnectionInternal, const std::vector& turn_servers, IceTransportsType type, int candidate_pool_size, - bool prune_turn_ports, + PortPrunePolicy turn_port_prune_policy, webrtc::TurnCustomizer* turn_customizer, absl::optional stun_candidate_keepalive_interval, bool have_local_description); diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 2d0687c10d..5a01430b95 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -1395,7 +1395,8 @@ TEST_P(PeerConnectionInterfaceTest, EXPECT_TRUE(raw_port_allocator->flags() & cricket::PORTALLOCATOR_DISABLE_TCP); EXPECT_TRUE(raw_port_allocator->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS); - EXPECT_TRUE(raw_port_allocator->prune_turn_ports()); + EXPECT_EQ(webrtc::PRUNE_BASED_ON_PRIORITY, + raw_port_allocator->turn_port_prune_policy()); } // Check that GetConfiguration returns the configuration the PeerConnection was @@ -2448,11 +2449,12 @@ TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) { config.prune_turn_ports = false; CreatePeerConnection(config); config = pc_->GetConfiguration(); - EXPECT_FALSE(port_allocator_->prune_turn_ports()); + EXPECT_EQ(webrtc::NO_PRUNE, port_allocator_->turn_port_prune_policy()); config.prune_turn_ports = true; EXPECT_TRUE(pc_->SetConfiguration(config).ok()); - EXPECT_TRUE(port_allocator_->prune_turn_ports()); + EXPECT_EQ(webrtc::PRUNE_BASED_ON_PRIORITY, + port_allocator_->turn_port_prune_policy()); } // Test that the ice check interval can be changed. This does not verify that diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java index 7317573f03..b981520746 100644 --- a/sdk/android/api/org/webrtc/PeerConnection.java +++ b/sdk/android/api/org/webrtc/PeerConnection.java @@ -407,6 +407,13 @@ public class PeerConnection { /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */ public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY } + /** Java version of webrtc::PortPrunePolicy */ + public enum PortPrunePolicy { + NO_PRUNE, // Do not prune turn port. + PRUNE_BASED_ON_PRIORITY, // Prune turn port based the priority on the same network + KEEP_FIRST_READY // Keep the first ready port and prune the rest on the same network. + } + /** Java version of rtc::IntervalRange */ public static class IntervalRange { private final int min; @@ -472,7 +479,9 @@ public class PeerConnection { public KeyType keyType; public ContinualGatheringPolicy continualGatheringPolicy; public int iceCandidatePoolSize; + @Deprecated // by the turnPortPrunePolicy. See bugs.webrtc.org/11026 public boolean pruneTurnPorts; + public PortPrunePolicy turnPortPrunePolicy; public boolean presumeWritableWhenFullyRelayed; public boolean surfaceIceCandidatesOnIceTransportTypeChanged; // The following fields define intervals in milliseconds at which ICE @@ -583,6 +592,7 @@ public class PeerConnection { continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE; iceCandidatePoolSize = 0; pruneTurnPorts = false; + turnPortPrunePolicy = PortPrunePolicy.NO_PRUNE; presumeWritableWhenFullyRelayed = false; surfaceIceCandidatesOnIceTransportTypeChanged = false; iceCheckIntervalStrongConnectivityMs = null; @@ -626,6 +636,11 @@ public class PeerConnection { return bundlePolicy; } + @CalledByNative("RTCConfiguration") + PortPrunePolicy getTurnPortPrunePolicy() { + return turnPortPrunePolicy; + } + @Nullable @CalledByNative("RTCConfiguration") RtcCertificatePem getCertificate() { diff --git a/sdk/android/src/jni/pc/ice_candidate.cc b/sdk/android/src/jni/pc/ice_candidate.cc index 247e8fa34c..af92ff8e89 100644 --- a/sdk/android/src/jni/pc/ice_candidate.cc +++ b/sdk/android/src/jni/pc/ice_candidate.cc @@ -194,6 +194,25 @@ JavaToNativeContinualGatheringPolicy( return PeerConnectionInterface::GATHER_ONCE; } +webrtc::PortPrunePolicy JavaToNativePortPrunePolicy( + JNIEnv* jni, + const JavaRef& j_port_prune_policy) { + std::string enum_name = GetJavaEnumName(jni, j_port_prune_policy); + if (enum_name == "NO_PRUNE") { + return webrtc::NO_PRUNE; + } + if (enum_name == "PRUNE_BASED_ON_PRIORITY") { + return webrtc::PRUNE_BASED_ON_PRIORITY; + } + if (enum_name == "KEEP_FIRST_READY") { + return webrtc::KEEP_FIRST_READY; + } + + RTC_CHECK(false) << " Unexpected PortPrunePolicy enum name " << enum_name; + + return webrtc::NO_PRUNE; +} + PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy( JNIEnv* jni, const JavaRef& j_ice_server_tls_cert_policy) { diff --git a/sdk/android/src/jni/pc/ice_candidate.h b/sdk/android/src/jni/pc/ice_candidate.h index 0feeeb49f0..4bdeea61c6 100644 --- a/sdk/android/src/jni/pc/ice_candidate.h +++ b/sdk/android/src/jni/pc/ice_candidate.h @@ -71,6 +71,10 @@ JavaToNativeContinualGatheringPolicy( JNIEnv* jni, const JavaRef& j_gathering_policy); +webrtc::PortPrunePolicy JavaToNativePortPrunePolicy( + JNIEnv* jni, + const JavaRef& j_port_prune_policy); + PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy( JNIEnv* jni, const JavaRef& j_ice_server_tls_cert_policy); diff --git a/sdk/android/src/jni/pc/peer_connection.cc b/sdk/android/src/jni/pc/peer_connection.cc index 20804deb08..f40a7bff3a 100644 --- a/sdk/android/src/jni/pc/peer_connection.cc +++ b/sdk/android/src/jni/pc/peer_connection.cc @@ -158,6 +158,8 @@ void JavaToNativeRTCConfiguration( Java_RTCConfiguration_getIceServers(jni, j_rtc_config); ScopedJavaLocalRef j_continual_gathering_policy = Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config); + ScopedJavaLocalRef j_turn_port_prune_policy = + Java_RTCConfiguration_getTurnPortPrunePolicy(jni, j_rtc_config); ScopedJavaLocalRef j_turn_customizer = Java_RTCConfiguration_getTurnCustomizer(jni, j_rtc_config); ScopedJavaLocalRef j_network_preference = @@ -199,6 +201,8 @@ void JavaToNativeRTCConfiguration( Java_RTCConfiguration_getIceCandidatePoolSize(jni, j_rtc_config); rtc_config->prune_turn_ports = Java_RTCConfiguration_getPruneTurnPorts(jni, j_rtc_config); + rtc_config->turn_port_prune_policy = + JavaToNativePortPrunePolicy(jni, j_turn_port_prune_policy); rtc_config->presume_writable_when_fully_relayed = Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni, j_rtc_config); diff --git a/test/peer_scenario/scenario_connection.cc b/test/peer_scenario/scenario_connection.cc index 2c0ed36323..9f0d3bff42 100644 --- a/test/peer_scenario/scenario_connection.cc +++ b/test/peer_scenario/scenario_connection.cc @@ -109,7 +109,8 @@ ScenarioIceConnectionImpl::ScenarioIceConnectionImpl( port_allocator_->set_flags(port_allocator_->flags() | flags); port_allocator_->Initialize(); RTC_CHECK(port_allocator_->SetConfiguration(/*stun_servers*/ {}, - /*turn_servers*/ {}, 0, false)); + /*turn_servers*/ {}, 0, + webrtc::NO_PRUNE)); jsep_controller_->SetLocalCertificate(certificate_); }); }