1 /*
2 * Copyright 2009 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "p2p/base/p2p_transport_channel.h"
12
13 #include <list>
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <utility>
18
19 #include "absl/algorithm/container.h"
20 #include "absl/strings/string_view.h"
21 #include "api/test/mock_async_dns_resolver.h"
22 #include "p2p/base/active_ice_controller_factory_interface.h"
23 #include "p2p/base/active_ice_controller_interface.h"
24 #include "p2p/base/basic_ice_controller.h"
25 #include "p2p/base/connection.h"
26 #include "p2p/base/fake_port_allocator.h"
27 #include "p2p/base/ice_transport_internal.h"
28 #include "p2p/base/mock_active_ice_controller.h"
29 #include "p2p/base/mock_async_resolver.h"
30 #include "p2p/base/mock_ice_controller.h"
31 #include "p2p/base/packet_transport_internal.h"
32 #include "p2p/base/test_stun_server.h"
33 #include "p2p/base/test_turn_server.h"
34 #include "p2p/client/basic_port_allocator.h"
35 #include "rtc_base/checks.h"
36 #include "rtc_base/dscp.h"
37 #include "rtc_base/fake_clock.h"
38 #include "rtc_base/fake_mdns_responder.h"
39 #include "rtc_base/fake_network.h"
40 #include "rtc_base/firewall_socket_server.h"
41 #include "rtc_base/gunit.h"
42 #include "rtc_base/helpers.h"
43 #include "rtc_base/internal/default_socket_server.h"
44 #include "rtc_base/logging.h"
45 #include "rtc_base/mdns_responder_interface.h"
46 #include "rtc_base/nat_server.h"
47 #include "rtc_base/nat_socket_factory.h"
48 #include "rtc_base/proxy_server.h"
49 #include "rtc_base/socket_address.h"
50 #include "rtc_base/ssl_adapter.h"
51 #include "rtc_base/strings/string_builder.h"
52 #include "rtc_base/thread.h"
53 #include "rtc_base/virtual_socket_server.h"
54 #include "system_wrappers/include/metrics.h"
55 #include "test/scoped_key_value_config.h"
56
57 namespace {
58
59 using rtc::SocketAddress;
60 using ::testing::_;
61 using ::testing::Assign;
62 using ::testing::Combine;
63 using ::testing::Contains;
64 using ::testing::DoAll;
65 using ::testing::InSequence;
66 using ::testing::InvokeArgument;
67 using ::testing::InvokeWithoutArgs;
68 using ::testing::Return;
69 using ::testing::ReturnRef;
70 using ::testing::SaveArg;
71 using ::testing::SetArgPointee;
72 using ::testing::SizeIs;
73 using ::testing::TestWithParam;
74 using ::testing::Values;
75 using ::testing::WithParamInterface;
76 using ::webrtc::PendingTaskSafetyFlag;
77 using ::webrtc::SafeTask;
78
79 // Default timeout for tests in this file.
80 // Should be large enough for slow buildbots to run the tests reliably.
81 static const int kDefaultTimeout = 10000;
82 static const int kMediumTimeout = 3000;
83 static const int kShortTimeout = 1000;
84
85 static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
86 cricket::PORTALLOCATOR_DISABLE_RELAY |
87 cricket::PORTALLOCATOR_DISABLE_TCP;
88 static const int LOW_RTT = 20;
89 // Addresses on the public internet.
90 static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
91 SocketAddress("22.22.22.22", 0)};
92 // IPv6 Addresses on the public internet.
93 static const SocketAddress kIPv6PublicAddrs[2] = {
94 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
95 SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
96 // For configuring multihomed clients.
97 static const SocketAddress kAlternateAddrs[2] = {
98 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
99 static const SocketAddress kIPv6AlternateAddrs[2] = {
100 SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
101 SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
102 // Addresses for HTTP proxy servers.
103 static const SocketAddress kHttpsProxyAddrs[2] = {
104 SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443)};
105 // Addresses for SOCKS proxy servers.
106 static const SocketAddress kSocksProxyAddrs[2] = {
107 SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080)};
108 // Internal addresses for NAT boxes.
109 static const SocketAddress kNatAddrs[2] = {SocketAddress("192.168.1.1", 0),
110 SocketAddress("192.168.2.1", 0)};
111 // Private addresses inside the NAT private networks.
112 static const SocketAddress kPrivateAddrs[2] = {
113 SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0)};
114 // For cascaded NATs, the internal addresses of the inner NAT boxes.
115 static const SocketAddress kCascadedNatAddrs[2] = {
116 SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0)};
117 // For cascaded NATs, private addresses inside the inner private networks.
118 static const SocketAddress kCascadedPrivateAddrs[2] = {
119 SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0)};
120 // The address of the public STUN server.
121 static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
122 // The addresses for the public turn server.
123 static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
124 cricket::STUN_SERVER_PORT);
125 static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
126 cricket::STUN_SERVER_PORT + 1);
127 static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
128 static const cricket::RelayCredentials kRelayCredentials("test", "test");
129
130 // Based on ICE_UFRAG_LENGTH
131 const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
132 // Based on ICE_PWD_LENGTH
133 const char* kIcePwd[4] = {
134 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
135 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
136 const cricket::IceParameters kIceParams[4] = {
137 {kIceUfrag[0], kIcePwd[0], false},
138 {kIceUfrag[1], kIcePwd[1], false},
139 {kIceUfrag[2], kIcePwd[2], false},
140 {kIceUfrag[3], kIcePwd[3], false}};
141
142 const uint64_t kLowTiebreaker = 11111;
143 const uint64_t kHighTiebreaker = 22222;
144 const uint64_t kTiebreakerDefault = 44444;
145
CreateIceConfig(int receiving_timeout,cricket::ContinualGatheringPolicy continual_gathering_policy,absl::optional<int> backup_ping_interval=absl::nullopt)146 cricket::IceConfig CreateIceConfig(
147 int receiving_timeout,
148 cricket::ContinualGatheringPolicy continual_gathering_policy,
149 absl::optional<int> backup_ping_interval = absl::nullopt) {
150 cricket::IceConfig config;
151 config.receiving_timeout = receiving_timeout;
152 config.continual_gathering_policy = continual_gathering_policy;
153 config.backup_connection_ping_interval = backup_ping_interval;
154 return config;
155 }
156
CreateUdpCandidate(absl::string_view type,absl::string_view ip,int port,int priority,absl::string_view ufrag="")157 cricket::Candidate CreateUdpCandidate(absl::string_view type,
158 absl::string_view ip,
159 int port,
160 int priority,
161 absl::string_view ufrag = "") {
162 cricket::Candidate c;
163 c.set_address(rtc::SocketAddress(ip, port));
164 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
165 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
166 c.set_priority(priority);
167 c.set_username(ufrag);
168 c.set_type(type);
169 return c;
170 }
171
CreateBasicPortAllocator(rtc::NetworkManager * network_manager,rtc::SocketServer * socket_server,const cricket::ServerAddresses & stun_servers,const rtc::SocketAddress & turn_server_udp,const rtc::SocketAddress & turn_server_tcp)172 cricket::BasicPortAllocator* CreateBasicPortAllocator(
173 rtc::NetworkManager* network_manager,
174 rtc::SocketServer* socket_server,
175 const cricket::ServerAddresses& stun_servers,
176 const rtc::SocketAddress& turn_server_udp,
177 const rtc::SocketAddress& turn_server_tcp) {
178 cricket::RelayServerConfig turn_server;
179 turn_server.credentials = kRelayCredentials;
180 if (!turn_server_udp.IsNil()) {
181 turn_server.ports.push_back(
182 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
183 }
184 if (!turn_server_tcp.IsNil()) {
185 turn_server.ports.push_back(
186 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
187 }
188 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
189
190 std::unique_ptr<cricket::BasicPortAllocator> allocator =
191 std::make_unique<cricket::BasicPortAllocator>(
192 network_manager,
193 std::make_unique<rtc::BasicPacketSocketFactory>(socket_server));
194 allocator->Initialize();
195 allocator->SetConfiguration(stun_servers, turn_servers, 0, webrtc::NO_PRUNE);
196 return allocator.release();
197 }
198
199 // An one-shot resolver factory with default return arguments.
200 // Resolution is immediate, always succeeds, and returns nonsense.
201 class ResolverFactoryFixture : public webrtc::MockAsyncDnsResolverFactory {
202 public:
ResolverFactoryFixture()203 ResolverFactoryFixture() {
204 mock_async_dns_resolver_ = std::make_unique<webrtc::MockAsyncDnsResolver>();
205 EXPECT_CALL(*mock_async_dns_resolver_, Start(_, _))
206 .WillRepeatedly(InvokeArgument<1>());
207 EXPECT_CALL(*mock_async_dns_resolver_, result())
208 .WillOnce(ReturnRef(mock_async_dns_resolver_result_));
209
210 // A default action for GetResolvedAddress. Will be overruled
211 // by SetAddressToReturn.
212 EXPECT_CALL(mock_async_dns_resolver_result_, GetResolvedAddress(_, _))
213 .WillRepeatedly(Return(true));
214
215 EXPECT_CALL(mock_async_dns_resolver_result_, GetError())
216 .WillOnce(Return(0));
217 EXPECT_CALL(*this, Create()).WillOnce([this]() {
218 return std::move(mock_async_dns_resolver_);
219 });
220 }
221
SetAddressToReturn(rtc::SocketAddress address_to_return)222 void SetAddressToReturn(rtc::SocketAddress address_to_return) {
223 EXPECT_CALL(mock_async_dns_resolver_result_, GetResolvedAddress(_, _))
224 .WillOnce(DoAll(SetArgPointee<1>(address_to_return), Return(true)));
225 }
DelayResolution()226 void DelayResolution() {
227 // This function must be called before Create().
228 ASSERT_TRUE(!!mock_async_dns_resolver_);
229 EXPECT_CALL(*mock_async_dns_resolver_, Start(_, _))
230 .WillOnce(SaveArg<1>(&saved_callback_));
231 }
FireDelayedResolution()232 void FireDelayedResolution() {
233 // This function must be called after Create().
234 ASSERT_TRUE(saved_callback_);
235 saved_callback_();
236 }
237
238 private:
239 std::unique_ptr<webrtc::MockAsyncDnsResolver> mock_async_dns_resolver_;
240 webrtc::MockAsyncDnsResolverResult mock_async_dns_resolver_result_;
241 std::function<void()> saved_callback_;
242 };
243
HasLocalAddress(const cricket::CandidatePairInterface * pair,const SocketAddress & address)244 bool HasLocalAddress(const cricket::CandidatePairInterface* pair,
245 const SocketAddress& address) {
246 return pair->local_candidate().address().EqualIPs(address);
247 }
248
HasRemoteAddress(const cricket::CandidatePairInterface * pair,const SocketAddress & address)249 bool HasRemoteAddress(const cricket::CandidatePairInterface* pair,
250 const SocketAddress& address) {
251 return pair->remote_candidate().address().EqualIPs(address);
252 }
253
254 } // namespace
255
256 namespace cricket {
257
258 // This test simulates 2 P2P endpoints that want to establish connectivity
259 // with each other over various network topologies and conditions, which can be
260 // specified in each individial test.
261 // A virtual network (via VirtualSocketServer) along with virtual firewalls and
262 // NATs (via Firewall/NATSocketServer) are used to simulate the various network
263 // conditions. We can configure the IP addresses of the endpoints,
264 // block various types of connectivity, or add arbitrary levels of NAT.
265 // We also run a STUN server and a relay server on the virtual network to allow
266 // our typical P2P mechanisms to do their thing.
267 // For each case, we expect the P2P stack to eventually settle on a specific
268 // form of connectivity to the other side. The test checks that the P2P
269 // negotiation successfully establishes connectivity within a certain time,
270 // and that the result is what we expect.
271 // Note that this class is a base class for use by other tests, who will provide
272 // specialized test behavior.
273 class P2PTransportChannelTestBase : public ::testing::Test,
274 public sigslot::has_slots<> {
275 public:
P2PTransportChannelTestBase(absl::string_view field_trials)276 explicit P2PTransportChannelTestBase(absl::string_view field_trials)
277 : field_trials_(field_trials),
278 vss_(new rtc::VirtualSocketServer()),
279 nss_(new rtc::NATSocketServer(vss_.get())),
280 ss_(new rtc::FirewallSocketServer(nss_.get())),
281 main_(ss_.get()),
282 stun_server_(TestStunServer::Create(ss_.get(), kStunAddr)),
283 turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
284 socks_server1_(ss_.get(),
285 kSocksProxyAddrs[0],
286 ss_.get(),
287 kSocksProxyAddrs[0]),
288 socks_server2_(ss_.get(),
289 kSocksProxyAddrs[1],
290 ss_.get(),
291 kSocksProxyAddrs[1]),
292 force_relay_(false) {
293 ep1_.role_ = ICEROLE_CONTROLLING;
294 ep2_.role_ = ICEROLE_CONTROLLED;
295
296 ServerAddresses stun_servers;
297 stun_servers.insert(kStunAddr);
298 ep1_.allocator_.reset(CreateBasicPortAllocator(
299 &ep1_.network_manager_, ss_.get(), stun_servers, kTurnUdpIntAddr,
300 rtc::SocketAddress()));
301 ep2_.allocator_.reset(CreateBasicPortAllocator(
302 &ep2_.network_manager_, ss_.get(), stun_servers, kTurnUdpIntAddr,
303 rtc::SocketAddress()));
304
305 ep1_.SetIceTiebreaker(kTiebreakerDefault);
306 ep1_.allocator_->SetIceTiebreaker(kTiebreakerDefault);
307 ep2_.SetIceTiebreaker(kTiebreakerDefault);
308 ep2_.allocator_->SetIceTiebreaker(kTiebreakerDefault);
309 webrtc::metrics::Reset();
310 }
311
P2PTransportChannelTestBase()312 P2PTransportChannelTestBase()
313 : P2PTransportChannelTestBase(absl::string_view()) {}
314
315 protected:
316 enum Config {
317 OPEN, // Open to the Internet
318 NAT_FULL_CONE, // NAT, no filtering
319 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
320 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
321 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
322 NAT_DOUBLE_CONE, // Double NAT, both cone
323 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
324 BLOCK_UDP, // Firewall, UDP in/out blocked
325 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
326 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
327 PROXY_HTTPS, // All traffic through HTTPS proxy
328 PROXY_SOCKS, // All traffic through SOCKS proxy
329 NUM_CONFIGS
330 };
331
332 struct Result {
Resultcricket::P2PTransportChannelTestBase::Result333 Result(absl::string_view controlling_type,
334 absl::string_view controlling_protocol,
335 absl::string_view controlled_type,
336 absl::string_view controlled_protocol,
337 int wait)
338 : controlling_type(controlling_type),
339 controlling_protocol(controlling_protocol),
340 controlled_type(controlled_type),
341 controlled_protocol(controlled_protocol),
342 connect_wait(wait) {}
343
344 // The expected candidate type and protocol of the controlling ICE agent.
345 std::string controlling_type;
346 std::string controlling_protocol;
347 // The expected candidate type and protocol of the controlled ICE agent.
348 std::string controlled_type;
349 std::string controlled_protocol;
350 // How long to wait before the correct candidate pair is selected.
351 int connect_wait;
352 };
353
354 struct ChannelData {
CheckDatacricket::P2PTransportChannelTestBase::ChannelData355 bool CheckData(const char* data, int len) {
356 bool ret = false;
357 if (!ch_packets_.empty()) {
358 std::string packet = ch_packets_.front();
359 ret = (packet == std::string(data, len));
360 ch_packets_.pop_front();
361 }
362 return ret;
363 }
364
365 std::string name_; // TODO(?) - Currently not used.
366 std::list<std::string> ch_packets_;
367 std::unique_ptr<P2PTransportChannel> ch_;
368 };
369
370 struct CandidateData {
371 IceTransportInternal* channel;
372 Candidate candidate;
373 };
374
375 struct Endpoint : public sigslot::has_slots<> {
Endpointcricket::P2PTransportChannelTestBase::Endpoint376 Endpoint()
377 : role_(ICEROLE_UNKNOWN),
378 tiebreaker_(0),
379 role_conflict_(false),
380 save_candidates_(false) {}
HasTransportcricket::P2PTransportChannelTestBase::Endpoint381 bool HasTransport(const rtc::PacketTransportInternal* transport) {
382 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
383 }
GetChannelDatacricket::P2PTransportChannelTestBase::Endpoint384 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
385 if (!HasTransport(transport))
386 return NULL;
387 if (cd1_.ch_.get() == transport)
388 return &cd1_;
389 else
390 return &cd2_;
391 }
392
SetIceRolecricket::P2PTransportChannelTestBase::Endpoint393 void SetIceRole(IceRole role) { role_ = role; }
ice_rolecricket::P2PTransportChannelTestBase::Endpoint394 IceRole ice_role() { return role_; }
SetIceTiebreakercricket::P2PTransportChannelTestBase::Endpoint395 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
GetIceTiebreakercricket::P2PTransportChannelTestBase::Endpoint396 uint64_t GetIceTiebreaker() { return tiebreaker_; }
OnRoleConflictcricket::P2PTransportChannelTestBase::Endpoint397 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
role_conflictcricket::P2PTransportChannelTestBase::Endpoint398 bool role_conflict() { return role_conflict_; }
SetAllocationStepDelaycricket::P2PTransportChannelTestBase::Endpoint399 void SetAllocationStepDelay(uint32_t delay) {
400 allocator_->set_step_delay(delay);
401 }
SetAllowTcpListencricket::P2PTransportChannelTestBase::Endpoint402 void SetAllowTcpListen(bool allow_tcp_listen) {
403 allocator_->set_allow_tcp_listen(allow_tcp_listen);
404 }
405
OnIceRegatheringcricket::P2PTransportChannelTestBase::Endpoint406 void OnIceRegathering(PortAllocatorSession*, IceRegatheringReason reason) {
407 ++ice_regathering_counter_[reason];
408 }
409
GetIceRegatheringCountForReasoncricket::P2PTransportChannelTestBase::Endpoint410 int GetIceRegatheringCountForReason(IceRegatheringReason reason) {
411 return ice_regathering_counter_[reason];
412 }
413
414 rtc::FakeNetworkManager network_manager_;
415 std::unique_ptr<BasicPortAllocator> allocator_;
416 webrtc::AsyncDnsResolverFactoryInterface* async_dns_resolver_factory_;
417 ChannelData cd1_;
418 ChannelData cd2_;
419 IceRole role_;
420 uint64_t tiebreaker_;
421 bool role_conflict_;
422 bool save_candidates_;
423 std::vector<CandidateData> saved_candidates_;
424 bool ready_to_send_ = false;
425 std::map<IceRegatheringReason, int> ice_regathering_counter_;
426 };
427
GetChannelData(rtc::PacketTransportInternal * transport)428 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
429 if (ep1_.HasTransport(transport))
430 return ep1_.GetChannelData(transport);
431 else
432 return ep2_.GetChannelData(transport);
433 }
434
IceParamsWithRenomination(const IceParameters & ice,bool renomination)435 IceParameters IceParamsWithRenomination(const IceParameters& ice,
436 bool renomination) {
437 IceParameters new_ice = ice;
438 new_ice.renomination = renomination;
439 return new_ice;
440 }
441
CreateChannels(const IceConfig & ep1_config,const IceConfig & ep2_config,bool renomination=false)442 void CreateChannels(const IceConfig& ep1_config,
443 const IceConfig& ep2_config,
444 bool renomination = false) {
445 IceParameters ice_ep1_cd1_ch =
446 IceParamsWithRenomination(kIceParams[0], renomination);
447 IceParameters ice_ep2_cd1_ch =
448 IceParamsWithRenomination(kIceParams[1], renomination);
449 ep1_.cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
450 ice_ep1_cd1_ch, ice_ep2_cd1_ch);
451 ep2_.cd1_.ch_ = CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
452 ice_ep2_cd1_ch, ice_ep1_cd1_ch);
453 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
454 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
455 ep1_.cd1_.ch_->MaybeStartGathering();
456 ep2_.cd1_.ch_->MaybeStartGathering();
457 ep1_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
458 &ep1_, &Endpoint::OnIceRegathering);
459 ep2_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
460 &ep2_, &Endpoint::OnIceRegathering);
461 }
462
CreateChannels()463 void CreateChannels() {
464 IceConfig default_config;
465 CreateChannels(default_config, default_config, false);
466 }
467
CreateChannel(int endpoint,int component,const IceParameters & local_ice,const IceParameters & remote_ice)468 std::unique_ptr<P2PTransportChannel> CreateChannel(
469 int endpoint,
470 int component,
471 const IceParameters& local_ice,
472 const IceParameters& remote_ice) {
473 webrtc::IceTransportInit init;
474 init.set_port_allocator(GetAllocator(endpoint));
475 init.set_async_dns_resolver_factory(
476 GetEndpoint(endpoint)->async_dns_resolver_factory_);
477 init.set_field_trials(&field_trials_);
478 auto channel = P2PTransportChannel::Create("test content name", component,
479 std::move(init));
480 channel->SignalReadyToSend.connect(
481 this, &P2PTransportChannelTestBase::OnReadyToSend);
482 channel->SignalCandidateGathered.connect(
483 this, &P2PTransportChannelTestBase::OnCandidateGathered);
484 channel->SignalCandidatesRemoved.connect(
485 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
486 channel->SignalReadPacket.connect(
487 this, &P2PTransportChannelTestBase::OnReadPacket);
488 channel->SignalRoleConflict.connect(
489 this, &P2PTransportChannelTestBase::OnRoleConflict);
490 channel->SignalNetworkRouteChanged.connect(
491 this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
492 channel->SignalSentPacket.connect(
493 this, &P2PTransportChannelTestBase::OnSentPacket);
494 channel->SetIceParameters(local_ice);
495 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
496 channel->SetRemoteIceParameters(remote_ice);
497 }
498 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
499 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
500 return channel;
501 }
502
DestroyChannels()503 void DestroyChannels() {
504 safety_->SetNotAlive();
505 ep1_.cd1_.ch_.reset();
506 ep2_.cd1_.ch_.reset();
507 ep1_.cd2_.ch_.reset();
508 ep2_.cd2_.ch_.reset();
509 // Process pending tasks that need to run for cleanup purposes such as
510 // pending deletion of Connection objects (see Connection::Destroy).
511 rtc::Thread::Current()->ProcessMessages(0);
512 }
ep1_ch1()513 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
ep1_ch2()514 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
ep2_ch1()515 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
ep2_ch2()516 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
517
test_turn_server()518 TestTurnServer* test_turn_server() { return &turn_server_; }
virtual_socket_server()519 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
520
521 // Common results.
522 static const Result kLocalUdpToLocalUdp;
523 static const Result kLocalUdpToStunUdp;
524 static const Result kLocalUdpToPrflxUdp;
525 static const Result kPrflxUdpToLocalUdp;
526 static const Result kStunUdpToLocalUdp;
527 static const Result kStunUdpToStunUdp;
528 static const Result kStunUdpToPrflxUdp;
529 static const Result kPrflxUdpToStunUdp;
530 static const Result kLocalUdpToRelayUdp;
531 static const Result kPrflxUdpToRelayUdp;
532 static const Result kRelayUdpToPrflxUdp;
533 static const Result kLocalTcpToLocalTcp;
534 static const Result kLocalTcpToPrflxTcp;
535 static const Result kPrflxTcpToLocalTcp;
536
nat()537 rtc::NATSocketServer* nat() { return nss_.get(); }
fw()538 rtc::FirewallSocketServer* fw() { return ss_.get(); }
539
GetEndpoint(int endpoint)540 Endpoint* GetEndpoint(int endpoint) {
541 if (endpoint == 0) {
542 return &ep1_;
543 } else if (endpoint == 1) {
544 return &ep2_;
545 } else {
546 return NULL;
547 }
548 }
GetAllocator(int endpoint)549 BasicPortAllocator* GetAllocator(int endpoint) {
550 return GetEndpoint(endpoint)->allocator_.get();
551 }
AddAddress(int endpoint,const SocketAddress & addr)552 void AddAddress(int endpoint, const SocketAddress& addr) {
553 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
554 }
AddAddress(int endpoint,const SocketAddress & addr,absl::string_view ifname,rtc::AdapterType adapter_type,absl::optional<rtc::AdapterType> underlying_vpn_adapter_type=absl::nullopt)555 void AddAddress(int endpoint,
556 const SocketAddress& addr,
557 absl::string_view ifname,
558 rtc::AdapterType adapter_type,
559 absl::optional<rtc::AdapterType> underlying_vpn_adapter_type =
560 absl::nullopt) {
561 GetEndpoint(endpoint)->network_manager_.AddInterface(
562 addr, ifname, adapter_type, underlying_vpn_adapter_type);
563 }
RemoveAddress(int endpoint,const SocketAddress & addr)564 void RemoveAddress(int endpoint, const SocketAddress& addr) {
565 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
566 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
567 }
SetProxy(int endpoint,rtc::ProxyType type)568 void SetProxy(int endpoint, rtc::ProxyType type) {
569 rtc::ProxyInfo info;
570 info.type = type;
571 info.address = (type == rtc::PROXY_HTTPS) ? kHttpsProxyAddrs[endpoint]
572 : kSocksProxyAddrs[endpoint];
573 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
574 }
SetAllocatorFlags(int endpoint,int flags)575 void SetAllocatorFlags(int endpoint, int flags) {
576 GetAllocator(endpoint)->set_flags(flags);
577 }
SetIceRole(int endpoint,IceRole role)578 void SetIceRole(int endpoint, IceRole role) {
579 GetEndpoint(endpoint)->SetIceRole(role);
580 }
SetIceTiebreaker(int endpoint,uint64_t tiebreaker)581 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
582 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
583 }
GetRoleConflict(int endpoint)584 bool GetRoleConflict(int endpoint) {
585 return GetEndpoint(endpoint)->role_conflict();
586 }
SetAllocationStepDelay(int endpoint,uint32_t delay)587 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
588 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
589 }
SetAllowTcpListen(int endpoint,bool allow_tcp_listen)590 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
591 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
592 }
593
594 // Return true if the approprite parts of the expected Result, based
595 // on the local and remote candidate of ep1_ch1, match. This can be
596 // used in an EXPECT_TRUE_WAIT.
CheckCandidate1(const Result & expected)597 bool CheckCandidate1(const Result& expected) {
598 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
599 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
600 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
601 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
602 return (local_protocol == expected.controlling_protocol &&
603 remote_protocol == expected.controlled_protocol &&
604 local_type == expected.controlling_type &&
605 remote_type == expected.controlled_type);
606 }
607
608 // EXPECT_EQ on the approprite parts of the expected Result, based
609 // on the local and remote candidate of ep1_ch1. This is like
610 // CheckCandidate1, except that it will provide more detail about
611 // what didn't match.
ExpectCandidate1(const Result & expected)612 void ExpectCandidate1(const Result& expected) {
613 if (CheckCandidate1(expected)) {
614 return;
615 }
616
617 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
618 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
619 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
620 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
621 EXPECT_EQ(expected.controlling_type, local_type);
622 EXPECT_EQ(expected.controlled_type, remote_type);
623 EXPECT_EQ(expected.controlling_protocol, local_protocol);
624 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
625 }
626
627 // Return true if the approprite parts of the expected Result, based
628 // on the local and remote candidate of ep2_ch1, match. This can be
629 // used in an EXPECT_TRUE_WAIT.
CheckCandidate2(const Result & expected)630 bool CheckCandidate2(const Result& expected) {
631 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
632 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
633 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
634 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
635 return (local_protocol == expected.controlled_protocol &&
636 remote_protocol == expected.controlling_protocol &&
637 local_type == expected.controlled_type &&
638 remote_type == expected.controlling_type);
639 }
640
641 // EXPECT_EQ on the approprite parts of the expected Result, based
642 // on the local and remote candidate of ep2_ch1. This is like
643 // CheckCandidate2, except that it will provide more detail about
644 // what didn't match.
ExpectCandidate2(const Result & expected)645 void ExpectCandidate2(const Result& expected) {
646 if (CheckCandidate2(expected)) {
647 return;
648 }
649
650 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
651 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
652 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
653 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
654 EXPECT_EQ(expected.controlled_type, local_type);
655 EXPECT_EQ(expected.controlling_type, remote_type);
656 EXPECT_EQ(expected.controlled_protocol, local_protocol);
657 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
658 }
659
CheckCandidate(P2PTransportChannel * channel,SocketAddress from,SocketAddress to)660 static bool CheckCandidate(P2PTransportChannel* channel,
661 SocketAddress from,
662 SocketAddress to) {
663 auto local_candidate = LocalCandidate(channel);
664 auto remote_candidate = RemoteCandidate(channel);
665 return local_candidate != nullptr &&
666 local_candidate->address().EqualIPs(from) &&
667 remote_candidate != nullptr &&
668 remote_candidate->address().EqualIPs(to);
669 }
670
CheckCandidatePair(P2PTransportChannel * ch1,P2PTransportChannel * ch2,SocketAddress from,SocketAddress to)671 static bool CheckCandidatePair(P2PTransportChannel* ch1,
672 P2PTransportChannel* ch2,
673 SocketAddress from,
674 SocketAddress to) {
675 return CheckCandidate(ch1, from, to) && CheckCandidate(ch2, to, from);
676 }
677
CheckConnected(P2PTransportChannel * ch1,P2PTransportChannel * ch2)678 static bool CheckConnected(P2PTransportChannel* ch1,
679 P2PTransportChannel* ch2) {
680 return ch1 != nullptr && ch1->receiving() && ch1->writable() &&
681 ch2 != nullptr && ch2->receiving() && ch2->writable();
682 }
683
CheckCandidatePairAndConnected(P2PTransportChannel * ch1,P2PTransportChannel * ch2,SocketAddress from,SocketAddress to)684 static bool CheckCandidatePairAndConnected(P2PTransportChannel* ch1,
685 P2PTransportChannel* ch2,
686 SocketAddress from,
687 SocketAddress to) {
688 return CheckConnected(ch1, ch2) && CheckCandidatePair(ch1, ch2, from, to);
689 }
690
Test(const Result & expected)691 virtual void Test(const Result& expected) {
692 rtc::ScopedFakeClock clock;
693 int64_t connect_start = rtc::TimeMillis();
694 int64_t connect_time;
695
696 // Create the channels and wait for them to connect.
697 CreateChannels();
698 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
699 expected.connect_wait + kShortTimeout, clock);
700 connect_time = rtc::TimeMillis() - connect_start;
701 if (connect_time < expected.connect_wait) {
702 RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
703 } else {
704 RTC_LOG(LS_INFO) << "Connect time: TIMEOUT (" << expected.connect_wait
705 << " ms)";
706 }
707
708 // Allow a few turns of the crank for the selected connections to emerge.
709 // This may take up to 2 seconds.
710 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
711 int64_t converge_start = rtc::TimeMillis();
712 int64_t converge_time;
713 // Verifying local and remote channel selected connection information.
714 // This is done only for the RFC 5245 as controlled agent will use
715 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
716 // EP1 result matrix.
717 EXPECT_TRUE_SIMULATED_WAIT(
718 CheckCandidate1(expected) && CheckCandidate2(expected),
719 kDefaultTimeout, clock);
720 // Also do EXPECT_EQ on each part so that failures are more verbose.
721 ExpectCandidate1(expected);
722 ExpectCandidate2(expected);
723
724 converge_time = rtc::TimeMillis() - converge_start;
725 int64_t converge_wait = 2000;
726 if (converge_time < converge_wait) {
727 RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
728 } else {
729 RTC_LOG(LS_INFO) << "Converge time: TIMEOUT (" << converge_time
730 << " ms)";
731 }
732 }
733 // Try sending some data to other end.
734 TestSendRecv(&clock);
735
736 // Destroy the channels, and wait for them to be fully cleaned up.
737 DestroyChannels();
738 }
739
TestSendRecv(rtc::ThreadProcessingFakeClock * clock)740 void TestSendRecv(rtc::ThreadProcessingFakeClock* clock) {
741 for (int i = 0; i < 10; ++i) {
742 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
743 int len = static_cast<int>(strlen(data));
744 // local_channel1 <==> remote_channel1
745 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
746 kMediumTimeout, *clock);
747 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
748 kMediumTimeout, *clock);
749 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
750 kMediumTimeout, *clock);
751 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
752 kMediumTimeout, *clock);
753 }
754 }
755
756 // This test waits for the transport to become receiving and writable on both
757 // end points. Once they are, the end points set new local ice parameters and
758 // restart the ice gathering. Finally it waits for the transport to select a
759 // new connection using the newly generated ice candidates.
760 // Before calling this function the end points must be configured.
TestHandleIceUfragPasswordChanged()761 void TestHandleIceUfragPasswordChanged() {
762 rtc::ScopedFakeClock clock;
763 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
764 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
765 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
766 kMediumTimeout, clock);
767
768 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
769 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
770 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
771 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
772
773 ep1_ch1()->SetIceParameters(kIceParams[2]);
774 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
775 ep1_ch1()->MaybeStartGathering();
776 ep2_ch1()->SetIceParameters(kIceParams[3]);
777
778 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
779 ep2_ch1()->MaybeStartGathering();
780
781 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
782 old_local_candidate1->generation(),
783 kMediumTimeout, clock);
784 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
785 old_local_candidate2->generation(),
786 kMediumTimeout, clock);
787 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
788 old_remote_candidate1->generation(),
789 kMediumTimeout, clock);
790 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
791 old_remote_candidate2->generation(),
792 kMediumTimeout, clock);
793 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
794 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
795 }
796
TestSignalRoleConflict()797 void TestSignalRoleConflict() {
798 rtc::ScopedFakeClock clock;
799 // Default EP1 is in controlling state.
800 SetIceTiebreaker(0, kLowTiebreaker);
801
802 SetIceRole(1, ICEROLE_CONTROLLING);
803 SetIceTiebreaker(1, kHighTiebreaker);
804
805 // Creating channels with both channels role set to CONTROLLING.
806 CreateChannels();
807 // Since both the channels initiated with controlling state and channel2
808 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
809 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
810 EXPECT_FALSE(GetRoleConflict(1));
811
812 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
813 kShortTimeout, clock);
814
815 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
816 ep2_ch1()->selected_connection());
817
818 TestSendRecv(&clock);
819 DestroyChannels();
820 }
821
TestPacketInfoIsSet(rtc::PacketInfo info)822 void TestPacketInfoIsSet(rtc::PacketInfo info) {
823 EXPECT_NE(info.packet_type, rtc::PacketType::kUnknown);
824 EXPECT_NE(info.protocol, rtc::PacketInfoProtocolType::kUnknown);
825 EXPECT_TRUE(info.network_id.has_value());
826 }
827
OnReadyToSend(rtc::PacketTransportInternal * transport)828 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
829 GetEndpoint(transport)->ready_to_send_ = true;
830 }
831
832 // We pass the candidates directly to the other side.
OnCandidateGathered(IceTransportInternal * ch,const Candidate & c)833 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
834 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
835 return;
836
837 if (GetEndpoint(ch)->save_candidates_) {
838 GetEndpoint(ch)->saved_candidates_.push_back(
839 {.channel = ch, .candidate = c});
840 } else {
841 main_.PostTask(SafeTask(
842 safety_, [this, ch, c = c]() mutable { AddCandidate(ch, c); }));
843 }
844 }
845
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)846 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
847 // If the `network_route` is unset, don't count. This is used in the case
848 // when the network on remote side is down, the signal will be fired with an
849 // unset network route and it shouldn't trigger a connection switch.
850 if (network_route) {
851 ++selected_candidate_pair_switches_;
852 }
853 }
854
reset_selected_candidate_pair_switches()855 int reset_selected_candidate_pair_switches() {
856 int switches = selected_candidate_pair_switches_;
857 selected_candidate_pair_switches_ = 0;
858 return switches;
859 }
860
PauseCandidates(int endpoint)861 void PauseCandidates(int endpoint) {
862 GetEndpoint(endpoint)->save_candidates_ = true;
863 }
864
OnCandidatesRemoved(IceTransportInternal * ch,const std::vector<Candidate> & candidates)865 void OnCandidatesRemoved(IceTransportInternal* ch,
866 const std::vector<Candidate>& candidates) {
867 // Candidate removals are not paused.
868 main_.PostTask(SafeTask(safety_, [this, ch, candidates]() mutable {
869 P2PTransportChannel* rch = GetRemoteChannel(ch);
870 if (rch == nullptr) {
871 return;
872 }
873 for (const Candidate& c : candidates) {
874 RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
875 rch->RemoveRemoteCandidate(c);
876 }
877 }));
878 }
879
880 // Tcp candidate verification has to be done when they are generated.
VerifySavedTcpCandidates(int endpoint,absl::string_view tcptype)881 void VerifySavedTcpCandidates(int endpoint, absl::string_view tcptype) {
882 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
883 EXPECT_EQ(data.candidate.protocol(), TCP_PROTOCOL_NAME);
884 EXPECT_EQ(data.candidate.tcptype(), tcptype);
885 if (data.candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
886 EXPECT_EQ(data.candidate.address().port(), DISCARD_PORT);
887 } else if (data.candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
888 EXPECT_NE(data.candidate.address().port(), DISCARD_PORT);
889 } else {
890 FAIL() << "Unknown tcptype: " << data.candidate.tcptype();
891 }
892 }
893 }
894
ResumeCandidates(int endpoint)895 void ResumeCandidates(int endpoint) {
896 Endpoint* ed = GetEndpoint(endpoint);
897 std::vector<CandidateData> candidates = std::move(ed->saved_candidates_);
898 if (!candidates.empty()) {
899 main_.PostTask(SafeTask(
900 safety_, [this, candidates = std::move(candidates)]() mutable {
901 for (CandidateData& data : candidates) {
902 AddCandidate(data.channel, data.candidate);
903 }
904 }));
905 }
906 ed->saved_candidates_.clear();
907 ed->save_candidates_ = false;
908 }
909
AddCandidate(IceTransportInternal * channel,Candidate & candidate)910 void AddCandidate(IceTransportInternal* channel, Candidate& candidate) {
911 P2PTransportChannel* rch = GetRemoteChannel(channel);
912 if (rch == nullptr) {
913 return;
914 }
915 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
916 candidate.set_username("");
917 candidate.set_password("");
918 }
919 RTC_LOG(LS_INFO) << "Candidate(" << channel->component() << "->"
920 << rch->component() << "): " << candidate.ToString();
921 rch->AddRemoteCandidate(candidate);
922 }
923
OnReadPacket(rtc::PacketTransportInternal * transport,const char * data,size_t len,const int64_t &,int flags)924 void OnReadPacket(rtc::PacketTransportInternal* transport,
925 const char* data,
926 size_t len,
927 const int64_t& /* packet_time_us */,
928 int flags) {
929 std::list<std::string>& packets = GetPacketList(transport);
930 packets.push_front(std::string(data, len));
931 }
932
OnRoleConflict(IceTransportInternal * channel)933 void OnRoleConflict(IceTransportInternal* channel) {
934 GetEndpoint(channel)->OnRoleConflict(true);
935 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
936 ? ICEROLE_CONTROLLED
937 : ICEROLE_CONTROLLING;
938 channel->SetIceRole(new_role);
939 }
940
OnSentPacket(rtc::PacketTransportInternal * transport,const rtc::SentPacket & packet)941 void OnSentPacket(rtc::PacketTransportInternal* transport,
942 const rtc::SentPacket& packet) {
943 TestPacketInfoIsSet(packet.info);
944 }
945
SendData(IceTransportInternal * channel,const char * data,size_t len)946 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
947 rtc::PacketOptions options;
948 return channel->SendPacket(data, len, options, 0);
949 }
CheckDataOnChannel(IceTransportInternal * channel,const char * data,int len)950 bool CheckDataOnChannel(IceTransportInternal* channel,
951 const char* data,
952 int len) {
953 return GetChannelData(channel)->CheckData(data, len);
954 }
LocalCandidate(P2PTransportChannel * ch)955 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
956 return (ch && ch->selected_connection())
957 ? &ch->selected_connection()->local_candidate()
958 : NULL;
959 }
RemoteCandidate(P2PTransportChannel * ch)960 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
961 return (ch && ch->selected_connection())
962 ? &ch->selected_connection()->remote_candidate()
963 : NULL;
964 }
GetEndpoint(rtc::PacketTransportInternal * transport)965 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
966 if (ep1_.HasTransport(transport)) {
967 return &ep1_;
968 } else if (ep2_.HasTransport(transport)) {
969 return &ep2_;
970 } else {
971 return NULL;
972 }
973 }
GetRemoteChannel(IceTransportInternal * ch)974 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
975 if (ch == ep1_ch1())
976 return ep2_ch1();
977 else if (ch == ep1_ch2())
978 return ep2_ch2();
979 else if (ch == ep2_ch1())
980 return ep1_ch1();
981 else if (ch == ep2_ch2())
982 return ep1_ch2();
983 else
984 return NULL;
985 }
GetPacketList(rtc::PacketTransportInternal * transport)986 std::list<std::string>& GetPacketList(
987 rtc::PacketTransportInternal* transport) {
988 return GetChannelData(transport)->ch_packets_;
989 }
990
991 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
992
993 // How does the test pass ICE parameters to the P2PTransportChannel?
994 // On the candidate itself, or through SetRemoteIceParameters?
995 // Goes through the candidate itself by default.
set_remote_ice_parameter_source(RemoteIceParameterSource source)996 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
997 remote_ice_parameter_source_ = source;
998 }
999
set_force_relay(bool relay)1000 void set_force_relay(bool relay) { force_relay_ = relay; }
1001
ConnectSignalNominated(Connection * conn)1002 void ConnectSignalNominated(Connection* conn) {
1003 conn->SignalNominated.connect(this,
1004 &P2PTransportChannelTestBase::OnNominated);
1005 }
1006
OnNominated(Connection * conn)1007 void OnNominated(Connection* conn) { nominated_ = true; }
nominated()1008 bool nominated() { return nominated_; }
1009
1010 webrtc::test::ScopedKeyValueConfig field_trials_;
1011
1012 private:
1013 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1014 std::unique_ptr<rtc::NATSocketServer> nss_;
1015 std::unique_ptr<rtc::FirewallSocketServer> ss_;
1016 rtc::AutoSocketServerThread main_;
1017 rtc::scoped_refptr<PendingTaskSafetyFlag> safety_ =
1018 PendingTaskSafetyFlag::Create();
1019 std::unique_ptr<TestStunServer> stun_server_;
1020 TestTurnServer turn_server_;
1021 rtc::SocksProxyServer socks_server1_;
1022 rtc::SocksProxyServer socks_server2_;
1023 Endpoint ep1_;
1024 Endpoint ep2_;
1025 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
1026 bool force_relay_;
1027 int selected_candidate_pair_switches_ = 0;
1028
1029 bool nominated_ = false;
1030 };
1031
1032 // The tests have only a few outcomes, which we predefine.
1033 const P2PTransportChannelTestBase::Result
1034 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
1035 "udp",
1036 "local",
1037 "udp",
1038 1000);
1039 const P2PTransportChannelTestBase::Result
1040 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
1041 "udp",
1042 "stun",
1043 "udp",
1044 1000);
1045 const P2PTransportChannelTestBase::Result
1046 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
1047 "udp",
1048 "prflx",
1049 "udp",
1050 1000);
1051 const P2PTransportChannelTestBase::Result
1052 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
1053 "udp",
1054 "local",
1055 "udp",
1056 1000);
1057 const P2PTransportChannelTestBase::Result
1058 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
1059 "udp",
1060 "local",
1061 "udp",
1062 1000);
1063 const P2PTransportChannelTestBase::Result
1064 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
1065 "udp",
1066 "stun",
1067 "udp",
1068 1000);
1069 const P2PTransportChannelTestBase::Result
1070 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
1071 "udp",
1072 "prflx",
1073 "udp",
1074 1000);
1075 const P2PTransportChannelTestBase::Result
1076 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
1077 "udp",
1078 "stun",
1079 "udp",
1080 1000);
1081 const P2PTransportChannelTestBase::Result
1082 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
1083 "udp",
1084 "relay",
1085 "udp",
1086 2000);
1087 const P2PTransportChannelTestBase::Result
1088 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
1089 "udp",
1090 "relay",
1091 "udp",
1092 2000);
1093 const P2PTransportChannelTestBase::Result
1094 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
1095 "udp",
1096 "prflx",
1097 "udp",
1098 2000);
1099 const P2PTransportChannelTestBase::Result
1100 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
1101 "tcp",
1102 "local",
1103 "tcp",
1104 3000);
1105 const P2PTransportChannelTestBase::Result
1106 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
1107 "tcp",
1108 "prflx",
1109 "tcp",
1110 3000);
1111 const P2PTransportChannelTestBase::Result
1112 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
1113 "tcp",
1114 "local",
1115 "tcp",
1116 3000);
1117
1118 // Test the matrix of all the connectivity types we expect to see in the wild.
1119 // Just test every combination of the configs in the Config enum.
1120 class P2PTransportChannelTest : public P2PTransportChannelTestBase {
1121 public:
P2PTransportChannelTest()1122 P2PTransportChannelTest() : P2PTransportChannelTestBase() {}
P2PTransportChannelTest(absl::string_view field_trials)1123 explicit P2PTransportChannelTest(absl::string_view field_trials)
1124 : P2PTransportChannelTestBase(field_trials) {}
1125
1126 protected:
ConfigureEndpoints(Config config1,Config config2,int allocator_flags1,int allocator_flags2)1127 void ConfigureEndpoints(Config config1,
1128 Config config2,
1129 int allocator_flags1,
1130 int allocator_flags2) {
1131 ConfigureEndpoint(0, config1);
1132 SetAllocatorFlags(0, allocator_flags1);
1133 SetAllocationStepDelay(0, kMinimumStepDelay);
1134 ConfigureEndpoint(1, config2);
1135 SetAllocatorFlags(1, allocator_flags2);
1136 SetAllocationStepDelay(1, kMinimumStepDelay);
1137
1138 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
1139 }
ConfigureEndpoint(int endpoint,Config config)1140 void ConfigureEndpoint(int endpoint, Config config) {
1141 switch (config) {
1142 case OPEN:
1143 AddAddress(endpoint, kPublicAddrs[endpoint]);
1144 break;
1145 case NAT_FULL_CONE:
1146 case NAT_ADDR_RESTRICTED:
1147 case NAT_PORT_RESTRICTED:
1148 case NAT_SYMMETRIC:
1149 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1150 // Add a single NAT of the desired type
1151 nat()
1152 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1153 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
1154 ->AddClient(kPrivateAddrs[endpoint]);
1155 break;
1156 case NAT_DOUBLE_CONE:
1157 case NAT_SYMMETRIC_THEN_CONE:
1158 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1159 // Add a two cascaded NATs of the desired types
1160 nat()
1161 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1162 (config == NAT_DOUBLE_CONE) ? rtc::NAT_OPEN_CONE
1163 : rtc::NAT_SYMMETRIC)
1164 ->AddTranslator(kPrivateAddrs[endpoint],
1165 kCascadedNatAddrs[endpoint], rtc::NAT_OPEN_CONE)
1166 ->AddClient(kCascadedPrivateAddrs[endpoint]);
1167 break;
1168 case BLOCK_UDP:
1169 case BLOCK_UDP_AND_INCOMING_TCP:
1170 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1171 case PROXY_HTTPS:
1172 case PROXY_SOCKS:
1173 AddAddress(endpoint, kPublicAddrs[endpoint]);
1174 // Block all UDP
1175 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
1176 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1177 // Block TCP inbound to the endpoint
1178 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1179 kPublicAddrs[endpoint]);
1180 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1181 // Block all TCP to/from the endpoint except 80/443 out
1182 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1183 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1184 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1185 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1186 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1187 kPublicAddrs[endpoint]);
1188 } else if (config == PROXY_HTTPS) {
1189 // Block all TCP to/from the endpoint except to the proxy server
1190 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1191 kHttpsProxyAddrs[endpoint]);
1192 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1193 kPublicAddrs[endpoint]);
1194 SetProxy(endpoint, rtc::PROXY_HTTPS);
1195 } else if (config == PROXY_SOCKS) {
1196 // Block all TCP to/from the endpoint except to the proxy server
1197 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1198 kSocksProxyAddrs[endpoint]);
1199 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1200 kPublicAddrs[endpoint]);
1201 SetProxy(endpoint, rtc::PROXY_SOCKS5);
1202 }
1203 break;
1204 default:
1205 RTC_DCHECK_NOTREACHED();
1206 break;
1207 }
1208 }
1209 };
1210
1211 class P2PTransportChannelTestWithFieldTrials
1212 : public P2PTransportChannelTest,
1213 public WithParamInterface<std::string> {
1214 public:
P2PTransportChannelTestWithFieldTrials()1215 P2PTransportChannelTestWithFieldTrials()
1216 : P2PTransportChannelTest(GetParam()) {}
1217 };
1218
1219 class P2PTransportChannelMatrixTest
1220 : public P2PTransportChannelTestWithFieldTrials {
1221 protected:
1222 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
1223 };
1224
1225 // Shorthands for use in the test matrix.
1226 #define LULU &kLocalUdpToLocalUdp
1227 #define LUSU &kLocalUdpToStunUdp
1228 #define LUPU &kLocalUdpToPrflxUdp
1229 #define PULU &kPrflxUdpToLocalUdp
1230 #define SULU &kStunUdpToLocalUdp
1231 #define SUSU &kStunUdpToStunUdp
1232 #define SUPU &kStunUdpToPrflxUdp
1233 #define PUSU &kPrflxUdpToStunUdp
1234 #define LURU &kLocalUdpToRelayUdp
1235 #define PURU &kPrflxUdpToRelayUdp
1236 #define RUPU &kRelayUdpToPrflxUdp
1237 #define LTLT &kLocalTcpToLocalTcp
1238 #define LTPT &kLocalTcpToPrflxTcp
1239 #define PTLT &kPrflxTcpToLocalTcp
1240 // TODO(?): Enable these once TestRelayServer can accept external TCP.
1241 #define LTRT NULL
1242 #define LSRS NULL
1243
1244 // Test matrix. Originator behavior defined by rows, receiever by columns.
1245
1246 // TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
1247 // TODO(?): Fix NULLs caused by no HTTP proxy support.
1248 // TODO(?): Rearrange rows/columns from best to worst.
1249 const P2PTransportChannelMatrixTest::Result*
1250 P2PTransportChannelMatrixTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
1251 // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH
1252 // PRXS
1253 /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS,
1254 NULL, LTPT},
1255 /*CO*/
1256 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1257 LTRT},
1258 /*AD*/
1259 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1260 LTRT},
1261 /*PO*/
1262 {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL,
1263 LTRT},
1264 /*SY*/
1265 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1266 LTRT},
1267 /*2C*/
1268 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1269 LTRT},
1270 /*SC*/
1271 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1272 LTRT},
1273 /*!U*/
1274 {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL,
1275 LTRT},
1276 /*!T*/
1277 {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL,
1278 LTRT},
1279 /*HT*/
1280 {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL,
1281 LSRS},
1282 /*PR*/
1283 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1284 NULL},
1285 /*PR*/
1286 {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL,
1287 LTRT},
1288 };
1289
1290 // The actual tests that exercise all the various configurations.
1291 // Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
1292 #define P2P_TEST_DECLARATION(x, y, z) \
1293 TEST_P(P2PTransportChannelMatrixTest, z##Test##x##To##y) { \
1294 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1295 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
1296 if (kMatrix[x][y] != NULL) \
1297 Test(*kMatrix[x][y]); \
1298 else \
1299 RTC_LOG(LS_WARNING) << "Not yet implemented"; \
1300 }
1301
1302 #define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)
1303
1304 #define P2P_TEST_SET(x) \
1305 P2P_TEST(x, OPEN) \
1306 P2P_TEST(x, NAT_FULL_CONE) \
1307 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1308 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1309 P2P_TEST(x, NAT_SYMMETRIC) \
1310 P2P_TEST(x, NAT_DOUBLE_CONE) \
1311 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1312 P2P_TEST(x, BLOCK_UDP) \
1313 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1314 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1315 P2P_TEST(x, PROXY_HTTPS) \
1316 P2P_TEST(x, PROXY_SOCKS)
1317
1318 P2P_TEST_SET(OPEN)
1319 P2P_TEST_SET(NAT_FULL_CONE)
1320 P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1321 P2P_TEST_SET(NAT_PORT_RESTRICTED)
1322 P2P_TEST_SET(NAT_SYMMETRIC)
1323 P2P_TEST_SET(NAT_DOUBLE_CONE)
1324 P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1325 P2P_TEST_SET(BLOCK_UDP)
1326 P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
1327 P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1328 P2P_TEST_SET(PROXY_HTTPS)
1329 P2P_TEST_SET(PROXY_SOCKS)
1330
1331 INSTANTIATE_TEST_SUITE_P(
1332 Legacy,
1333 P2PTransportChannelMatrixTest,
1334 // Each field-trial is ~144 tests (some return not-yet-implemented).
1335 Values("", "WebRTC-IceFieldTrials/enable_goog_ping:true/"));
1336 INSTANTIATE_TEST_SUITE_P(
1337 Active,
1338 P2PTransportChannelMatrixTest,
1339 // Each field-trial is ~144 tests (some return not-yet-implemented).
1340 Values("WebRTC-UseActiveIceController/Enabled/",
1341 "WebRTC-IceFieldTrials/enable_goog_ping:true/"
1342 "WebRTC-UseActiveIceController/Enabled/"));
1343
1344 INSTANTIATE_TEST_SUITE_P(Legacy,
1345 P2PTransportChannelTestWithFieldTrials,
1346 Values(""));
1347 INSTANTIATE_TEST_SUITE_P(Active,
1348 P2PTransportChannelTestWithFieldTrials,
1349 Values("WebRTC-UseActiveIceController/Enabled/"));
1350
1351 // Test that we restart candidate allocation when local ufrag&pwd changed.
1352 // Standard Ice protocol is used.
TEST_P(P2PTransportChannelTestWithFieldTrials,HandleUfragPwdChange)1353 TEST_P(P2PTransportChannelTestWithFieldTrials, HandleUfragPwdChange) {
1354 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1355 kDefaultPortAllocatorFlags);
1356 CreateChannels();
1357 TestHandleIceUfragPasswordChanged();
1358 DestroyChannels();
1359 }
1360
1361 // Same as above test, but with a symmetric NAT.
1362 // We should end up with relay<->prflx candidate pairs, with generation "1".
TEST_P(P2PTransportChannelTestWithFieldTrials,HandleUfragPwdChangeSymmetricNat)1363 TEST_P(P2PTransportChannelTestWithFieldTrials,
1364 HandleUfragPwdChangeSymmetricNat) {
1365 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1366 kDefaultPortAllocatorFlags);
1367 CreateChannels();
1368 TestHandleIceUfragPasswordChanged();
1369 DestroyChannels();
1370 }
1371
1372 // Test the operation of GetStats.
TEST_P(P2PTransportChannelTestWithFieldTrials,GetStats)1373 TEST_P(P2PTransportChannelTestWithFieldTrials, GetStats) {
1374 rtc::ScopedFakeClock clock;
1375 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1376 kDefaultPortAllocatorFlags);
1377 CreateChannels();
1378 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1379 ep2_ch1()->receiving() &&
1380 ep2_ch1()->writable(),
1381 kMediumTimeout, clock);
1382 // Sends and receives 10 packets.
1383 TestSendRecv(&clock);
1384
1385 // Try sending a packet which is discarded due to the socket being blocked.
1386 virtual_socket_server()->SetSendingBlocked(true);
1387 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
1388 int len = static_cast<int>(strlen(data));
1389 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
1390
1391 IceTransportStats ice_transport_stats;
1392 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
1393 ASSERT_GE(ice_transport_stats.connection_infos.size(), 1u);
1394 ASSERT_GE(ice_transport_stats.candidate_stats_list.size(), 1u);
1395 EXPECT_EQ(ice_transport_stats.selected_candidate_pair_changes, 1u);
1396 ConnectionInfo* best_conn_info = nullptr;
1397 for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
1398 if (info.best_connection) {
1399 best_conn_info = &info;
1400 break;
1401 }
1402 }
1403 ASSERT_TRUE(best_conn_info != nullptr);
1404 EXPECT_TRUE(best_conn_info->receiving);
1405 EXPECT_TRUE(best_conn_info->writable);
1406 EXPECT_FALSE(best_conn_info->timeout);
1407 // Note that discarded packets are counted in sent_total_packets but not
1408 // sent_total_bytes.
1409 EXPECT_EQ(11U, best_conn_info->sent_total_packets);
1410 EXPECT_EQ(1U, best_conn_info->sent_discarded_packets);
1411 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1412 EXPECT_EQ(36U, best_conn_info->sent_discarded_bytes);
1413 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
1414 EXPECT_EQ(10U, best_conn_info->packets_received);
1415
1416 EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_sent);
1417 EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_received);
1418
1419 DestroyChannels();
1420 }
1421
TEST_P(P2PTransportChannelTestWithFieldTrials,GetStatsSwitchConnection)1422 TEST_P(P2PTransportChannelTestWithFieldTrials, GetStatsSwitchConnection) {
1423 rtc::ScopedFakeClock clock;
1424 IceConfig continual_gathering_config =
1425 CreateIceConfig(1000, GATHER_CONTINUALLY);
1426
1427 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1428 kDefaultPortAllocatorFlags);
1429
1430 AddAddress(0, kAlternateAddrs[1], "rmnet0", rtc::ADAPTER_TYPE_CELLULAR);
1431
1432 CreateChannels(continual_gathering_config, continual_gathering_config);
1433 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1434 ep2_ch1()->receiving() &&
1435 ep2_ch1()->writable(),
1436 kMediumTimeout, clock);
1437 // Sends and receives 10 packets.
1438 TestSendRecv(&clock);
1439
1440 IceTransportStats ice_transport_stats;
1441 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
1442 ASSERT_GE(ice_transport_stats.connection_infos.size(), 2u);
1443 ASSERT_GE(ice_transport_stats.candidate_stats_list.size(), 2u);
1444 EXPECT_EQ(ice_transport_stats.selected_candidate_pair_changes, 1u);
1445
1446 ConnectionInfo* best_conn_info = nullptr;
1447 for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
1448 if (info.best_connection) {
1449 best_conn_info = &info;
1450 break;
1451 }
1452 }
1453 ASSERT_TRUE(best_conn_info != nullptr);
1454 EXPECT_TRUE(best_conn_info->receiving);
1455 EXPECT_TRUE(best_conn_info->writable);
1456 EXPECT_FALSE(best_conn_info->timeout);
1457
1458 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1459 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
1460 EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_sent);
1461 EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_received);
1462
1463 auto old_selected_connection = ep1_ch1()->selected_connection();
1464 ep1_ch1()->RemoveConnectionForTest(
1465 const_cast<Connection*>(old_selected_connection));
1466
1467 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
1468 kMediumTimeout, clock);
1469
1470 // Sends and receives 10 packets.
1471 TestSendRecv(&clock);
1472
1473 IceTransportStats ice_transport_stats2;
1474 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats2));
1475
1476 int64_t sum_bytes_sent = 0;
1477 int64_t sum_bytes_received = 0;
1478 for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
1479 sum_bytes_sent += info.sent_total_bytes;
1480 sum_bytes_received += info.recv_total_bytes;
1481 }
1482
1483 EXPECT_EQ(10 * 36U, sum_bytes_sent);
1484 EXPECT_EQ(10 * 36U, sum_bytes_received);
1485
1486 EXPECT_EQ(20 * 36U, ice_transport_stats2.bytes_sent);
1487 EXPECT_EQ(20 * 36U, ice_transport_stats2.bytes_received);
1488
1489 DestroyChannels();
1490 }
1491
1492 // Tests that UMAs are recorded when ICE restarts while the channel
1493 // is disconnected.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestUMAIceRestartWhileDisconnected)1494 TEST_P(P2PTransportChannelTestWithFieldTrials,
1495 TestUMAIceRestartWhileDisconnected) {
1496 rtc::ScopedFakeClock clock;
1497 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1498
1499 CreateChannels();
1500 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
1501 kDefaultTimeout, clock);
1502
1503 // Drop all packets so that both channels become not writable.
1504 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1505 const int kWriteTimeoutDelay = 8000;
1506 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1507 kWriteTimeoutDelay, clock);
1508
1509 ep1_ch1()->SetIceParameters(kIceParams[2]);
1510 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1511 ep1_ch1()->MaybeStartGathering();
1512 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1513 "WebRTC.PeerConnection.IceRestartState",
1514 static_cast<int>(IceRestartState::DISCONNECTED)));
1515
1516 ep2_ch1()->SetIceParameters(kIceParams[3]);
1517 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1518 ep2_ch1()->MaybeStartGathering();
1519 EXPECT_METRIC_EQ(2, webrtc::metrics::NumEvents(
1520 "WebRTC.PeerConnection.IceRestartState",
1521 static_cast<int>(IceRestartState::DISCONNECTED)));
1522
1523 DestroyChannels();
1524 }
1525
1526 // Tests that UMAs are recorded when ICE restarts while the channel
1527 // is connected.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestUMAIceRestartWhileConnected)1528 TEST_P(P2PTransportChannelTestWithFieldTrials,
1529 TestUMAIceRestartWhileConnected) {
1530 rtc::ScopedFakeClock clock;
1531 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1532
1533 CreateChannels();
1534 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
1535 kDefaultTimeout, clock);
1536
1537 ep1_ch1()->SetIceParameters(kIceParams[2]);
1538 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1539 ep1_ch1()->MaybeStartGathering();
1540 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1541 "WebRTC.PeerConnection.IceRestartState",
1542 static_cast<int>(IceRestartState::CONNECTED)));
1543
1544 ep2_ch1()->SetIceParameters(kIceParams[3]);
1545 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1546 ep2_ch1()->MaybeStartGathering();
1547 EXPECT_METRIC_EQ(2, webrtc::metrics::NumEvents(
1548 "WebRTC.PeerConnection.IceRestartState",
1549 static_cast<int>(IceRestartState::CONNECTED)));
1550
1551 DestroyChannels();
1552 }
1553
1554 // Tests that UMAs are recorded when ICE restarts while the channel
1555 // is connecting.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestUMAIceRestartWhileConnecting)1556 TEST_P(P2PTransportChannelTestWithFieldTrials,
1557 TestUMAIceRestartWhileConnecting) {
1558 rtc::ScopedFakeClock clock;
1559 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1560
1561 // Create the channels without waiting for them to become connected.
1562 CreateChannels();
1563
1564 ep1_ch1()->SetIceParameters(kIceParams[2]);
1565 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1566 ep1_ch1()->MaybeStartGathering();
1567 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1568 "WebRTC.PeerConnection.IceRestartState",
1569 static_cast<int>(IceRestartState::CONNECTING)));
1570
1571 ep2_ch1()->SetIceParameters(kIceParams[3]);
1572 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1573 ep2_ch1()->MaybeStartGathering();
1574 EXPECT_METRIC_EQ(2, webrtc::metrics::NumEvents(
1575 "WebRTC.PeerConnection.IceRestartState",
1576 static_cast<int>(IceRestartState::CONNECTING)));
1577
1578 DestroyChannels();
1579 }
1580
1581 // Tests that a UMA on ICE regathering is recorded when there is a network
1582 // change if and only if continual gathering is enabled.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIceRegatheringReasonContinualGatheringByNetworkChange)1583 TEST_P(P2PTransportChannelTestWithFieldTrials,
1584 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1585 rtc::ScopedFakeClock clock;
1586 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1587
1588 // ep1 gathers continually but ep2 does not.
1589 IceConfig continual_gathering_config =
1590 CreateIceConfig(1000, GATHER_CONTINUALLY);
1591 IceConfig default_config;
1592 CreateChannels(continual_gathering_config, default_config);
1593
1594 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
1595 kDefaultTimeout, clock);
1596
1597 // Adding address in ep1 will trigger continual gathering.
1598 AddAddress(0, kAlternateAddrs[0]);
1599 EXPECT_EQ_SIMULATED_WAIT(1,
1600 GetEndpoint(0)->GetIceRegatheringCountForReason(
1601 IceRegatheringReason::NETWORK_CHANGE),
1602 kDefaultTimeout, clock);
1603
1604 ep2_ch1()->SetIceParameters(kIceParams[3]);
1605 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1606 ep2_ch1()->MaybeStartGathering();
1607
1608 AddAddress(1, kAlternateAddrs[1]);
1609 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1610 // ep2 has not enabled continual gathering.
1611 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1612 IceRegatheringReason::NETWORK_CHANGE));
1613
1614 DestroyChannels();
1615 }
1616
1617 // Tests that a UMA on ICE regathering is recorded when there is a network
1618 // failure if and only if continual gathering is enabled.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIceRegatheringReasonContinualGatheringByNetworkFailure)1619 TEST_P(P2PTransportChannelTestWithFieldTrials,
1620 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1621 rtc::ScopedFakeClock clock;
1622 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1623
1624 // ep1 gathers continually but ep2 does not.
1625 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1626 config1.regather_on_failed_networks_interval = 2000;
1627 IceConfig config2;
1628 config2.regather_on_failed_networks_interval = 2000;
1629 CreateChannels(config1, config2);
1630
1631 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
1632 kDefaultTimeout, clock);
1633
1634 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1635 // Timeout value such that all connections are deleted.
1636 const int kNetworkFailureTimeout = 35000;
1637 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
1638 EXPECT_LE(1, GetEndpoint(0)->GetIceRegatheringCountForReason(
1639 IceRegatheringReason::NETWORK_FAILURE));
1640 EXPECT_METRIC_LE(
1641 1, webrtc::metrics::NumEvents(
1642 "WebRTC.PeerConnection.IceRegatheringReason",
1643 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1644 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1645 IceRegatheringReason::NETWORK_FAILURE));
1646
1647 DestroyChannels();
1648 }
1649
1650 // Test that we properly create a connection on a STUN ping from unknown address
1651 // when the signaling is slow.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveCandidateBeforeSignaling)1652 TEST_P(P2PTransportChannelTestWithFieldTrials,
1653 PeerReflexiveCandidateBeforeSignaling) {
1654 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1655 kDefaultPortAllocatorFlags);
1656 // Emulate no remote parameters coming in.
1657 set_remote_ice_parameter_source(FROM_CANDIDATE);
1658 CreateChannels();
1659 // Only have remote parameters come in for ep2, not ep1.
1660 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
1661
1662 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1663 // candidate.
1664 PauseCandidates(1);
1665
1666 // Wait until the callee becomes writable to make sure that a ping request is
1667 // received by the caller before their remote ICE credentials are set.
1668 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
1669 // Add two sets of remote ICE credentials, so that the ones used by the
1670 // candidate will be generation 1 instead of 0.
1671 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1672 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1673 // The caller should have the selected connection connected to the peer
1674 // reflexive candidate.
1675 const Connection* selected_connection = nullptr;
1676 ASSERT_TRUE_WAIT(
1677 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
1678 kMediumTimeout);
1679 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
1680 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1681 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1682 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
1683
1684 ResumeCandidates(1);
1685 // Verify ep1's selected connection is updated to use the 'local' candidate.
1686 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
1687 ep1_ch1()->selected_connection()->remote_candidate().type(),
1688 kMediumTimeout);
1689 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
1690 DestroyChannels();
1691 }
1692
1693 // Test that if we learn a prflx remote candidate, its address is concealed in
1694 // 1. the selected candidate pair accessed via the public API, and
1695 // 2. the candidate pair stats
1696 // until we learn the same address from signaling.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveRemoteCandidateIsSanitized)1697 TEST_P(P2PTransportChannelTestWithFieldTrials,
1698 PeerReflexiveRemoteCandidateIsSanitized) {
1699 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1700 // Emulate no remote parameters coming in.
1701 set_remote_ice_parameter_source(FROM_CANDIDATE);
1702 CreateChannels();
1703 // Only have remote parameters come in for ep2, not ep1.
1704 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
1705
1706 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1707 // candidate.
1708 PauseCandidates(1);
1709
1710 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
1711 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1712 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
1713
1714 // Check the selected candidate pair.
1715 auto pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
1716 ASSERT_TRUE(pair_ep1.has_value());
1717 EXPECT_EQ(PRFLX_PORT_TYPE, pair_ep1->remote_candidate().type());
1718 EXPECT_TRUE(pair_ep1->remote_candidate().address().ipaddr().IsNil());
1719
1720 IceTransportStats ice_transport_stats;
1721 ep1_ch1()->GetStats(&ice_transport_stats);
1722 // Check the candidate pair stats.
1723 ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
1724 EXPECT_EQ(PRFLX_PORT_TYPE,
1725 ice_transport_stats.connection_infos[0].remote_candidate.type());
1726 EXPECT_TRUE(ice_transport_stats.connection_infos[0]
1727 .remote_candidate.address()
1728 .ipaddr()
1729 .IsNil());
1730
1731 // Let ep1 receive the remote candidate to update its type from prflx to host.
1732 ResumeCandidates(1);
1733 ASSERT_TRUE_WAIT(
1734 ep1_ch1()->selected_connection() != nullptr &&
1735 ep1_ch1()->selected_connection()->remote_candidate().type() ==
1736 LOCAL_PORT_TYPE,
1737 kMediumTimeout);
1738
1739 // We should be able to reveal the address after it is learnt via
1740 // AddIceCandidate.
1741 //
1742 // Check the selected candidate pair.
1743 auto updated_pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
1744 ASSERT_TRUE(updated_pair_ep1.has_value());
1745 EXPECT_EQ(LOCAL_PORT_TYPE, updated_pair_ep1->remote_candidate().type());
1746 EXPECT_TRUE(HasRemoteAddress(&updated_pair_ep1.value(), kPublicAddrs[1]));
1747
1748 ep1_ch1()->GetStats(&ice_transport_stats);
1749 // Check the candidate pair stats.
1750 ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
1751 EXPECT_EQ(LOCAL_PORT_TYPE,
1752 ice_transport_stats.connection_infos[0].remote_candidate.type());
1753 EXPECT_TRUE(ice_transport_stats.connection_infos[0]
1754 .remote_candidate.address()
1755 .EqualIPs(kPublicAddrs[1]));
1756
1757 DestroyChannels();
1758 }
1759
1760 // Test that we properly create a connection on a STUN ping from unknown address
1761 // when the signaling is slow and the end points are behind NAT.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveCandidateBeforeSignalingWithNAT)1762 TEST_P(P2PTransportChannelTestWithFieldTrials,
1763 PeerReflexiveCandidateBeforeSignalingWithNAT) {
1764 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1765 kDefaultPortAllocatorFlags);
1766 // Emulate no remote parameters coming in.
1767 set_remote_ice_parameter_source(FROM_CANDIDATE);
1768 CreateChannels();
1769 // Only have remote parameters come in for ep2, not ep1.
1770 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
1771 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1772 // candidate.
1773 PauseCandidates(1);
1774
1775 // Wait until the callee becomes writable to make sure that a ping request is
1776 // received by the caller before their remote ICE credentials are set.
1777 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
1778 // Add two sets of remote ICE credentials, so that the ones used by the
1779 // candidate will be generation 1 instead of 0.
1780 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1781 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1782
1783 // The caller's selected connection should be connected to the peer reflexive
1784 // candidate.
1785 const Connection* selected_connection = nullptr;
1786 ASSERT_TRUE_WAIT(
1787 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
1788 kMediumTimeout);
1789 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
1790 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1791 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1792 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
1793
1794 ResumeCandidates(1);
1795
1796 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
1797 ep1_ch1()->selected_connection()->remote_candidate().type(),
1798 kMediumTimeout);
1799 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
1800 DestroyChannels();
1801 }
1802
1803 // Test that we properly create a connection on a STUN ping from unknown address
1804 // when the signaling is slow, even if the new candidate is created due to the
1805 // remote peer doing an ICE restart, pairing this candidate across generations.
1806 //
1807 // Previously this wasn't working due to a bug where the peer reflexive
1808 // candidate was only updated for the newest generation candidate pairs, and
1809 // not older-generation candidate pairs created by pairing candidates across
1810 // generations. This resulted in the old-generation prflx candidate being
1811 // prioritized above new-generation candidate pairs.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveCandidateBeforeSignalingWithIceRestart)1812 TEST_P(P2PTransportChannelTestWithFieldTrials,
1813 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1814 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1815 kDefaultPortAllocatorFlags);
1816 // Only gather relay candidates, so that when the prflx candidate arrives
1817 // it's prioritized above the current candidate pair.
1818 GetEndpoint(0)->allocator_->SetCandidateFilter(CF_RELAY);
1819 GetEndpoint(1)->allocator_->SetCandidateFilter(CF_RELAY);
1820 // Setting this allows us to control when SetRemoteIceParameters is called.
1821 set_remote_ice_parameter_source(FROM_CANDIDATE);
1822 CreateChannels();
1823 // Wait for the initial connection to be made.
1824 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1825 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
1826 EXPECT_TRUE_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()), kDefaultTimeout);
1827
1828 // Simulate an ICE restart on ep2, but don't signal the candidate or new
1829 // ICE parameters until after a prflx connection has been made.
1830 PauseCandidates(1);
1831 ep2_ch1()->SetIceParameters(kIceParams[3]);
1832
1833 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1834 ep2_ch1()->MaybeStartGathering();
1835
1836 // The caller should have the selected connection connected to the peer
1837 // reflexive candidate.
1838 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
1839 ep1_ch1()->selected_connection()->remote_candidate().type(),
1840 kDefaultTimeout);
1841 const Connection* prflx_selected_connection =
1842 ep1_ch1()->selected_connection();
1843
1844 // Now simulate the ICE restart on ep1.
1845 ep1_ch1()->SetIceParameters(kIceParams[2]);
1846
1847 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1848 ep1_ch1()->MaybeStartGathering();
1849
1850 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1851 // their information to update the peer reflexive candidate.
1852 ResumeCandidates(1);
1853
1854 EXPECT_EQ_WAIT(RELAY_PORT_TYPE,
1855 ep1_ch1()->selected_connection()->remote_candidate().type(),
1856 kDefaultTimeout);
1857 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
1858 DestroyChannels();
1859 }
1860
1861 // Test that if remote candidates don't have ufrag and pwd, we still work.
TEST_P(P2PTransportChannelTestWithFieldTrials,RemoteCandidatesWithoutUfragPwd)1862 TEST_P(P2PTransportChannelTestWithFieldTrials,
1863 RemoteCandidatesWithoutUfragPwd) {
1864 rtc::ScopedFakeClock clock;
1865 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
1866 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1867 kDefaultPortAllocatorFlags);
1868 CreateChannels();
1869 const Connection* selected_connection = NULL;
1870 // Wait until the callee's connections are created.
1871 EXPECT_TRUE_SIMULATED_WAIT(
1872 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1873 kMediumTimeout, clock);
1874 // Wait to make sure the selected connection is not changed.
1875 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1876 kShortTimeout, clock);
1877 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
1878 DestroyChannels();
1879 }
1880
1881 // Test that a host behind NAT cannot be reached when incoming_only
1882 // is set to true.
TEST_P(P2PTransportChannelTestWithFieldTrials,IncomingOnlyBlocked)1883 TEST_P(P2PTransportChannelTestWithFieldTrials, IncomingOnlyBlocked) {
1884 rtc::ScopedFakeClock clock;
1885 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
1886 kDefaultPortAllocatorFlags);
1887
1888 SetAllocatorFlags(0, kOnlyLocalPorts);
1889 CreateChannels();
1890 ep1_ch1()->set_incoming_only(true);
1891
1892 // Pump for 1 second and verify that the channels are not connected.
1893 SIMULATED_WAIT(false, kShortTimeout, clock);
1894
1895 EXPECT_FALSE(ep1_ch1()->receiving());
1896 EXPECT_FALSE(ep1_ch1()->writable());
1897 EXPECT_FALSE(ep2_ch1()->receiving());
1898 EXPECT_FALSE(ep2_ch1()->writable());
1899
1900 DestroyChannels();
1901 }
1902
1903 // Test that a peer behind NAT can connect to a peer that has
1904 // incoming_only flag set.
TEST_P(P2PTransportChannelTestWithFieldTrials,IncomingOnlyOpen)1905 TEST_P(P2PTransportChannelTestWithFieldTrials, IncomingOnlyOpen) {
1906 rtc::ScopedFakeClock clock;
1907 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
1908 kDefaultPortAllocatorFlags);
1909
1910 SetAllocatorFlags(0, kOnlyLocalPorts);
1911 CreateChannels();
1912 ep1_ch1()->set_incoming_only(true);
1913
1914 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
1915 kMediumTimeout, clock);
1916
1917 DestroyChannels();
1918 }
1919
1920 // Test that two peers can connect when one can only make outgoing TCP
1921 // connections. This has been observed in some scenarios involving
1922 // VPNs/firewalls.
TEST_P(P2PTransportChannelTestWithFieldTrials,CanOnlyMakeOutgoingTcpConnections)1923 TEST_P(P2PTransportChannelTestWithFieldTrials,
1924 CanOnlyMakeOutgoingTcpConnections) {
1925 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1926 // application needs this use case to work, since the application must accept
1927 // the tradeoff that more candidates need to be allocated.
1928 //
1929 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1930 // things to ensure extra candidates don't waste resources?
1931 ConfigureEndpoints(
1932 OPEN, OPEN,
1933 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1934 kDefaultPortAllocatorFlags);
1935 // In order to simulate nothing working but outgoing TCP connections, prevent
1936 // the endpoint from binding to its interface's address as well as the
1937 // "any" addresses. It can then only make a connection by using "Connect()".
1938 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1939 kPublicAddrs[0].ipaddr()});
1940 CreateChannels();
1941 // Expect a "prflx" candidate on the side that can only make outgoing
1942 // connections, endpoint 0.
1943 Test(kPrflxTcpToLocalTcp);
1944 DestroyChannels();
1945 }
1946
TEST_P(P2PTransportChannelTestWithFieldTrials,TestTcpConnectionsFromActiveToPassive)1947 TEST_P(P2PTransportChannelTestWithFieldTrials,
1948 TestTcpConnectionsFromActiveToPassive) {
1949 rtc::ScopedFakeClock clock;
1950 AddAddress(0, kPublicAddrs[0]);
1951 AddAddress(1, kPublicAddrs[1]);
1952
1953 SetAllocationStepDelay(0, kMinimumStepDelay);
1954 SetAllocationStepDelay(1, kMinimumStepDelay);
1955
1956 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1957 PORTALLOCATOR_DISABLE_STUN |
1958 PORTALLOCATOR_DISABLE_RELAY;
1959 // Disable all protocols except TCP.
1960 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1961 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1962
1963 SetAllowTcpListen(0, true); // actpass.
1964 SetAllowTcpListen(1, false); // active.
1965
1966 // We want SetRemoteIceParameters to be called as it normally would.
1967 // Otherwise we won't know what parameters to use for the expected
1968 // prflx TCP candidates.
1969 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
1970
1971 // Pause candidate so we could verify the candidate properties.
1972 PauseCandidates(0);
1973 PauseCandidates(1);
1974 CreateChannels();
1975
1976 // Verify tcp candidates.
1977 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1978 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
1979
1980 // Resume candidates.
1981 ResumeCandidates(0);
1982 ResumeCandidates(1);
1983
1984 EXPECT_TRUE_SIMULATED_WAIT(
1985 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
1986 kPublicAddrs[1]),
1987 kShortTimeout, clock);
1988
1989 TestSendRecv(&clock);
1990 DestroyChannels();
1991 }
1992
1993 // Test that tcptype is set on all candidates for a connection running over TCP.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestTcpConnectionTcptypeSet)1994 TEST_P(P2PTransportChannelTestWithFieldTrials, TestTcpConnectionTcptypeSet) {
1995 rtc::ScopedFakeClock clock;
1996 ConfigureEndpoints(BLOCK_UDP_AND_INCOMING_TCP, OPEN,
1997 PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1998 PORTALLOCATOR_ENABLE_SHARED_SOCKET);
1999
2000 SetAllowTcpListen(0, false); // active.
2001 SetAllowTcpListen(1, true); // actpass.
2002 CreateChannels();
2003
2004 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2005 kMediumTimeout, clock);
2006 SIMULATED_WAIT(false, kDefaultTimeout, clock);
2007
2008 EXPECT_EQ(RemoteCandidate(ep1_ch1())->tcptype(), "passive");
2009 EXPECT_EQ(LocalCandidate(ep1_ch1())->tcptype(), "active");
2010 EXPECT_EQ(RemoteCandidate(ep2_ch1())->tcptype(), "active");
2011 EXPECT_EQ(LocalCandidate(ep2_ch1())->tcptype(), "passive");
2012
2013 DestroyChannels();
2014 }
2015
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIceRoleConflict)2016 TEST_P(P2PTransportChannelTestWithFieldTrials, TestIceRoleConflict) {
2017 AddAddress(0, kPublicAddrs[0]);
2018 AddAddress(1, kPublicAddrs[1]);
2019 TestSignalRoleConflict();
2020 }
2021
2022 // Tests that the ice configs (protocol, tiebreaker and role) can be passed
2023 // down to ports.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIceConfigWillPassDownToPort)2024 TEST_P(P2PTransportChannelTestWithFieldTrials,
2025 TestIceConfigWillPassDownToPort) {
2026 rtc::ScopedFakeClock clock;
2027 AddAddress(0, kPublicAddrs[0]);
2028 AddAddress(1, kPublicAddrs[1]);
2029
2030 // Give the first connection the higher tiebreaker so its role won't
2031 // change unless we tell it to.
2032 SetIceRole(0, ICEROLE_CONTROLLING);
2033 SetIceTiebreaker(0, kHighTiebreaker);
2034 SetIceRole(1, ICEROLE_CONTROLLING);
2035 SetIceTiebreaker(1, kLowTiebreaker);
2036
2037 CreateChannels();
2038
2039 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
2040
2041 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
2042 for (size_t i = 0; i < ports_before.size(); ++i) {
2043 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
2044 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
2045 }
2046
2047 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
2048 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
2049
2050 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
2051 for (size_t i = 0; i < ports_after.size(); ++i) {
2052 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
2053 // SetIceTiebreaker after ports have been created will fail. So expect the
2054 // original value.
2055 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
2056 }
2057
2058 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2059 kShortTimeout, clock);
2060
2061 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2062 ep2_ch1()->selected_connection());
2063
2064 TestSendRecv(&clock);
2065 DestroyChannels();
2066 }
2067
2068 // Verify that we can set DSCP value and retrieve properly from P2PTC.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestDefaultDscpValue)2069 TEST_P(P2PTransportChannelTestWithFieldTrials, TestDefaultDscpValue) {
2070 AddAddress(0, kPublicAddrs[0]);
2071 AddAddress(1, kPublicAddrs[1]);
2072
2073 CreateChannels();
2074 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
2075 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
2076 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
2077 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
2078 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
2079 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
2080 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
2081 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
2082 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
2083 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
2084 DestroyChannels();
2085 }
2086
2087 // Verify IPv6 connection is preferred over IPv4.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIPv6Connections)2088 TEST_P(P2PTransportChannelTestWithFieldTrials, TestIPv6Connections) {
2089 rtc::ScopedFakeClock clock;
2090 AddAddress(0, kIPv6PublicAddrs[0]);
2091 AddAddress(0, kPublicAddrs[0]);
2092 AddAddress(1, kIPv6PublicAddrs[1]);
2093 AddAddress(1, kPublicAddrs[1]);
2094
2095 SetAllocationStepDelay(0, kMinimumStepDelay);
2096 SetAllocationStepDelay(1, kMinimumStepDelay);
2097
2098 // Enable IPv6
2099 SetAllocatorFlags(
2100 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2101 SetAllocatorFlags(
2102 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2103
2104 CreateChannels();
2105
2106 EXPECT_TRUE_SIMULATED_WAIT(
2107 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kIPv6PublicAddrs[0],
2108 kIPv6PublicAddrs[1]),
2109 kShortTimeout, clock);
2110
2111 TestSendRecv(&clock);
2112 DestroyChannels();
2113 }
2114
2115 // Testing forceful TURN connections.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestForceTurn)2116 TEST_P(P2PTransportChannelTestWithFieldTrials, TestForceTurn) {
2117 rtc::ScopedFakeClock clock;
2118 ConfigureEndpoints(
2119 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
2120 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
2121 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
2122 set_force_relay(true);
2123
2124 SetAllocationStepDelay(0, kMinimumStepDelay);
2125 SetAllocationStepDelay(1, kMinimumStepDelay);
2126
2127 CreateChannels();
2128
2129 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2130 kMediumTimeout, clock);
2131
2132 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2133 ep2_ch1()->selected_connection());
2134
2135 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2136 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2137 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type());
2138 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type());
2139
2140 TestSendRecv(&clock);
2141 DestroyChannels();
2142 }
2143
2144 // Test that if continual gathering is set to true, ICE gathering state will
2145 // not change to "Complete", and vice versa.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestContinualGathering)2146 TEST_P(P2PTransportChannelTestWithFieldTrials, TestContinualGathering) {
2147 rtc::ScopedFakeClock clock;
2148 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2149 kDefaultPortAllocatorFlags);
2150 SetAllocationStepDelay(0, kDefaultStepDelay);
2151 SetAllocationStepDelay(1, kDefaultStepDelay);
2152 IceConfig continual_gathering_config =
2153 CreateIceConfig(1000, GATHER_CONTINUALLY);
2154 // By default, ep2 does not gather continually.
2155 IceConfig default_config;
2156 CreateChannels(continual_gathering_config, default_config);
2157
2158 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2159 kMediumTimeout, clock);
2160 SIMULATED_WAIT(
2161 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
2162 kShortTimeout, clock);
2163 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
2164 ep1_ch1()->gathering_state());
2165 // By now, ep2 should have completed gathering.
2166 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
2167 ep2_ch1()->gathering_state());
2168
2169 DestroyChannels();
2170 }
2171
2172 // Test that a connection succeeds when the P2PTransportChannel uses a pooled
2173 // PortAllocatorSession that has not yet finished gathering candidates.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestUsingPooledSessionBeforeDoneGathering)2174 TEST_P(P2PTransportChannelTestWithFieldTrials,
2175 TestUsingPooledSessionBeforeDoneGathering) {
2176 rtc::ScopedFakeClock clock;
2177 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2178 kDefaultPortAllocatorFlags);
2179 // First create a pooled session for each endpoint.
2180 auto& allocator_1 = GetEndpoint(0)->allocator_;
2181 auto& allocator_2 = GetEndpoint(1)->allocator_;
2182 int pool_size = 1;
2183 allocator_1->SetConfiguration(allocator_1->stun_servers(),
2184 allocator_1->turn_servers(), pool_size,
2185 webrtc::NO_PRUNE);
2186 allocator_2->SetConfiguration(allocator_2->stun_servers(),
2187 allocator_2->turn_servers(), pool_size,
2188 webrtc::NO_PRUNE);
2189 const PortAllocatorSession* pooled_session_1 =
2190 allocator_1->GetPooledSession();
2191 const PortAllocatorSession* pooled_session_2 =
2192 allocator_2->GetPooledSession();
2193 ASSERT_NE(nullptr, pooled_session_1);
2194 ASSERT_NE(nullptr, pooled_session_2);
2195 // Sanity check that pooled sessions haven't gathered anything yet.
2196 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
2197 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
2198 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
2199 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
2200 // Now let the endpoints connect and try exchanging some data.
2201 CreateChannels();
2202 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2203 kMediumTimeout, clock);
2204 TestSendRecv(&clock);
2205 // Make sure the P2PTransportChannels are actually using ports from the
2206 // pooled sessions.
2207 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2208 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
2209 EXPECT_THAT(pooled_ports_1,
2210 Contains(ep1_ch1()->selected_connection()->PortForTest()));
2211 EXPECT_THAT(pooled_ports_2,
2212 Contains(ep2_ch1()->selected_connection()->PortForTest()));
2213 DestroyChannels();
2214 }
2215
2216 // Test that a connection succeeds when the P2PTransportChannel uses a pooled
2217 // PortAllocatorSession that already finished gathering candidates.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestUsingPooledSessionAfterDoneGathering)2218 TEST_P(P2PTransportChannelTestWithFieldTrials,
2219 TestUsingPooledSessionAfterDoneGathering) {
2220 rtc::ScopedFakeClock clock;
2221 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2222 kDefaultPortAllocatorFlags);
2223 // First create a pooled session for each endpoint.
2224 auto& allocator_1 = GetEndpoint(0)->allocator_;
2225 auto& allocator_2 = GetEndpoint(1)->allocator_;
2226 int pool_size = 1;
2227 allocator_1->SetConfiguration(allocator_1->stun_servers(),
2228 allocator_1->turn_servers(), pool_size,
2229 webrtc::NO_PRUNE);
2230 allocator_2->SetConfiguration(allocator_2->stun_servers(),
2231 allocator_2->turn_servers(), pool_size,
2232 webrtc::NO_PRUNE);
2233 const PortAllocatorSession* pooled_session_1 =
2234 allocator_1->GetPooledSession();
2235 const PortAllocatorSession* pooled_session_2 =
2236 allocator_2->GetPooledSession();
2237 ASSERT_NE(nullptr, pooled_session_1);
2238 ASSERT_NE(nullptr, pooled_session_2);
2239 // Wait for the pooled sessions to finish gathering before the
2240 // P2PTransportChannels try to use them.
2241 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
2242 pooled_session_2->CandidatesAllocationDone(),
2243 kDefaultTimeout, clock);
2244 // Now let the endpoints connect and try exchanging some data.
2245 CreateChannels();
2246 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2247 kMediumTimeout, clock);
2248 TestSendRecv(&clock);
2249 // Make sure the P2PTransportChannels are actually using ports from the
2250 // pooled sessions.
2251 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2252 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
2253 EXPECT_THAT(pooled_ports_1,
2254 Contains(ep1_ch1()->selected_connection()->PortForTest()));
2255 EXPECT_THAT(pooled_ports_2,
2256 Contains(ep2_ch1()->selected_connection()->PortForTest()));
2257 DestroyChannels();
2258 }
2259
2260 // Test that when the "presume_writable_when_fully_relayed" flag is set to
2261 // true and there's a TURN-TURN candidate pair, it's presumed to be writable
2262 // as soon as it's created.
2263 // TODO(deadbeef): Move this and other "presumed writable" tests into a test
2264 // class that operates on a single P2PTransportChannel, once an appropriate one
2265 // (which supports TURN servers and TURN candidate gathering) is available.
TEST_P(P2PTransportChannelTestWithFieldTrials,TurnToTurnPresumedWritable)2266 TEST_P(P2PTransportChannelTestWithFieldTrials, TurnToTurnPresumedWritable) {
2267 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2268 kDefaultPortAllocatorFlags);
2269 // Only configure one channel so we can control when the remote candidate
2270 // is added.
2271 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
2272 kIceParams[0], kIceParams[1]);
2273 IceConfig config;
2274 config.presume_writable_when_fully_relayed = true;
2275 ep1_ch1()->SetIceConfig(config);
2276 ep1_ch1()->MaybeStartGathering();
2277 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2278 ep1_ch1()->gathering_state(), kDefaultTimeout);
2279 // Add two remote candidates; a host candidate (with higher priority)
2280 // and TURN candidate.
2281 ep1_ch1()->AddRemoteCandidate(
2282 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2283 ep1_ch1()->AddRemoteCandidate(
2284 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2285 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2286 // "probably writable".
2287 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout);
2288 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2289 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2290 // Also expect that the channel instantly indicates that it's writable since
2291 // it has a TURN-TURN pair.
2292 EXPECT_TRUE(ep1_ch1()->writable());
2293 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2294 // Also make sure we can immediately send packets.
2295 const char* data = "test";
2296 int len = static_cast<int>(strlen(data));
2297 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2298 // Prevent pending messages to access endpoints after their destruction.
2299 DestroyChannels();
2300 }
2301
2302 // Test that a TURN/peer reflexive candidate pair is also presumed writable.
TEST_P(P2PTransportChannelTestWithFieldTrials,TurnToPrflxPresumedWritable)2303 TEST_P(P2PTransportChannelTestWithFieldTrials, TurnToPrflxPresumedWritable) {
2304 rtc::ScopedFakeClock fake_clock;
2305
2306 // We need to add artificial network delay to verify that the connection
2307 // is presumed writable before it's actually writable. Without this delay
2308 // it would become writable instantly.
2309 virtual_socket_server()->set_delay_mean(50);
2310 virtual_socket_server()->UpdateDelayDistribution();
2311
2312 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2313 kDefaultPortAllocatorFlags);
2314 // We want the remote TURN candidate to show up as prflx. To do this we need
2315 // to configure the server to accept packets from an address we haven't
2316 // explicitly installed permission for.
2317 test_turn_server()->set_enable_permission_checks(false);
2318 IceConfig config;
2319 config.presume_writable_when_fully_relayed = true;
2320 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
2321 kIceParams[0], kIceParams[1]);
2322 GetEndpoint(1)->cd1_.ch_ = CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
2323 kIceParams[1], kIceParams[0]);
2324 ep1_ch1()->SetIceConfig(config);
2325 ep2_ch1()->SetIceConfig(config);
2326 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2327 // candidate as peer reflexive.
2328 PauseCandidates(1);
2329 ep1_ch1()->MaybeStartGathering();
2330 ep2_ch1()->MaybeStartGathering();
2331
2332 // Wait for the TURN<->prflx connection.
2333 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
2334 kShortTimeout, fake_clock);
2335 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2336 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2337 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2338 // Make sure that at this point the connection is only presumed writable,
2339 // not fully writable.
2340 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2341
2342 // Now wait for it to actually become writable.
2343 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2344 kShortTimeout, fake_clock);
2345
2346 // Explitly destroy channels, before fake clock is destroyed.
2347 DestroyChannels();
2348 }
2349
2350 // Test that a presumed-writable TURN<->TURN connection is preferred above an
2351 // unreliable connection (one that has failed to be pinged for some time).
TEST_P(P2PTransportChannelTestWithFieldTrials,PresumedWritablePreferredOverUnreliable)2352 TEST_P(P2PTransportChannelTestWithFieldTrials,
2353 PresumedWritablePreferredOverUnreliable) {
2354 rtc::ScopedFakeClock fake_clock;
2355
2356 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2357 kDefaultPortAllocatorFlags);
2358 IceConfig config;
2359 config.presume_writable_when_fully_relayed = true;
2360 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
2361 kIceParams[0], kIceParams[1]);
2362 GetEndpoint(1)->cd1_.ch_ = CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
2363 kIceParams[1], kIceParams[0]);
2364 ep1_ch1()->SetIceConfig(config);
2365 ep2_ch1()->SetIceConfig(config);
2366 ep1_ch1()->MaybeStartGathering();
2367 ep2_ch1()->MaybeStartGathering();
2368 // Wait for initial connection as usual.
2369 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2370 kShortTimeout, fake_clock);
2371 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
2372 // Destroy the second channel and wait for the current connection on the
2373 // first channel to become "unreliable", making it no longer writable.
2374 GetEndpoint(1)->cd1_.ch_.reset();
2375 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2376 fake_clock);
2377 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
2378 // Add a remote TURN candidate. The first channel should still have a TURN
2379 // port available to make a TURN<->TURN pair that's presumed writable.
2380 ep1_ch1()->AddRemoteCandidate(
2381 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2382 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2383 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2384 EXPECT_TRUE(ep1_ch1()->writable());
2385 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2386 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
2387 // Explitly destroy channels, before fake clock is destroyed.
2388 DestroyChannels();
2389 }
2390
2391 // Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2392 // writable" connection. Previously this did not work.
TEST_P(P2PTransportChannelTestWithFieldTrials,SignalReadyToSendWithPresumedWritable)2393 TEST_P(P2PTransportChannelTestWithFieldTrials,
2394 SignalReadyToSendWithPresumedWritable) {
2395 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2396 kDefaultPortAllocatorFlags);
2397 // Only test one endpoint, so we can ensure the connection doesn't receive a
2398 // binding response and advance beyond being "presumed" writable.
2399 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
2400 kIceParams[0], kIceParams[1]);
2401 IceConfig config;
2402 config.presume_writable_when_fully_relayed = true;
2403 ep1_ch1()->SetIceConfig(config);
2404 ep1_ch1()->MaybeStartGathering();
2405 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2406 ep1_ch1()->gathering_state(), kDefaultTimeout);
2407 ep1_ch1()->AddRemoteCandidate(
2408 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2409 // Sanity checking the type of the connection.
2410 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout);
2411 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2412 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2413
2414 // Tell the socket server to block packets (returning EWOULDBLOCK).
2415 virtual_socket_server()->SetSendingBlocked(true);
2416 const char* data = "test";
2417 int len = static_cast<int>(strlen(data));
2418 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2419
2420 // Reset `ready_to_send_` flag, which is set to true if the event fires as it
2421 // should.
2422 GetEndpoint(0)->ready_to_send_ = false;
2423 virtual_socket_server()->SetSendingBlocked(false);
2424 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2425 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2426 DestroyChannels();
2427 }
2428
2429 // Test that role conflict error responses are sent as expected when receiving a
2430 // ping from an unknown address over a TURN connection. Regression test for
2431 // crbug.com/webrtc/9034.
TEST_P(P2PTransportChannelTestWithFieldTrials,TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict)2432 TEST_P(P2PTransportChannelTestWithFieldTrials,
2433 TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict) {
2434 rtc::ScopedFakeClock clock;
2435 // Gather only relay candidates.
2436 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC,
2437 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2438 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP,
2439 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2440 PORTALLOCATOR_DISABLE_STUN |
2441 PORTALLOCATOR_DISABLE_TCP);
2442 // With conflicting ICE roles, endpoint 1 has the higher tie breaker and will
2443 // send a binding error response.
2444 SetIceRole(0, ICEROLE_CONTROLLING);
2445 SetIceTiebreaker(0, kHighTiebreaker);
2446 SetIceRole(1, ICEROLE_CONTROLLING);
2447 SetIceTiebreaker(1, kLowTiebreaker);
2448 // We want the remote TURN candidate to show up as prflx. To do this we need
2449 // to configure the server to accept packets from an address we haven't
2450 // explicitly installed permission for.
2451 test_turn_server()->set_enable_permission_checks(false);
2452 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
2453 kIceParams[0], kIceParams[1]);
2454 GetEndpoint(1)->cd1_.ch_ = CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
2455 kIceParams[1], kIceParams[0]);
2456 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2457 // candidate as peer reflexive.
2458 PauseCandidates(1);
2459 ep1_ch1()->MaybeStartGathering();
2460 ep2_ch1()->MaybeStartGathering();
2461
2462 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
2463 kMediumTimeout, clock);
2464
2465 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2466
2467 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2468 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2469
2470 DestroyChannels();
2471 }
2472
2473 // Test that the writability can be established with the piggyback
2474 // acknowledgement in the connectivity check from the remote peer.
TEST_P(P2PTransportChannelTestWithFieldTrials,CanConnectWithPiggybackCheckAcknowledgementWhenCheckResponseBlocked)2475 TEST_P(P2PTransportChannelTestWithFieldTrials,
2476 CanConnectWithPiggybackCheckAcknowledgementWhenCheckResponseBlocked) {
2477 webrtc::test::ScopedKeyValueConfig field_trials(
2478 field_trials_, "WebRTC-PiggybackIceCheckAcknowledgement/Enabled/");
2479 rtc::ScopedFakeClock clock;
2480 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
2481 IceConfig ep1_config;
2482 IceConfig ep2_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2483 // Let ep2 be tolerable of the loss of connectivity checks, so that it keeps
2484 // sending pings even after ep1 becomes unwritable as we configure the
2485 // firewall below.
2486 ep2_config.receiving_timeout = 30 * 1000;
2487 ep2_config.ice_unwritable_timeout = 30 * 1000;
2488 ep2_config.ice_unwritable_min_checks = 30;
2489 ep2_config.ice_inactive_timeout = 60 * 1000;
2490
2491 CreateChannels(ep1_config, ep2_config);
2492
2493 // Wait until both sides become writable for the first time.
2494 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2495 kDefaultTimeout, clock);
2496 // Block the ingress traffic to ep1 so that there is no check response from
2497 // ep2.
2498 ASSERT_NE(nullptr, LocalCandidate(ep1_ch1()));
2499 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_IN,
2500 LocalCandidate(ep1_ch1())->address());
2501 // Wait until ep1 becomes unwritable. At the same time ep2 should be still
2502 // fine so that it will keep sending pings.
2503 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && !ep1_ch1()->writable(),
2504 kDefaultTimeout, clock);
2505 EXPECT_TRUE(ep2_ch1() != nullptr && ep2_ch1()->writable());
2506 // Now let the pings from ep2 to flow but block any pings from ep1, so that
2507 // ep1 can only become writable again after receiving an incoming ping from
2508 // ep2 with piggyback acknowledgement of its previously sent pings. Note
2509 // though that ep1 should have stopped sending pings after becoming unwritable
2510 // in the current design.
2511 fw()->ClearRules();
2512 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_OUT,
2513 LocalCandidate(ep1_ch1())->address());
2514 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && ep1_ch1()->writable(),
2515 kDefaultTimeout, clock);
2516 DestroyChannels();
2517 }
2518
2519 // Test what happens when we have 2 users behind the same NAT. This can lead
2520 // to interesting behavior because the STUN server will only give out the
2521 // address of the outermost NAT.
2522 class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase,
2523 public WithParamInterface<std::string> {
2524 public:
P2PTransportChannelSameNatTest()2525 P2PTransportChannelSameNatTest() : P2PTransportChannelTestBase(GetParam()) {}
2526
2527 protected:
ConfigureEndpoints(Config nat_type,Config config1,Config config2)2528 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
2529 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2530 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
2531 rtc::NATSocketServer::Translator* outer_nat = nat()->AddTranslator(
2532 kPublicAddrs[0], kNatAddrs[0],
2533 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
2534 ConfigureEndpoint(outer_nat, 0, config1);
2535 ConfigureEndpoint(outer_nat, 1, config2);
2536 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
2537 }
ConfigureEndpoint(rtc::NATSocketServer::Translator * nat,int endpoint,Config config)2538 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
2539 int endpoint,
2540 Config config) {
2541 RTC_CHECK(config <= NAT_SYMMETRIC);
2542 if (config == OPEN) {
2543 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2544 nat->AddClient(kPrivateAddrs[endpoint]);
2545 } else {
2546 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2547 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
2548 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
2549 ->AddClient(kCascadedPrivateAddrs[endpoint]);
2550 }
2551 }
2552 };
2553
2554 INSTANTIATE_TEST_SUITE_P(Legacy, P2PTransportChannelSameNatTest, Values(""));
2555 INSTANTIATE_TEST_SUITE_P(Active,
2556 P2PTransportChannelSameNatTest,
2557 Values("WebRTC-UseActiveIceController/Enabled/"));
2558
TEST_P(P2PTransportChannelSameNatTest,TestConesBehindSameCone)2559 TEST_P(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2560 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
2561 Test(
2562 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
2563 }
2564
2565 // Test what happens when we have multiple available pathways.
2566 // In the future we will try different RTTs and configs for the different
2567 // interfaces, so that we can simulate a user with Ethernet and VPN networks.
2568 class P2PTransportChannelMultihomedTest
2569 : public P2PTransportChannelTestWithFieldTrials {
2570 public:
GetConnectionWithRemoteAddress(P2PTransportChannel * channel,const SocketAddress & address)2571 const Connection* GetConnectionWithRemoteAddress(
2572 P2PTransportChannel* channel,
2573 const SocketAddress& address) {
2574 for (Connection* conn : channel->connections()) {
2575 if (HasRemoteAddress(conn, address)) {
2576 return conn;
2577 }
2578 }
2579 return nullptr;
2580 }
2581
GetConnectionWithLocalAddress(P2PTransportChannel * channel,const SocketAddress & address)2582 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2583 const SocketAddress& address) {
2584 for (Connection* conn : channel->connections()) {
2585 if (HasLocalAddress(conn, address)) {
2586 return conn;
2587 }
2588 }
2589 return nullptr;
2590 }
2591
GetConnection(P2PTransportChannel * channel,const SocketAddress & local,const SocketAddress & remote)2592 Connection* GetConnection(P2PTransportChannel* channel,
2593 const SocketAddress& local,
2594 const SocketAddress& remote) {
2595 for (Connection* conn : channel->connections()) {
2596 if (HasLocalAddress(conn, local) && HasRemoteAddress(conn, remote)) {
2597 return conn;
2598 }
2599 }
2600 return nullptr;
2601 }
2602
GetBestConnection(P2PTransportChannel * channel)2603 Connection* GetBestConnection(P2PTransportChannel* channel) {
2604 rtc::ArrayView<Connection*> connections = channel->connections();
2605 auto it = absl::c_find(connections, channel->selected_connection());
2606 if (it == connections.end()) {
2607 return nullptr;
2608 }
2609 return *it;
2610 }
2611
GetBackupConnection(P2PTransportChannel * channel)2612 Connection* GetBackupConnection(P2PTransportChannel* channel) {
2613 rtc::ArrayView<Connection*> connections = channel->connections();
2614 auto it = absl::c_find_if_not(connections, [channel](Connection* conn) {
2615 return conn == channel->selected_connection();
2616 });
2617 if (it == connections.end()) {
2618 return nullptr;
2619 }
2620 return *it;
2621 }
2622
DestroyAllButBestConnection(P2PTransportChannel * channel)2623 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2624 const Connection* selected_connection = channel->selected_connection();
2625 // Copy the list of connections since the original will be modified.
2626 rtc::ArrayView<Connection*> view = channel->connections();
2627 std::vector<Connection*> connections(view.begin(), view.end());
2628 for (Connection* conn : connections) {
2629 if (conn != selected_connection)
2630 channel->RemoveConnectionForTest(conn);
2631 }
2632 }
2633 };
2634
2635 INSTANTIATE_TEST_SUITE_P(Legacy, P2PTransportChannelMultihomedTest, Values(""));
2636 INSTANTIATE_TEST_SUITE_P(Active,
2637 P2PTransportChannelMultihomedTest,
2638 Values("WebRTC-UseActiveIceController/Enabled/"));
2639
2640 // Test that we can establish connectivity when both peers are multihomed.
TEST_P(P2PTransportChannelMultihomedTest,TestBasic)2641 TEST_P(P2PTransportChannelMultihomedTest, TestBasic) {
2642 AddAddress(0, kPublicAddrs[0]);
2643 AddAddress(0, kAlternateAddrs[0]);
2644 AddAddress(1, kPublicAddrs[1]);
2645 AddAddress(1, kAlternateAddrs[1]);
2646 Test(kLocalUdpToLocalUdp);
2647 }
2648
2649 // Test that we can quickly switch links if an interface goes down.
2650 // The controlled side has two interfaces and one will die.
TEST_P(P2PTransportChannelMultihomedTest,TestFailoverControlledSide)2651 TEST_P(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
2652 rtc::ScopedFakeClock clock;
2653 AddAddress(0, kPublicAddrs[0]);
2654 // Simulate failing over from Wi-Fi to cell interface.
2655 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2656 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
2657
2658 // Use only local ports for simplicity.
2659 SetAllocatorFlags(0, kOnlyLocalPorts);
2660 SetAllocatorFlags(1, kOnlyLocalPorts);
2661
2662 // Make the receiving timeout shorter for testing.
2663 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2664 // Create channels and let them go writable, as usual.
2665 CreateChannels(config, config);
2666
2667 EXPECT_TRUE_SIMULATED_WAIT(
2668 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
2669 kPublicAddrs[1]),
2670 kMediumTimeout, clock);
2671
2672 // Blackhole any traffic to or from the public addrs.
2673 RTC_LOG(LS_INFO) << "Failing over...";
2674 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2675 // The selected connections may switch, so keep references to them.
2676 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2677 // We should detect loss of receiving within 1 second or so.
2678 EXPECT_TRUE_SIMULATED_WAIT(!selected_connection1->receiving(), kMediumTimeout,
2679 clock);
2680
2681 // We should switch over to use the alternate addr on both sides
2682 // when we are not receiving.
2683 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2684 ep2_ch1()->selected_connection()->receiving(),
2685 kMediumTimeout, clock);
2686 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2687 EXPECT_TRUE(
2688 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2689 EXPECT_TRUE(
2690 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2691
2692 DestroyChannels();
2693 }
2694
2695 // Test that we can quickly switch links if an interface goes down.
2696 // The controlling side has two interfaces and one will die.
TEST_P(P2PTransportChannelMultihomedTest,TestFailoverControllingSide)2697 TEST_P(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
2698 rtc::ScopedFakeClock clock;
2699 // Simulate failing over from Wi-Fi to cell interface.
2700 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2701 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
2702 AddAddress(1, kPublicAddrs[1]);
2703
2704 // Use only local ports for simplicity.
2705 SetAllocatorFlags(0, kOnlyLocalPorts);
2706 SetAllocatorFlags(1, kOnlyLocalPorts);
2707
2708 // Make the receiving timeout shorter for testing.
2709 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2710 // Create channels and let them go writable, as usual.
2711 CreateChannels(config, config);
2712 EXPECT_TRUE_SIMULATED_WAIT(
2713 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
2714 kPublicAddrs[1]),
2715 kMediumTimeout, clock);
2716
2717 // Blackhole any traffic to or from the public addrs.
2718 RTC_LOG(LS_INFO) << "Failing over...";
2719 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2720
2721 // We should detect loss of receiving within 1 second or so.
2722 // We should switch over to use the alternate addr on both sides
2723 // when we are not receiving.
2724 EXPECT_TRUE_SIMULATED_WAIT(
2725 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kAlternateAddrs[0],
2726 kPublicAddrs[1]),
2727 kMediumTimeout, clock);
2728
2729 DestroyChannels();
2730 }
2731
2732 // Tests that we can quickly switch links if an interface goes down when
2733 // there are many connections.
TEST_P(P2PTransportChannelMultihomedTest,TestFailoverWithManyConnections)2734 TEST_P(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2735 rtc::ScopedFakeClock clock;
2736 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
2737 RelayServerConfig turn_server;
2738 turn_server.credentials = kRelayCredentials;
2739 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
2740 GetAllocator(0)->AddTurnServerForTesting(turn_server);
2741 GetAllocator(1)->AddTurnServerForTesting(turn_server);
2742 // Enable IPv6
2743 SetAllocatorFlags(
2744 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2745 SetAllocatorFlags(
2746 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2747 SetAllocationStepDelay(0, kMinimumStepDelay);
2748 SetAllocationStepDelay(1, kMinimumStepDelay);
2749
2750 auto& wifi = kPublicAddrs;
2751 auto& cellular = kAlternateAddrs;
2752 auto& wifiIpv6 = kIPv6PublicAddrs;
2753 auto& cellularIpv6 = kIPv6AlternateAddrs;
2754 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2755 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2756 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2757 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2758 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2759 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2760 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2761 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2762
2763 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2764 // will be created in time.
2765 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2766 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2767 virtual_socket_server()->set_delay_mean(500);
2768 virtual_socket_server()->UpdateDelayDistribution();
2769
2770 // Make the receiving timeout shorter for testing.
2771 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2772 // Create channels and let them go writable, as usual.
2773 CreateChannels(config, config, true /* ice_renomination */);
2774 EXPECT_TRUE_SIMULATED_WAIT(
2775 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), wifiIpv6[0],
2776 wifiIpv6[1]),
2777 kMediumTimeout, clock);
2778
2779 // Blackhole any traffic to or from the wifi on endpoint 1.
2780 RTC_LOG(LS_INFO) << "Failing over...";
2781 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2782 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2783
2784 // The selected connections may switch, so keep references to them.
2785 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2786 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2787 EXPECT_TRUE_SIMULATED_WAIT(
2788 !selected_connection1->receiving() && !selected_connection2->receiving(),
2789 kMediumTimeout, clock);
2790
2791 // Per-network best connections will be pinged at relatively higher rate when
2792 // the selected connection becomes not receiving.
2793 Connection* per_network_best_connection1 =
2794 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2795 ASSERT_NE(nullptr, per_network_best_connection1);
2796 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2797 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2798 EXPECT_TRUE_SIMULATED_WAIT(
2799 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2800 kMediumTimeout, clock);
2801 ASSERT_GT(per_network_best_connection1->num_pings_sent() - num_pings_sent1,
2802 0);
2803 int64_t ping_interval1 =
2804 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2805 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2806 constexpr int SCHEDULING_DELAY = 200;
2807 EXPECT_LT(
2808 ping_interval1,
2809 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2810
2811 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2812 // it timed out on writing.
2813 EXPECT_TRUE_SIMULATED_WAIT(
2814 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), cellularIpv6[0],
2815 wifiIpv6[1]),
2816 kMediumTimeout, clock);
2817
2818 DestroyChannels();
2819 }
2820
2821 // Test that when the controlling side switches the selected connection,
2822 // the nomination of the selected connection on the controlled side will
2823 // increase.
TEST_P(P2PTransportChannelMultihomedTest,TestIceRenomination)2824 TEST_P(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2825 rtc::ScopedFakeClock clock;
2826 // Simulate failing over from Wi-Fi to cell interface.
2827 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2828 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
2829 AddAddress(1, kPublicAddrs[1]);
2830
2831 // Use only local ports for simplicity.
2832 SetAllocatorFlags(0, kOnlyLocalPorts);
2833 SetAllocatorFlags(1, kOnlyLocalPorts);
2834
2835 // We want it to set the remote ICE parameters when creating channels.
2836 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
2837 // Make the receiving timeout shorter for testing.
2838 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2839 // Create channels with ICE renomination and let them go writable as usual.
2840 CreateChannels(config, config, true);
2841 ASSERT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
2842 kMediumTimeout, clock);
2843 EXPECT_TRUE_SIMULATED_WAIT(
2844 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2845 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2846 kDefaultTimeout, clock);
2847 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2848 Connection* selected_connection2 =
2849 const_cast<Connection*>(ep2_ch1()->selected_connection());
2850 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2851 // `selected_connection2` should not be nominated any more since the previous
2852 // nomination has been acknowledged.
2853 ConnectSignalNominated(selected_connection2);
2854 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
2855 EXPECT_FALSE(nominated());
2856
2857 // Blackhole any traffic to or from the public addrs.
2858 RTC_LOG(LS_INFO) << "Failing over...";
2859 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2860
2861 // The selected connection on the controlling side should switch.
2862 EXPECT_TRUE_SIMULATED_WAIT(
2863 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2864 clock);
2865 // The connection on the controlled side should be nominated again
2866 // and have an increased nomination.
2867 EXPECT_TRUE_SIMULATED_WAIT(
2868 ep2_ch1()->selected_connection()->remote_nomination() >
2869 remote_nomination2,
2870 kDefaultTimeout, clock);
2871
2872 DestroyChannels();
2873 }
2874
2875 // Test that if an interface fails temporarily and then recovers quickly,
2876 // the selected connection will not switch.
2877 // The case that it will switch over to the backup connection if the selected
2878 // connection does not recover after enough time is covered in
2879 // TestFailoverControlledSide and TestFailoverControllingSide.
TEST_P(P2PTransportChannelMultihomedTest,TestConnectionSwitchDampeningControlledSide)2880 TEST_P(P2PTransportChannelMultihomedTest,
2881 TestConnectionSwitchDampeningControlledSide) {
2882 rtc::ScopedFakeClock clock;
2883 AddAddress(0, kPublicAddrs[0]);
2884 // Simulate failing over from Wi-Fi to cell interface.
2885 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2886 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
2887
2888 // Use only local ports for simplicity.
2889 SetAllocatorFlags(0, kOnlyLocalPorts);
2890 SetAllocatorFlags(1, kOnlyLocalPorts);
2891
2892 // Create channels and let them go writable, as usual.
2893 CreateChannels();
2894
2895 EXPECT_TRUE_SIMULATED_WAIT(
2896 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
2897 kPublicAddrs[1]),
2898 kMediumTimeout, clock);
2899
2900 // Make the receiving timeout shorter for testing.
2901 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2902 ep1_ch1()->SetIceConfig(config);
2903 ep2_ch1()->SetIceConfig(config);
2904 reset_selected_candidate_pair_switches();
2905
2906 // Blackhole any traffic to or from the public addrs.
2907 RTC_LOG(LS_INFO) << "Failing over...";
2908 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2909
2910 // The selected connections may switch, so keep references to them.
2911 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2912 // We should detect loss of receiving within 1 second or so.
2913 EXPECT_TRUE_SIMULATED_WAIT(!selected_connection1->receiving(), kMediumTimeout,
2914 clock);
2915 // After a short while, the link recovers itself.
2916 SIMULATED_WAIT(false, 10, clock);
2917 fw()->ClearRules();
2918
2919 // We should remain on the public address on both sides and no connection
2920 // switches should have happened.
2921 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2922 ep2_ch1()->selected_connection()->receiving(),
2923 kMediumTimeout, clock);
2924 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2925 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2926 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2927
2928 DestroyChannels();
2929 }
2930
2931 // Test that if an interface fails temporarily and then recovers quickly,
2932 // the selected connection will not switch.
TEST_P(P2PTransportChannelMultihomedTest,TestConnectionSwitchDampeningControllingSide)2933 TEST_P(P2PTransportChannelMultihomedTest,
2934 TestConnectionSwitchDampeningControllingSide) {
2935 rtc::ScopedFakeClock clock;
2936 // Simulate failing over from Wi-Fi to cell interface.
2937 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2938 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
2939 AddAddress(1, kPublicAddrs[1]);
2940
2941 // Use only local ports for simplicity.
2942 SetAllocatorFlags(0, kOnlyLocalPorts);
2943 SetAllocatorFlags(1, kOnlyLocalPorts);
2944
2945 // Create channels and let them go writable, as usual.
2946 CreateChannels();
2947 EXPECT_TRUE_SIMULATED_WAIT(
2948 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
2949 kPublicAddrs[1]),
2950 kMediumTimeout, clock);
2951
2952 // Make the receiving timeout shorter for testing.
2953 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2954 ep1_ch1()->SetIceConfig(config);
2955 ep2_ch1()->SetIceConfig(config);
2956 reset_selected_candidate_pair_switches();
2957
2958 // Blackhole any traffic to or from the public addrs.
2959 RTC_LOG(LS_INFO) << "Failing over...";
2960 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2961 // The selected connections may switch, so keep references to them.
2962 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2963 // We should detect loss of receiving within 1 second or so.
2964 EXPECT_TRUE_SIMULATED_WAIT(!selected_connection1->receiving(), kMediumTimeout,
2965 clock);
2966 // The link recovers after a short while.
2967 SIMULATED_WAIT(false, 10, clock);
2968 fw()->ClearRules();
2969
2970 // We should not switch to the alternate addr on both sides because of the
2971 // dampening.
2972 EXPECT_TRUE_SIMULATED_WAIT(
2973 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
2974 kPublicAddrs[1]),
2975 kMediumTimeout, clock);
2976 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2977 DestroyChannels();
2978 }
2979
2980 // Tests that if the remote side's network failed, it won't cause the local
2981 // side to switch connections and networks.
TEST_P(P2PTransportChannelMultihomedTest,TestRemoteFailover)2982 TEST_P(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2983 rtc::ScopedFakeClock clock;
2984 // The interface names are chosen so that `cellular` would have higher
2985 // candidate priority and higher cost.
2986 auto& wifi = kPublicAddrs;
2987 auto& cellular = kAlternateAddrs;
2988 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2989 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2990 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2991
2992 // Use only local ports for simplicity.
2993 SetAllocatorFlags(0, kOnlyLocalPorts);
2994 SetAllocatorFlags(1, kOnlyLocalPorts);
2995 // Create channels and let them go writable, as usual.
2996 CreateChannels();
2997 // Make the receiving timeout shorter for testing.
2998 // Set the backup connection ping interval to 25s.
2999 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
3000 // Ping the best connection more frequently since we don't have traffic.
3001 config.stable_writable_connection_ping_interval = 900;
3002 ep1_ch1()->SetIceConfig(config);
3003 ep2_ch1()->SetIceConfig(config);
3004 // Need to wait to make sure the connections on both networks are writable.
3005 EXPECT_TRUE_SIMULATED_WAIT(
3006 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), wifi[0], wifi[1]),
3007 kDefaultTimeout, clock);
3008 Connection* backup_conn =
3009 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
3010 ASSERT_NE(nullptr, backup_conn);
3011 // After a short while, the backup connection will be writable but not
3012 // receiving because backup connection is pinged at a slower rate.
3013 EXPECT_TRUE_SIMULATED_WAIT(
3014 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
3015 clock);
3016 reset_selected_candidate_pair_switches();
3017 // Blackhole any traffic to or from the remote WiFi networks.
3018 RTC_LOG(LS_INFO) << "Failing over...";
3019 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
3020
3021 int num_switches = 0;
3022 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
3023 20000, clock);
3024 EXPECT_EQ(0, num_switches);
3025 DestroyChannels();
3026 }
3027
3028 // Tests that a Wifi-Wifi connection has the highest precedence.
TEST_P(P2PTransportChannelMultihomedTest,TestPreferWifiToWifiConnection)3029 TEST_P(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
3030 // The interface names are chosen so that `cellular` would have higher
3031 // candidate priority if it is not for the network type.
3032 auto& wifi = kAlternateAddrs;
3033 auto& cellular = kPublicAddrs;
3034 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
3035 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
3036 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
3037 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
3038
3039 // Use only local ports for simplicity.
3040 SetAllocatorFlags(0, kOnlyLocalPorts);
3041 SetAllocatorFlags(1, kOnlyLocalPorts);
3042
3043 // Create channels and let them go writable, as usual.
3044 CreateChannels();
3045
3046 EXPECT_TRUE_WAIT_MARGIN(CheckConnected(ep1_ch1(), ep2_ch1()), 1000, 1000);
3047 // Need to wait to make sure the connections on both networks are writable.
3048 EXPECT_TRUE_WAIT(
3049 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), wifi[0], wifi[1]),
3050 1000);
3051 DestroyChannels();
3052 }
3053
3054 // Tests that a Wifi-Cellular connection has higher precedence than
3055 // a Cellular-Cellular connection.
TEST_P(P2PTransportChannelMultihomedTest,TestPreferWifiOverCellularNetwork)3056 TEST_P(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
3057 // The interface names are chosen so that `cellular` would have higher
3058 // candidate priority if it is not for the network type.
3059 auto& wifi = kAlternateAddrs;
3060 auto& cellular = kPublicAddrs;
3061 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
3062 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
3063 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
3064
3065 // Use only local ports for simplicity.
3066 SetAllocatorFlags(0, kOnlyLocalPorts);
3067 SetAllocatorFlags(1, kOnlyLocalPorts);
3068
3069 // Create channels and let them go writable, as usual.
3070 CreateChannels();
3071
3072 EXPECT_TRUE_WAIT_MARGIN(CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(),
3073 cellular[0], wifi[1]),
3074 1000, 1000);
3075 DestroyChannels();
3076 }
3077
3078 // Test that the backup connection is pinged at a rate no faster than
3079 // what was configured.
TEST_P(P2PTransportChannelMultihomedTest,TestPingBackupConnectionRate)3080 TEST_P(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
3081 AddAddress(0, kPublicAddrs[0]);
3082 // Adding alternate address will make sure `kPublicAddrs` has the higher
3083 // priority than others. This is due to FakeNetwork::AddInterface method.
3084 AddAddress(1, kAlternateAddrs[1]);
3085 AddAddress(1, kPublicAddrs[1]);
3086
3087 // Use only local ports for simplicity.
3088 SetAllocatorFlags(0, kOnlyLocalPorts);
3089 SetAllocatorFlags(1, kOnlyLocalPorts);
3090
3091 // Create channels and let them go writable, as usual.
3092 CreateChannels();
3093 EXPECT_TRUE_WAIT_MARGIN(CheckConnected(ep1_ch1(), ep2_ch1()), 1000, 1000);
3094 int backup_ping_interval = 2000;
3095 ep2_ch1()->SetIceConfig(
3096 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
3097 // After the state becomes COMPLETED, the backup connection will be pinged
3098 // once every `backup_ping_interval` milliseconds.
3099 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
3100 1000);
3101 auto connections = ep2_ch1()->connections();
3102 ASSERT_EQ(2U, connections.size());
3103 Connection* backup_conn = GetBackupConnection(ep2_ch1());
3104 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
3105 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
3106 EXPECT_TRUE_WAIT(
3107 last_ping_response_ms < backup_conn->last_ping_response_received(),
3108 kDefaultTimeout);
3109 int time_elapsed =
3110 backup_conn->last_ping_response_received() - last_ping_response_ms;
3111 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
3112 EXPECT_GE(time_elapsed, backup_ping_interval);
3113
3114 DestroyChannels();
3115 }
3116
3117 // Test that the connection is pinged at a rate no faster than
3118 // what was configured when stable and writable.
TEST_P(P2PTransportChannelMultihomedTest,TestStableWritableRate)3119 TEST_P(P2PTransportChannelMultihomedTest, TestStableWritableRate) {
3120 AddAddress(0, kPublicAddrs[0]);
3121 // Adding alternate address will make sure `kPublicAddrs` has the higher
3122 // priority than others. This is due to FakeNetwork::AddInterface method.
3123 AddAddress(1, kAlternateAddrs[1]);
3124 AddAddress(1, kPublicAddrs[1]);
3125
3126 // Use only local ports for simplicity.
3127 SetAllocatorFlags(0, kOnlyLocalPorts);
3128 SetAllocatorFlags(1, kOnlyLocalPorts);
3129
3130 // Create channels and let them go writable, as usual.
3131 CreateChannels();
3132 EXPECT_TRUE_WAIT_MARGIN(CheckConnected(ep1_ch1(), ep2_ch1()), 1000, 1000);
3133 // Set a value larger than the default value of 2500 ms
3134 int ping_interval_ms = 3456;
3135 IceConfig config = CreateIceConfig(2 * ping_interval_ms, GATHER_ONCE);
3136 config.stable_writable_connection_ping_interval = ping_interval_ms;
3137 ep2_ch1()->SetIceConfig(config);
3138 // After the state becomes COMPLETED and is stable and writable, the
3139 // connection will be pinged once every `ping_interval_ms` milliseconds.
3140 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
3141 1000);
3142 auto connections = ep2_ch1()->connections();
3143 ASSERT_EQ(2U, connections.size());
3144 Connection* conn = GetBestConnection(ep2_ch1());
3145 EXPECT_TRUE_WAIT(conn->writable(), kMediumTimeout);
3146
3147 int64_t last_ping_response_ms;
3148 // Burn through some pings so the connection is stable.
3149 for (int i = 0; i < 5; i++) {
3150 last_ping_response_ms = conn->last_ping_response_received();
3151 EXPECT_TRUE_WAIT(
3152 last_ping_response_ms < conn->last_ping_response_received(),
3153 kDefaultTimeout);
3154 }
3155 EXPECT_TRUE(conn->stable(last_ping_response_ms)) << "Connection not stable";
3156 int time_elapsed =
3157 conn->last_ping_response_received() - last_ping_response_ms;
3158 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
3159 EXPECT_GE(time_elapsed, ping_interval_ms);
3160
3161 DestroyChannels();
3162 }
3163
TEST_P(P2PTransportChannelMultihomedTest,TestGetState)3164 TEST_P(P2PTransportChannelMultihomedTest, TestGetState) {
3165 rtc::ScopedFakeClock clock;
3166 AddAddress(0, kAlternateAddrs[0]);
3167 AddAddress(0, kPublicAddrs[0]);
3168 AddAddress(1, kPublicAddrs[1]);
3169 // Create channels and let them go writable, as usual.
3170 CreateChannels();
3171
3172 // Both transport channels will reach STATE_COMPLETED quickly.
3173 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
3174 ep1_ch1()->GetState(), kShortTimeout, clock);
3175 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
3176 ep2_ch1()->GetState(), kShortTimeout, clock);
3177 DestroyChannels();
3178 }
3179
3180 // Tests that when a network interface becomes inactive, if Continual Gathering
3181 // policy is GATHER_CONTINUALLY, the ports associated with that network
3182 // will be removed from the port list of the channel, and the respective
3183 // remote candidates on the other participant will be removed eventually.
TEST_P(P2PTransportChannelMultihomedTest,TestNetworkBecomesInactive)3184 TEST_P(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
3185 rtc::ScopedFakeClock clock;
3186 AddAddress(0, kPublicAddrs[0]);
3187 AddAddress(1, kPublicAddrs[1]);
3188 // Create channels and let them go writable, as usual.
3189 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
3190 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
3191 CreateChannels(ep1_config, ep2_config);
3192
3193 SetAllocatorFlags(0, kOnlyLocalPorts);
3194 SetAllocatorFlags(1, kOnlyLocalPorts);
3195 ASSERT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
3196 kDefaultTimeout, clock);
3197 // More than one port has been created.
3198 EXPECT_LE(1U, ep1_ch1()->ports().size());
3199 // Endpoint 1 enabled continual gathering; the port will be removed
3200 // when the interface is removed.
3201 RemoveAddress(0, kPublicAddrs[0]);
3202 EXPECT_TRUE(ep1_ch1()->ports().empty());
3203 // The remote candidates will be removed eventually.
3204 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
3205 clock);
3206
3207 size_t num_ports = ep2_ch1()->ports().size();
3208 EXPECT_LE(1U, num_ports);
3209 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
3210 // Endpoint 2 did not enable continual gathering; the local port will still be
3211 // removed when the interface is removed but the remote candidates on the
3212 // other participant will not be removed.
3213 RemoveAddress(1, kPublicAddrs[1]);
3214
3215 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
3216 clock);
3217 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
3218 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
3219
3220 DestroyChannels();
3221 }
3222
3223 // Tests that continual gathering will create new connections when a new
3224 // interface is added.
TEST_P(P2PTransportChannelMultihomedTest,TestContinualGatheringOnNewInterface)3225 TEST_P(P2PTransportChannelMultihomedTest,
3226 TestContinualGatheringOnNewInterface) {
3227 auto& wifi = kAlternateAddrs;
3228 auto& cellular = kPublicAddrs;
3229 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3230 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3231 // Set continual gathering policy.
3232 IceConfig continual_gathering_config =
3233 CreateIceConfig(1000, GATHER_CONTINUALLY);
3234 CreateChannels(continual_gathering_config, continual_gathering_config);
3235 SetAllocatorFlags(0, kOnlyLocalPorts);
3236 SetAllocatorFlags(1, kOnlyLocalPorts);
3237 EXPECT_TRUE_WAIT_MARGIN(CheckConnected(ep1_ch1(), ep2_ch1()), kDefaultTimeout,
3238 kDefaultTimeout);
3239
3240 // Add a new wifi interface on end point 2. We should expect a new connection
3241 // to be created and the new one will be the best connection.
3242 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3243 const Connection* conn;
3244 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
3245 HasRemoteAddress(conn, wifi[1]),
3246 kDefaultTimeout);
3247 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
3248 HasLocalAddress(conn, wifi[1]),
3249 kDefaultTimeout);
3250
3251 // Add a new cellular interface on end point 1, we should expect a new
3252 // backup connection created using this new interface.
3253 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
3254 EXPECT_TRUE_WAIT(
3255 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
3256 absl::c_any_of(ep1_ch1()->connections(),
3257 [channel = ep1_ch1(),
3258 address = cellular[0]](const Connection* conn) {
3259 return HasLocalAddress(conn, address) &&
3260 conn != channel->selected_connection() &&
3261 conn->writable();
3262 }),
3263 kDefaultTimeout);
3264 EXPECT_TRUE_WAIT(
3265 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
3266 absl::c_any_of(ep2_ch1()->connections(),
3267 [channel = ep2_ch1(),
3268 address = cellular[0]](const Connection* conn) {
3269 return HasRemoteAddress(conn, address) &&
3270 conn != channel->selected_connection() &&
3271 conn->receiving();
3272 }),
3273 kDefaultTimeout);
3274
3275 DestroyChannels();
3276 }
3277
3278 // Tests that we can switch links via continual gathering.
TEST_P(P2PTransportChannelMultihomedTest,TestSwitchLinksViaContinualGathering)3279 TEST_P(P2PTransportChannelMultihomedTest,
3280 TestSwitchLinksViaContinualGathering) {
3281 rtc::ScopedFakeClock clock;
3282 AddAddress(0, kPublicAddrs[0]);
3283 AddAddress(1, kPublicAddrs[1]);
3284 // Use only local ports for simplicity.
3285 SetAllocatorFlags(0, kOnlyLocalPorts);
3286 SetAllocatorFlags(1, kOnlyLocalPorts);
3287
3288 // Set continual gathering policy.
3289 IceConfig continual_gathering_config =
3290 CreateIceConfig(1000, GATHER_CONTINUALLY);
3291 // Create channels and let them go writable, as usual.
3292 CreateChannels(continual_gathering_config, continual_gathering_config);
3293 EXPECT_TRUE_SIMULATED_WAIT(
3294 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
3295 kPublicAddrs[1]),
3296 kMediumTimeout, clock);
3297
3298 // Add the new address first and then remove the other one.
3299 RTC_LOG(LS_INFO) << "Draining...";
3300 AddAddress(1, kAlternateAddrs[1]);
3301 RemoveAddress(1, kPublicAddrs[1]);
3302 // We should switch to use the alternate address after an exchange of pings.
3303 EXPECT_TRUE_SIMULATED_WAIT(
3304 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
3305 kAlternateAddrs[1]),
3306 kMediumTimeout, clock);
3307
3308 // Remove one address first and then add another address.
3309 RTC_LOG(LS_INFO) << "Draining again...";
3310 RemoveAddress(1, kAlternateAddrs[1]);
3311 AddAddress(1, kAlternateAddrs[0]);
3312 EXPECT_TRUE_SIMULATED_WAIT(
3313 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), kPublicAddrs[0],
3314 kAlternateAddrs[0]),
3315 kMediumTimeout, clock);
3316
3317 DestroyChannels();
3318 }
3319
3320 // Tests that the backup connection will be restored after it is destroyed.
TEST_P(P2PTransportChannelMultihomedTest,TestRestoreBackupConnection)3321 TEST_P(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3322 rtc::ScopedFakeClock clock;
3323 auto& wifi = kAlternateAddrs;
3324 auto& cellular = kPublicAddrs;
3325 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3326 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3327 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3328 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3329 // Use only local ports for simplicity.
3330 SetAllocatorFlags(0, kOnlyLocalPorts);
3331 SetAllocatorFlags(1, kOnlyLocalPorts);
3332
3333 // Create channels and let them go writable, as usual.
3334 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
3335 config.regather_on_failed_networks_interval = 2000;
3336 CreateChannels(config, config);
3337 EXPECT_TRUE_SIMULATED_WAIT(
3338 CheckCandidatePairAndConnected(ep1_ch1(), ep2_ch1(), wifi[0], wifi[1]),
3339 kMediumTimeout, clock);
3340
3341 // Destroy all backup connections.
3342 DestroyAllButBestConnection(ep1_ch1());
3343 // Ensure the backup connection is removed first.
3344 EXPECT_TRUE_SIMULATED_WAIT(
3345 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3346 kDefaultTimeout, clock);
3347 const Connection* conn;
3348 EXPECT_TRUE_SIMULATED_WAIT(
3349 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3350 nullptr &&
3351 conn != ep1_ch1()->selected_connection() && conn->writable(),
3352 kDefaultTimeout, clock);
3353
3354 DestroyChannels();
3355 }
3356
TEST_P(P2PTransportChannelMultihomedTest,TestVpnDefault)3357 TEST_P(P2PTransportChannelMultihomedTest, TestVpnDefault) {
3358 rtc::ScopedFakeClock clock;
3359 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_ETHERNET);
3360 AddAddress(0, kAlternateAddrs[0], "vpn0", rtc::ADAPTER_TYPE_VPN);
3361 AddAddress(1, kPublicAddrs[1]);
3362
3363 IceConfig config;
3364 CreateChannels(config, config, false);
3365 EXPECT_TRUE_SIMULATED_WAIT(
3366 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3367 !ep1_ch1()->selected_connection()->network()->IsVpn(),
3368 kDefaultTimeout, clock);
3369 }
3370
TEST_P(P2PTransportChannelMultihomedTest,TestVpnPreferVpn)3371 TEST_P(P2PTransportChannelMultihomedTest, TestVpnPreferVpn) {
3372 rtc::ScopedFakeClock clock;
3373 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_ETHERNET);
3374 AddAddress(0, kAlternateAddrs[0], "vpn0", rtc::ADAPTER_TYPE_VPN,
3375 rtc::ADAPTER_TYPE_CELLULAR);
3376 AddAddress(1, kPublicAddrs[1]);
3377
3378 IceConfig config;
3379 config.vpn_preference = webrtc::VpnPreference::kPreferVpn;
3380 RTC_LOG(LS_INFO) << "KESO: config.vpn_preference: " << config.vpn_preference;
3381 CreateChannels(config, config, false);
3382 EXPECT_TRUE_SIMULATED_WAIT(
3383 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3384 ep1_ch1()->selected_connection()->network()->IsVpn(),
3385 kDefaultTimeout, clock);
3386
3387 // Block VPN.
3388 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kAlternateAddrs[0]);
3389
3390 // Check that it switches to non-VPN
3391 EXPECT_TRUE_SIMULATED_WAIT(
3392 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3393 !ep1_ch1()->selected_connection()->network()->IsVpn(),
3394 kDefaultTimeout, clock);
3395 }
3396
TEST_P(P2PTransportChannelMultihomedTest,TestVpnAvoidVpn)3397 TEST_P(P2PTransportChannelMultihomedTest, TestVpnAvoidVpn) {
3398 rtc::ScopedFakeClock clock;
3399 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_CELLULAR);
3400 AddAddress(0, kAlternateAddrs[0], "vpn0", rtc::ADAPTER_TYPE_VPN,
3401 rtc::ADAPTER_TYPE_ETHERNET);
3402 AddAddress(1, kPublicAddrs[1]);
3403
3404 IceConfig config;
3405 config.vpn_preference = webrtc::VpnPreference::kAvoidVpn;
3406 CreateChannels(config, config, false);
3407 EXPECT_TRUE_SIMULATED_WAIT(
3408 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3409 !ep1_ch1()->selected_connection()->network()->IsVpn(),
3410 kDefaultTimeout, clock);
3411
3412 // Block non-VPN.
3413 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
3414
3415 // Check that it switches to VPN
3416 EXPECT_TRUE_SIMULATED_WAIT(
3417 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3418 ep1_ch1()->selected_connection()->network()->IsVpn(),
3419 kDefaultTimeout, clock);
3420 }
3421
TEST_P(P2PTransportChannelMultihomedTest,TestVpnNeverVpn)3422 TEST_P(P2PTransportChannelMultihomedTest, TestVpnNeverVpn) {
3423 rtc::ScopedFakeClock clock;
3424 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_CELLULAR);
3425 AddAddress(0, kAlternateAddrs[0], "vpn0", rtc::ADAPTER_TYPE_VPN,
3426 rtc::ADAPTER_TYPE_ETHERNET);
3427 AddAddress(1, kPublicAddrs[1]);
3428
3429 IceConfig config;
3430 config.vpn_preference = webrtc::VpnPreference::kNeverUseVpn;
3431 CreateChannels(config, config, false);
3432 EXPECT_TRUE_SIMULATED_WAIT(
3433 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3434 !ep1_ch1()->selected_connection()->network()->IsVpn(),
3435 kDefaultTimeout, clock);
3436
3437 // Block non-VPN.
3438 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
3439
3440 // Check that it does not switches to VPN
3441 clock.AdvanceTime(webrtc::TimeDelta::Millis(kDefaultTimeout));
3442 EXPECT_TRUE_SIMULATED_WAIT(!CheckConnected(ep1_ch1(), ep2_ch1()),
3443 kDefaultTimeout, clock);
3444 }
3445
TEST_P(P2PTransportChannelMultihomedTest,TestVpnOnlyVpn)3446 TEST_P(P2PTransportChannelMultihomedTest, TestVpnOnlyVpn) {
3447 rtc::ScopedFakeClock clock;
3448 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_CELLULAR);
3449 AddAddress(0, kAlternateAddrs[0], "vpn0", rtc::ADAPTER_TYPE_VPN,
3450 rtc::ADAPTER_TYPE_ETHERNET);
3451 AddAddress(1, kPublicAddrs[1]);
3452
3453 IceConfig config;
3454 config.vpn_preference = webrtc::VpnPreference::kOnlyUseVpn;
3455 CreateChannels(config, config, false);
3456 EXPECT_TRUE_SIMULATED_WAIT(
3457 CheckConnected(ep1_ch1(), ep2_ch1()) &&
3458 ep1_ch1()->selected_connection()->network()->IsVpn(),
3459 kDefaultTimeout, clock);
3460
3461 // Block VPN.
3462 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kAlternateAddrs[0]);
3463
3464 // Check that it does not switch to non-VPN
3465 clock.AdvanceTime(webrtc::TimeDelta::Millis(kDefaultTimeout));
3466 EXPECT_TRUE_SIMULATED_WAIT(!CheckConnected(ep1_ch1(), ep2_ch1()),
3467 kDefaultTimeout, clock);
3468 }
3469
3470 // A collection of tests which tests a single P2PTransportChannel by sending
3471 // pings.
3472 class P2PTransportChannelPingTest : public TestWithParam<std::string>,
3473 public sigslot::has_slots<> {
3474 public:
P2PTransportChannelPingTest()3475 P2PTransportChannelPingTest()
3476 : field_trials_(GetParam()),
3477 vss_(std::make_unique<rtc::VirtualSocketServer>()),
3478 packet_socket_factory_(
3479 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get())),
3480 thread_(vss_.get()) {}
3481
3482 protected:
PrepareChannel(P2PTransportChannel * ch)3483 void PrepareChannel(P2PTransportChannel* ch) {
3484 ch->SetIceRole(ICEROLE_CONTROLLING);
3485 ch->SetIceTiebreaker(kTiebreakerDefault);
3486 ch->SetIceParameters(kIceParams[0]);
3487 ch->SetRemoteIceParameters(kIceParams[1]);
3488 ch->SignalNetworkRouteChanged.connect(
3489 this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
3490 ch->SignalReadyToSend.connect(this,
3491 &P2PTransportChannelPingTest::OnReadyToSend);
3492 ch->SignalStateChanged.connect(
3493 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
3494 ch->SignalCandidatePairChanged.connect(
3495 this, &P2PTransportChannelPingTest::OnCandidatePairChanged);
3496 }
3497
WaitForConnectionTo(P2PTransportChannel * ch,absl::string_view ip,int port_num,rtc::ThreadProcessingFakeClock * clock=nullptr)3498 Connection* WaitForConnectionTo(
3499 P2PTransportChannel* ch,
3500 absl::string_view ip,
3501 int port_num,
3502 rtc::ThreadProcessingFakeClock* clock = nullptr) {
3503 if (clock == nullptr) {
3504 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3505 kMediumTimeout);
3506 } else {
3507 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3508 kMediumTimeout, *clock);
3509 }
3510 return GetConnectionTo(ch, ip, port_num);
3511 }
3512
GetPort(P2PTransportChannel * ch)3513 Port* GetPort(P2PTransportChannel* ch) {
3514 if (ch->ports().empty()) {
3515 return nullptr;
3516 }
3517 return static_cast<Port*>(ch->ports()[0]);
3518 }
3519
GetPrunedPort(P2PTransportChannel * ch)3520 Port* GetPrunedPort(P2PTransportChannel* ch) {
3521 if (ch->pruned_ports().empty()) {
3522 return nullptr;
3523 }
3524 return static_cast<Port*>(ch->pruned_ports()[0]);
3525 }
3526
GetConnectionTo(P2PTransportChannel * ch,absl::string_view ip,int port_num)3527 Connection* GetConnectionTo(P2PTransportChannel* ch,
3528 absl::string_view ip,
3529 int port_num) {
3530 Port* port = GetPort(ch);
3531 if (!port) {
3532 return nullptr;
3533 }
3534 return port->GetConnection(rtc::SocketAddress(ip, port_num));
3535 }
3536
FindNextPingableConnectionAndPingIt(P2PTransportChannel * ch)3537 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3538 Connection* conn = ch->FindNextPingableConnection();
3539 if (conn) {
3540 ch->MarkConnectionPinged(conn);
3541 }
3542 return conn;
3543 }
3544
SendData(IceTransportInternal * channel,const char * data,size_t len,int packet_id)3545 int SendData(IceTransportInternal* channel,
3546 const char* data,
3547 size_t len,
3548 int packet_id) {
3549 rtc::PacketOptions options;
3550 options.packet_id = packet_id;
3551 return channel->SendPacket(data, len, options, 0);
3552 }
3553
CreateConnectionWithCandidate(P2PTransportChannel * channel,rtc::ScopedFakeClock * clock,absl::string_view ip_addr,int port,int priority,bool writable)3554 Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
3555 rtc::ScopedFakeClock* clock,
3556 absl::string_view ip_addr,
3557 int port,
3558 int priority,
3559 bool writable) {
3560 channel->AddRemoteCandidate(
3561 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3562 EXPECT_TRUE_SIMULATED_WAIT(
3563 GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
3564 *clock);
3565 Connection* conn = GetConnectionTo(channel, ip_addr, port);
3566
3567 if (conn && writable) {
3568 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
3569 }
3570 return conn;
3571 }
3572
NominateConnection(Connection * conn,uint32_t remote_nomination=1U)3573 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3574 conn->set_remote_nomination(remote_nomination);
3575 conn->SignalNominated(conn);
3576 }
3577
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)3578 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
3579 last_network_route_ = network_route;
3580 if (last_network_route_) {
3581 last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
3582 }
3583 ++selected_candidate_pair_switches_;
3584 }
3585
ReceivePingOnConnection(Connection * conn,absl::string_view remote_ufrag,int priority,uint32_t nomination,const absl::optional<std::string> & piggyback_ping_id)3586 void ReceivePingOnConnection(
3587 Connection* conn,
3588 absl::string_view remote_ufrag,
3589 int priority,
3590 uint32_t nomination,
3591 const absl::optional<std::string>& piggyback_ping_id) {
3592 IceMessage msg(STUN_BINDING_REQUEST);
3593 msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
3594 STUN_ATTR_USERNAME,
3595 conn->local_candidate().username() + ":" + std::string(remote_ufrag)));
3596 msg.AddAttribute(
3597 std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
3598 if (nomination != 0) {
3599 msg.AddAttribute(std::make_unique<StunUInt32Attribute>(
3600 STUN_ATTR_NOMINATION, nomination));
3601 }
3602 if (piggyback_ping_id) {
3603 msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
3604 STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED, piggyback_ping_id.value()));
3605 }
3606 msg.AddMessageIntegrity(conn->local_candidate().password());
3607 msg.AddFingerprint();
3608 rtc::ByteBufferWriter buf;
3609 msg.Write(&buf);
3610 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::TimeMicros());
3611 }
3612
ReceivePingOnConnection(Connection * conn,absl::string_view remote_ufrag,int priority,uint32_t nomination=0)3613 void ReceivePingOnConnection(Connection* conn,
3614 absl::string_view remote_ufrag,
3615 int priority,
3616 uint32_t nomination = 0) {
3617 ReceivePingOnConnection(conn, remote_ufrag, priority, nomination,
3618 absl::nullopt);
3619 }
3620
OnReadyToSend(rtc::PacketTransportInternal * transport)3621 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
3622 channel_ready_to_send_ = true;
3623 }
OnChannelStateChanged(IceTransportInternal * channel)3624 void OnChannelStateChanged(IceTransportInternal* channel) {
3625 channel_state_ = channel->GetState();
3626 }
OnCandidatePairChanged(const CandidatePairChangeEvent & event)3627 void OnCandidatePairChanged(const CandidatePairChangeEvent& event) {
3628 last_candidate_change_event_ = event;
3629 }
3630
last_sent_packet_id()3631 int last_sent_packet_id() { return last_sent_packet_id_; }
channel_ready_to_send()3632 bool channel_ready_to_send() { return channel_ready_to_send_; }
reset_channel_ready_to_send()3633 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
channel_state()3634 IceTransportState channel_state() { return channel_state_; }
reset_selected_candidate_pair_switches()3635 int reset_selected_candidate_pair_switches() {
3636 int switches = selected_candidate_pair_switches_;
3637 selected_candidate_pair_switches_ = 0;
3638 return switches;
3639 }
3640
3641 // Return true if the `pair` matches the last network route.
CandidatePairMatchesNetworkRoute(CandidatePairInterface * pair)3642 bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
3643 if (!pair) {
3644 return !last_network_route_.has_value();
3645 } else {
3646 return pair->local_candidate().network_id() ==
3647 last_network_route_->local.network_id() &&
3648 pair->remote_candidate().network_id() ==
3649 last_network_route_->remote.network_id();
3650 }
3651 }
3652
ConnectionMatchesChangeEvent(Connection * conn,absl::string_view reason)3653 bool ConnectionMatchesChangeEvent(Connection* conn,
3654 absl::string_view reason) {
3655 if (!conn) {
3656 return !last_candidate_change_event_.has_value();
3657 } else {
3658 const auto& last_selected_pair =
3659 last_candidate_change_event_->selected_candidate_pair;
3660 return last_selected_pair.local_candidate().IsEquivalent(
3661 conn->local_candidate()) &&
3662 last_selected_pair.remote_candidate().IsEquivalent(
3663 conn->remote_candidate()) &&
3664 last_candidate_change_event_->last_data_received_ms ==
3665 conn->last_data_received() &&
3666 last_candidate_change_event_->reason == reason;
3667 }
3668 }
3669
LastEstimatedDisconnectedTimeMs() const3670 int64_t LastEstimatedDisconnectedTimeMs() const {
3671 if (!last_candidate_change_event_.has_value()) {
3672 return 0;
3673 } else {
3674 return last_candidate_change_event_->estimated_disconnected_time_ms;
3675 }
3676 }
3677
ss() const3678 rtc::SocketServer* ss() const { return vss_.get(); }
3679
packet_socket_factory() const3680 rtc::PacketSocketFactory* packet_socket_factory() const {
3681 return packet_socket_factory_.get();
3682 }
3683
3684 webrtc::test::ScopedKeyValueConfig field_trials_;
3685
3686 private:
3687 std::unique_ptr<rtc::VirtualSocketServer> vss_;
3688 std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory_;
3689 rtc::AutoSocketServerThread thread_;
3690 int selected_candidate_pair_switches_ = 0;
3691 int last_sent_packet_id_ = -1;
3692 bool channel_ready_to_send_ = false;
3693 absl::optional<CandidatePairChangeEvent> last_candidate_change_event_;
3694 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
3695 absl::optional<rtc::NetworkRoute> last_network_route_;
3696 };
3697
3698 INSTANTIATE_TEST_SUITE_P(Legacy, P2PTransportChannelPingTest, Values(""));
3699 INSTANTIATE_TEST_SUITE_P(Active,
3700 P2PTransportChannelPingTest,
3701 Values("WebRTC-UseActiveIceController/Enabled/"));
3702
TEST_P(P2PTransportChannelPingTest,TestTriggeredChecks)3703 TEST_P(P2PTransportChannelPingTest, TestTriggeredChecks) {
3704 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3705 P2PTransportChannel ch("trigger checks", 1, &pa, &field_trials_);
3706 PrepareChannel(&ch);
3707 ch.MaybeStartGathering();
3708 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3709 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3710
3711 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3712 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3713 ASSERT_TRUE(conn1 != nullptr);
3714 ASSERT_TRUE(conn2 != nullptr);
3715
3716 // Before a triggered check, the first connection to ping is the
3717 // highest priority one.
3718 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3719
3720 // Receiving a ping causes a triggered check which should make conn1
3721 // be pinged first instead of conn2, even though conn2 has a higher
3722 // priority.
3723 conn1->ReceivedPing();
3724 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
3725 }
3726
TEST_P(P2PTransportChannelPingTest,TestAllConnectionsPingedSufficiently)3727 TEST_P(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
3728 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3729 P2PTransportChannel ch("ping sufficiently", 1, &pa, &field_trials_);
3730 PrepareChannel(&ch);
3731 ch.MaybeStartGathering();
3732 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3733 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3734
3735 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3736 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3737 ASSERT_TRUE(conn1 != nullptr);
3738 ASSERT_TRUE(conn2 != nullptr);
3739
3740 // Low-priority connection becomes writable so that the other connection
3741 // is not pruned.
3742 conn1->ReceivedPingResponse(LOW_RTT, "id");
3743 EXPECT_TRUE_WAIT(
3744 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3745 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3746 kDefaultTimeout);
3747 }
3748
3749 // Verify that the connections are pinged at the right time.
TEST_P(P2PTransportChannelPingTest,TestStunPingIntervals)3750 TEST_P(P2PTransportChannelPingTest, TestStunPingIntervals) {
3751 rtc::ScopedFakeClock clock;
3752 int RTT_RATIO = 4;
3753 int SCHEDULING_RANGE = 200;
3754 int RTT_RANGE = 10;
3755
3756 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3757 P2PTransportChannel ch("TestChannel", 1, &pa, &field_trials_);
3758 PrepareChannel(&ch);
3759 ch.MaybeStartGathering();
3760 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3761 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3762
3763 ASSERT_TRUE(conn != nullptr);
3764 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3765
3766 // Initializing.
3767
3768 int64_t start = clock.TimeNanos();
3769 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3770 kDefaultTimeout, clock);
3771 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3772 rtc::kNumNanosecsPerMillisec /
3773 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
3774 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
3775
3776 // Stabilizing.
3777
3778 conn->ReceivedPingResponse(LOW_RTT, "id");
3779 int ping_sent_before = conn->num_pings_sent();
3780 start = clock.TimeNanos();
3781 // The connection becomes strong but not stable because we haven't been able
3782 // to converge the RTT.
3783 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3784 clock);
3785 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3786 EXPECT_GE(ping_interval_ms,
3787 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3788 EXPECT_LE(
3789 ping_interval_ms,
3790 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
3791
3792 // Stabilized.
3793
3794 // The connection becomes stable after receiving more than RTT_RATIO rtt
3795 // samples.
3796 for (int i = 0; i < RTT_RATIO; i++) {
3797 conn->ReceivedPingResponse(LOW_RTT, "id");
3798 }
3799 ping_sent_before = conn->num_pings_sent();
3800 start = clock.TimeNanos();
3801 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3802 clock);
3803 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3804 EXPECT_GE(ping_interval_ms,
3805 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3806 EXPECT_LE(
3807 ping_interval_ms,
3808 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
3809
3810 // Destabilized.
3811
3812 conn->ReceivedPingResponse(LOW_RTT, "id");
3813 // Create a in-flight ping.
3814 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3815 start = clock.TimeNanos();
3816 // In-flight ping timeout and the connection will be unstable.
3817 SIMULATED_WAIT(
3818 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3819 kMediumTimeout, clock);
3820 int64_t duration_ms =
3821 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3822 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3823 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3824 // The connection become unstable due to not receiving ping responses.
3825 ping_sent_before = conn->num_pings_sent();
3826 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3827 clock);
3828 // The interval is expected to be
3829 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
3830 start = clock.TimeNanos();
3831 ping_sent_before = conn->num_pings_sent();
3832 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3833 clock);
3834 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3835 EXPECT_GE(ping_interval_ms,
3836 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3837 EXPECT_LE(
3838 ping_interval_ms,
3839 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
3840 }
3841
3842 // Test that we start pinging as soon as we have a connection and remote ICE
3843 // parameters.
TEST_P(P2PTransportChannelPingTest,PingingStartedAsSoonAsPossible)3844 TEST_P(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3845 rtc::ScopedFakeClock clock;
3846
3847 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3848 P2PTransportChannel ch("TestChannel", 1, &pa, &field_trials_);
3849 ch.SetIceRole(ICEROLE_CONTROLLING);
3850 ch.SetIceTiebreaker(kTiebreakerDefault);
3851 ch.SetIceParameters(kIceParams[0]);
3852 ch.MaybeStartGathering();
3853 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3854 kDefaultTimeout);
3855
3856 // Simulate a binding request being received, creating a peer reflexive
3857 // candidate pair while we still don't have remote ICE parameters.
3858 IceMessage request(STUN_BINDING_REQUEST);
3859 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
3860 STUN_ATTR_USERNAME, kIceUfrag[1]));
3861 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3862 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
3863 prflx_priority));
3864 Port* port = GetPort(&ch);
3865 ASSERT_NE(nullptr, port);
3866 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3867 &request, kIceUfrag[1], false);
3868 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3869 ASSERT_NE(nullptr, conn);
3870
3871 // Simulate waiting for a second (and change) and verify that no pings were
3872 // sent, since we don't yet have remote ICE parameters.
3873 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3874 EXPECT_EQ(0, conn->num_pings_sent());
3875
3876 // Set remote ICE parameters. Now we should be able to ping. Ensure that
3877 // the first ping is sent as soon as possible, within one simulated clock
3878 // tick.
3879 ch.SetRemoteIceParameters(kIceParams[1]);
3880 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3881 }
3882
TEST_P(P2PTransportChannelPingTest,TestNoTriggeredChecksWhenWritable)3883 TEST_P(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
3884 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3885 P2PTransportChannel ch("trigger checks", 1, &pa, &field_trials_);
3886 PrepareChannel(&ch);
3887 ch.MaybeStartGathering();
3888 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3889 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3890
3891 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3892 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3893 ASSERT_TRUE(conn1 != nullptr);
3894 ASSERT_TRUE(conn2 != nullptr);
3895
3896 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3897 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
3898 conn1->ReceivedPingResponse(LOW_RTT, "id");
3899 ASSERT_TRUE(conn1->writable());
3900 conn1->ReceivedPing();
3901
3902 // Ping received, but the connection is already writable, so no
3903 // "triggered check" and conn2 is pinged before conn1 because it has
3904 // a higher priority.
3905 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3906 }
3907
TEST_P(P2PTransportChannelPingTest,TestFailedConnectionNotPingable)3908 TEST_P(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
3909 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3910 P2PTransportChannel ch("Do not ping failed connections", 1, &pa,
3911 &field_trials_);
3912 PrepareChannel(&ch);
3913 ch.MaybeStartGathering();
3914 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3915
3916 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3917 ASSERT_TRUE(conn1 != nullptr);
3918
3919 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3920 conn1->Prune(); // A pruned connection may still be pingable.
3921 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3922 conn1->FailAndPrune();
3923 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3924 }
3925
TEST_P(P2PTransportChannelPingTest,TestSignalStateChanged)3926 TEST_P(P2PTransportChannelPingTest, TestSignalStateChanged) {
3927 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3928 P2PTransportChannel ch("state change", 1, &pa, &field_trials_);
3929 PrepareChannel(&ch);
3930 ch.MaybeStartGathering();
3931 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3932 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3933 ASSERT_TRUE(conn1 != nullptr);
3934 // Pruning the connection reduces the set of active connections and changes
3935 // the channel state.
3936 conn1->Prune();
3937 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3938 kDefaultTimeout);
3939 }
3940
3941 // Test adding remote candidates with different ufrags. If a remote candidate
3942 // is added with an old ufrag, it will be discarded. If it is added with a
3943 // ufrag that was not seen before, it will be used to create connections
3944 // although the ICE pwd in the remote candidate will be set when the ICE
3945 // parameters arrive. If a remote candidate is added with the current ICE
3946 // ufrag, its pwd and generation will be set properly.
TEST_P(P2PTransportChannelPingTest,TestAddRemoteCandidateWithVariousUfrags)3947 TEST_P(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
3948 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
3949 P2PTransportChannel ch("add candidate", 1, &pa, &field_trials_);
3950 PrepareChannel(&ch);
3951 ch.MaybeStartGathering();
3952 // Add a candidate with a future ufrag.
3953 ch.AddRemoteCandidate(
3954 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3955 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3956 ASSERT_TRUE(conn1 != nullptr);
3957 const Candidate& candidate = conn1->remote_candidate();
3958 EXPECT_EQ(kIceUfrag[2], candidate.username());
3959 EXPECT_TRUE(candidate.password().empty());
3960 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
3961
3962 // Set the remote ICE parameters with the "future" ufrag.
3963 // This should set the ICE pwd in the remote candidate of `conn1`, making
3964 // it pingable.
3965 ch.SetRemoteIceParameters(kIceParams[2]);
3966 EXPECT_EQ(kIceUfrag[2], candidate.username());
3967 EXPECT_EQ(kIcePwd[2], candidate.password());
3968 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
3969
3970 // Add a candidate with an old ufrag. No connection will be created.
3971 ch.AddRemoteCandidate(
3972 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
3973 rtc::Thread::Current()->ProcessMessages(500);
3974 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3975
3976 // Add a candidate with the current ufrag, its pwd and generation will be
3977 // assigned, even if the generation is not set.
3978 ch.AddRemoteCandidate(
3979 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3980 Connection* conn3 = nullptr;
3981 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
3982 kMediumTimeout);
3983 const Candidate& new_candidate = conn3->remote_candidate();
3984 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3985 EXPECT_EQ(1U, new_candidate.generation());
3986
3987 // Check that the pwd of all remote candidates are properly assigned.
3988 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
3989 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3990 candidate.username() == kIceUfrag[2]);
3991 if (candidate.username() == kIceUfrag[1]) {
3992 EXPECT_EQ(kIcePwd[1], candidate.password());
3993 } else if (candidate.username() == kIceUfrag[2]) {
3994 EXPECT_EQ(kIcePwd[2], candidate.password());
3995 }
3996 }
3997 }
3998
TEST_P(P2PTransportChannelPingTest,ConnectionResurrection)3999 TEST_P(P2PTransportChannelPingTest, ConnectionResurrection) {
4000 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4001 P2PTransportChannel ch("connection resurrection", 1, &pa, &field_trials_);
4002 PrepareChannel(&ch);
4003 ch.MaybeStartGathering();
4004
4005 // Create conn1 and keep track of original candidate priority.
4006 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4007 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4008 ASSERT_TRUE(conn1 != nullptr);
4009 uint32_t remote_priority = conn1->remote_candidate().priority();
4010
4011 // Create a higher priority candidate and make the connection
4012 // receiving/writable. This will prune conn1.
4013 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
4014 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4015 ASSERT_TRUE(conn2 != nullptr);
4016 conn2->ReceivedPing();
4017 conn2->ReceivedPingResponse(LOW_RTT, "id");
4018
4019 // Wait for conn2 to be selected.
4020 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kMediumTimeout);
4021 // Destroy the connection to test SignalUnknownAddress.
4022 ch.RemoveConnectionForTest(conn1);
4023 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
4024 kMediumTimeout);
4025
4026 // Create a minimal STUN message with prflx priority.
4027 IceMessage request(STUN_BINDING_REQUEST);
4028 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
4029 STUN_ATTR_USERNAME, kIceUfrag[1]));
4030 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
4031 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
4032 prflx_priority));
4033 EXPECT_NE(prflx_priority, remote_priority);
4034
4035 Port* port = GetPort(&ch);
4036 // conn1 should be resurrected with original priority.
4037 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
4038 &request, kIceUfrag[1], false);
4039 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4040 ASSERT_TRUE(conn1 != nullptr);
4041 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
4042
4043 // conn3, a real prflx connection, should have prflx priority.
4044 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
4045 &request, kIceUfrag[1], false);
4046 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
4047 ASSERT_TRUE(conn3 != nullptr);
4048 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
4049 }
4050
TEST_P(P2PTransportChannelPingTest,TestReceivingStateChange)4051 TEST_P(P2PTransportChannelPingTest, TestReceivingStateChange) {
4052 rtc::ScopedFakeClock clock;
4053 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4054 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials_);
4055 PrepareChannel(&ch);
4056 // Default receiving timeout and checking receiving interval should not be too
4057 // small.
4058 EXPECT_LE(1000, ch.config().receiving_timeout_or_default());
4059 EXPECT_LE(200, ch.check_receiving_interval());
4060 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
4061 EXPECT_EQ(500, ch.config().receiving_timeout_or_default());
4062 EXPECT_EQ(50, ch.check_receiving_interval());
4063 ch.MaybeStartGathering();
4064 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4065 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4066 ASSERT_TRUE(conn1 != nullptr);
4067
4068 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4069 conn1->ReceivedPing();
4070 conn1->OnReadPacket("ABC", 3, rtc::TimeMicros());
4071 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
4072 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
4073 }
4074
4075 // The controlled side will select a connection as the "selected connection"
4076 // based on priority until the controlling side nominates a connection, at which
4077 // point the controlled side will select that connection as the
4078 // "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
4079 // selected connection changes and SignalReadyToSend will be fired if the new
4080 // selected connection is writable.
TEST_P(P2PTransportChannelPingTest,TestSelectConnectionBeforeNomination)4081 TEST_P(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
4082 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4083 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials_);
4084 PrepareChannel(&ch);
4085 ch.SetIceRole(ICEROLE_CONTROLLED);
4086 ch.MaybeStartGathering();
4087 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4088 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4089 ASSERT_TRUE(conn1 != nullptr);
4090 // Channel is not ready to send because it is not writable.
4091 EXPECT_FALSE(channel_ready_to_send());
4092 int last_packet_id = 0;
4093 const char* data = "ABCDEFGH";
4094 int len = static_cast<int>(strlen(data));
4095 EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
4096 EXPECT_EQ(-1, last_sent_packet_id());
4097
4098 // A connection needs to be writable before it is selected for transmission.
4099 conn1->ReceivedPingResponse(LOW_RTT, "id");
4100 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4101 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4102 EXPECT_TRUE(ConnectionMatchesChangeEvent(
4103 conn1, "remote candidate generation maybe changed"));
4104 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
4105
4106 // When a higher priority candidate comes in, the new connection is chosen
4107 // as the selected connection.
4108 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
4109 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4110 ASSERT_TRUE(conn2 != nullptr);
4111 conn2->ReceivedPingResponse(LOW_RTT, "id");
4112 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
4113 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4114 EXPECT_TRUE(
4115 ConnectionMatchesChangeEvent(conn2, "candidate pair state changed"));
4116 EXPECT_TRUE(channel_ready_to_send());
4117 EXPECT_EQ(last_packet_id, last_sent_packet_id());
4118
4119 // If a stun request with use-candidate attribute arrives, the receiving
4120 // connection will be set as the selected connection, even though
4121 // its priority is lower.
4122 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
4123 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
4124 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
4125 ASSERT_TRUE(conn3 != nullptr);
4126 // Because it has a lower priority, the selected connection is still conn2.
4127 EXPECT_EQ(conn2, ch.selected_connection());
4128 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4129 // But if it is nominated via use_candidate, it is chosen as the selected
4130 // connection.
4131 NominateConnection(conn3);
4132 ASSERT_EQ(conn3, ch.selected_connection());
4133
4134 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
4135 EXPECT_TRUE(
4136 ConnectionMatchesChangeEvent(conn3, "nomination on the controlled side"));
4137 EXPECT_EQ(last_packet_id, last_sent_packet_id());
4138 EXPECT_TRUE(channel_ready_to_send());
4139
4140 // Even if another higher priority candidate arrives, it will not be set as
4141 // the selected connection because the selected connection is nominated by
4142 // the controlling side.
4143 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
4144 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
4145 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
4146 ASSERT_TRUE(conn4 != nullptr);
4147 EXPECT_EQ(conn3, ch.selected_connection());
4148 // But if it is nominated via use_candidate and writable, it will be set as
4149 // the selected connection.
4150 NominateConnection(conn4);
4151 // Not switched yet because conn4 is not writable.
4152 EXPECT_EQ(conn3, ch.selected_connection());
4153 reset_channel_ready_to_send();
4154 // The selected connection switches after conn4 becomes writable.
4155 conn4->ReceivedPingResponse(LOW_RTT, "id");
4156 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
4157 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
4158 EXPECT_TRUE(
4159 ConnectionMatchesChangeEvent(conn4, "candidate pair state changed"));
4160 EXPECT_EQ(last_packet_id, last_sent_packet_id());
4161 // SignalReadyToSend is fired again because conn4 is writable.
4162 EXPECT_TRUE(channel_ready_to_send());
4163 }
4164
4165 // Test the field trial send_ping_on_nomination_ice_controlled
4166 // that sends a ping directly when a connection has been nominated
4167 // i.e on the ICE_CONTROLLED-side.
TEST_P(P2PTransportChannelPingTest,TestPingOnNomination)4168 TEST_P(P2PTransportChannelPingTest, TestPingOnNomination) {
4169 webrtc::test::ScopedKeyValueConfig field_trials(
4170 field_trials_,
4171 "WebRTC-IceFieldTrials/send_ping_on_nomination_ice_controlled:true/");
4172 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4173 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials);
4174 PrepareChannel(&ch);
4175 ch.SetIceConfig(ch.config());
4176 ch.SetIceRole(ICEROLE_CONTROLLED);
4177 ch.MaybeStartGathering();
4178 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4179 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4180 ASSERT_TRUE(conn1 != nullptr);
4181
4182 // A connection needs to be writable before it is selected for transmission.
4183 conn1->ReceivedPingResponse(LOW_RTT, "id");
4184 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4185 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4186
4187 // When a higher priority candidate comes in, the new connection is chosen
4188 // as the selected connection.
4189 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
4190 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4191 ASSERT_TRUE(conn2 != nullptr);
4192 conn2->ReceivedPingResponse(LOW_RTT, "id");
4193 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
4194 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4195
4196 // Now nominate conn1 (low prio), it shall be choosen.
4197 const int before = conn1->num_pings_sent();
4198 NominateConnection(conn1);
4199 ASSERT_EQ(conn1, ch.selected_connection());
4200 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4201
4202 // And the additional ping should have been sent directly.
4203 EXPECT_EQ(conn1->num_pings_sent(), before + 1);
4204 }
4205
4206 // Test the field trial send_ping_on_switch_ice_controlling
4207 // that sends a ping directly when switching to a new connection
4208 // on the ICE_CONTROLLING-side.
TEST_P(P2PTransportChannelPingTest,TestPingOnSwitch)4209 TEST_P(P2PTransportChannelPingTest, TestPingOnSwitch) {
4210 webrtc::test::ScopedKeyValueConfig field_trials(
4211 field_trials_,
4212 "WebRTC-IceFieldTrials/send_ping_on_switch_ice_controlling:true/");
4213 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4214 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials);
4215 PrepareChannel(&ch);
4216 ch.SetIceConfig(ch.config());
4217 ch.SetIceRole(ICEROLE_CONTROLLING);
4218 ch.MaybeStartGathering();
4219 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4220 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4221 ASSERT_TRUE(conn1 != nullptr);
4222
4223 // A connection needs to be writable before it is selected for transmission.
4224 conn1->ReceivedPingResponse(LOW_RTT, "id");
4225 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4226 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4227
4228 // When a higher priority candidate comes in, the new connection is chosen
4229 // as the selected connection.
4230 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
4231 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4232 ASSERT_TRUE(conn2 != nullptr);
4233
4234 const int before = conn2->num_pings_sent();
4235
4236 conn2->ReceivedPingResponse(LOW_RTT, "id");
4237 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
4238 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4239
4240 // And the additional ping should have been sent directly.
4241 EXPECT_EQ(conn2->num_pings_sent(), before + 1);
4242 }
4243
4244 // Test the field trial send_ping_on_switch_ice_controlling
4245 // that sends a ping directly when selecteing a new connection
4246 // on the ICE_CONTROLLING-side (i.e also initial selection).
TEST_P(P2PTransportChannelPingTest,TestPingOnSelected)4247 TEST_P(P2PTransportChannelPingTest, TestPingOnSelected) {
4248 webrtc::test::ScopedKeyValueConfig field_trials(
4249 field_trials_,
4250 "WebRTC-IceFieldTrials/send_ping_on_selected_ice_controlling:true/");
4251 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4252 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials);
4253 PrepareChannel(&ch);
4254 ch.SetIceConfig(ch.config());
4255 ch.SetIceRole(ICEROLE_CONTROLLING);
4256 ch.MaybeStartGathering();
4257 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4258 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4259 ASSERT_TRUE(conn1 != nullptr);
4260
4261 const int before = conn1->num_pings_sent();
4262
4263 // A connection needs to be writable before it is selected for transmission.
4264 conn1->ReceivedPingResponse(LOW_RTT, "id");
4265 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4266 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4267
4268 // And the additional ping should have been sent directly.
4269 EXPECT_EQ(conn1->num_pings_sent(), before + 1);
4270 }
4271
4272 // The controlled side will select a connection as the "selected connection"
4273 // based on requests from an unknown address before the controlling side
4274 // nominates a connection, and will nominate a connection from an unknown
4275 // address if the request contains the use_candidate attribute. Plus, it will
4276 // also sends back a ping response and set the ICE pwd in the remote candidate
4277 // appropriately.
TEST_P(P2PTransportChannelPingTest,TestSelectConnectionFromUnknownAddress)4278 TEST_P(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
4279 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4280 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials_);
4281 PrepareChannel(&ch);
4282 ch.SetIceRole(ICEROLE_CONTROLLED);
4283 ch.MaybeStartGathering();
4284 // A minimal STUN message with prflx priority.
4285 IceMessage request(STUN_BINDING_REQUEST);
4286 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
4287 STUN_ATTR_USERNAME, kIceUfrag[1]));
4288 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
4289 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
4290 prflx_priority));
4291 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
4292 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
4293 &request, kIceUfrag[1], false);
4294 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4295 ASSERT_TRUE(conn1 != nullptr);
4296 EXPECT_EQ(conn1->stats().sent_ping_responses, 1u);
4297 EXPECT_NE(conn1, ch.selected_connection());
4298 conn1->ReceivedPingResponse(LOW_RTT, "id");
4299 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4300
4301 // Another connection is nominated via use_candidate.
4302 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
4303 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4304 ASSERT_TRUE(conn2 != nullptr);
4305 // Because it has a lower priority, the selected connection is still conn1.
4306 EXPECT_EQ(conn1, ch.selected_connection());
4307 // When it is nominated via use_candidate and writable, it is chosen as the
4308 // selected connection.
4309 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4310 NominateConnection(conn2);
4311 EXPECT_EQ(conn2, ch.selected_connection());
4312
4313 // Another request with unknown address, it will not be set as the selected
4314 // connection because the selected connection was nominated by the controlling
4315 // side.
4316 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
4317 &request, kIceUfrag[1], false);
4318 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
4319 ASSERT_TRUE(conn3 != nullptr);
4320 EXPECT_EQ(conn3->stats().sent_ping_responses, 1u);
4321 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4322 EXPECT_EQ(conn2, ch.selected_connection());
4323
4324 // However if the request contains use_candidate attribute, it will be
4325 // selected as the selected connection.
4326 request.AddAttribute(
4327 std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
4328 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
4329 &request, kIceUfrag[1], false);
4330 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
4331 ASSERT_TRUE(conn4 != nullptr);
4332 EXPECT_EQ(conn4->stats().sent_ping_responses, 1u);
4333 // conn4 is not the selected connection yet because it is not writable.
4334 EXPECT_EQ(conn2, ch.selected_connection());
4335 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4336 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
4337
4338 // Test that the request from an unknown address contains a ufrag from an old
4339 // generation.
4340 // port->set_sent_binding_response(false);
4341 ch.SetRemoteIceParameters(kIceParams[2]);
4342 ch.SetRemoteIceParameters(kIceParams[3]);
4343 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
4344 &request, kIceUfrag[2], false);
4345 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
4346 ASSERT_TRUE(conn5 != nullptr);
4347 EXPECT_EQ(conn5->stats().sent_ping_responses, 1u);
4348 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
4349 }
4350
4351 // The controlled side will select a connection as the "selected connection"
4352 // based on media received until the controlling side nominates a connection,
4353 // at which point the controlled side will select that connection as
4354 // the "selected connection".
TEST_P(P2PTransportChannelPingTest,TestSelectConnectionBasedOnMediaReceived)4355 TEST_P(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
4356 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4357 P2PTransportChannel ch("receiving state change", 1, &pa, &field_trials_);
4358 PrepareChannel(&ch);
4359 ch.SetIceRole(ICEROLE_CONTROLLED);
4360 ch.MaybeStartGathering();
4361 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
4362 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4363 ASSERT_TRUE(conn1 != nullptr);
4364 conn1->ReceivedPingResponse(LOW_RTT, "id");
4365 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
4366
4367 // If a data packet is received on conn2, the selected connection should
4368 // switch to conn2 because the controlled side must mirror the media path
4369 // chosen by the controlling side.
4370 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
4371 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4372 ASSERT_TRUE(conn2 != nullptr);
4373 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
4374 conn2->OnReadPacket("ABC", 3, rtc::TimeMicros());
4375 EXPECT_EQ(conn2, ch.selected_connection());
4376 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4377
4378 // Now another STUN message with an unknown address and use_candidate will
4379 // nominate the selected connection.
4380 IceMessage request(STUN_BINDING_REQUEST);
4381 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
4382 STUN_ATTR_USERNAME, kIceUfrag[1]));
4383 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
4384 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
4385 prflx_priority));
4386 request.AddAttribute(
4387 std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
4388 Port* port = GetPort(&ch);
4389 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
4390 &request, kIceUfrag[1], false);
4391 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
4392 ASSERT_TRUE(conn3 != nullptr);
4393 EXPECT_NE(conn3, ch.selected_connection()); // Not writable yet.
4394 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
4395 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
4396
4397 // Now another data packet will not switch the selected connection because the
4398 // selected connection was nominated by the controlling side.
4399 conn2->ReceivedPing();
4400 conn2->ReceivedPingResponse(LOW_RTT, "id");
4401 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4402 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
4403 }
4404
TEST_P(P2PTransportChannelPingTest,TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority)4405 TEST_P(P2PTransportChannelPingTest,
4406 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
4407 rtc::ScopedFakeClock clock;
4408 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4409 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4410 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa, &field_trials_);
4411 PrepareChannel(&ch);
4412 ch.SetIceRole(ICEROLE_CONTROLLED);
4413 ch.MaybeStartGathering();
4414 // The connections have decreasing priority.
4415 Connection* conn1 =
4416 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
4417 ASSERT_TRUE(conn1 != nullptr);
4418 Connection* conn2 =
4419 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
4420 ASSERT_TRUE(conn2 != nullptr);
4421
4422 // Initially, connections are selected based on priority.
4423 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4424 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4425
4426 // conn2 receives data; it becomes selected.
4427 // Advance the clock by 1ms so that the last data receiving timestamp of
4428 // conn2 is larger.
4429 SIMULATED_WAIT(false, 1, clock);
4430 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4431 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4432 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4433
4434 // conn1 also receives data; it becomes selected due to priority again.
4435 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4436 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4437 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4438
4439 // conn2 received data more recently; it is selected now because it
4440 // received data more recently.
4441 SIMULATED_WAIT(false, 1, clock);
4442 // Need to become writable again because it was pruned.
4443 conn2->ReceivedPingResponse(LOW_RTT, "id");
4444 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4445 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4446 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4447
4448 // Make sure sorting won't reselect candidate pair.
4449 SIMULATED_WAIT(false, 10, clock);
4450 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4451 }
4452
TEST_P(P2PTransportChannelPingTest,TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving)4453 TEST_P(P2PTransportChannelPingTest,
4454 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
4455 rtc::ScopedFakeClock clock;
4456 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4457
4458 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4459 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa, &field_trials_);
4460 PrepareChannel(&ch);
4461 ch.SetIceRole(ICEROLE_CONTROLLED);
4462 ch.MaybeStartGathering();
4463 // The connections have decreasing priority.
4464 Connection* conn1 =
4465 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
4466 ASSERT_TRUE(conn1 != nullptr);
4467 Connection* conn2 =
4468 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
4469 ASSERT_TRUE(conn2 != nullptr);
4470
4471 // conn1 received data; it is the selected connection.
4472 // Advance the clock to have a non-zero last-data-receiving time.
4473 SIMULATED_WAIT(false, 1, clock);
4474 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4475 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4476 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4477
4478 // conn2 is nominated; it becomes the selected connection.
4479 NominateConnection(conn2);
4480 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4481 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4482
4483 // conn1 is selected because it has higher priority and also nominated.
4484 NominateConnection(conn1);
4485 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4486 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4487
4488 // Make sure sorting won't reselect candidate pair.
4489 SIMULATED_WAIT(false, 10, clock);
4490 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4491 }
4492
TEST_P(P2PTransportChannelPingTest,TestControlledAgentSelectsConnectionWithHigherNomination)4493 TEST_P(P2PTransportChannelPingTest,
4494 TestControlledAgentSelectsConnectionWithHigherNomination) {
4495 rtc::ScopedFakeClock clock;
4496 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4497
4498 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4499 P2PTransportChannel ch("test", 1, &pa, &field_trials_);
4500 PrepareChannel(&ch);
4501 ch.SetIceRole(ICEROLE_CONTROLLED);
4502 ch.MaybeStartGathering();
4503 // The connections have decreasing priority.
4504 Connection* conn1 =
4505 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
4506 ASSERT_TRUE(conn1 != nullptr);
4507 Connection* conn2 =
4508 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
4509 ASSERT_TRUE(conn2 != nullptr);
4510
4511 // conn1 is the selected connection because it has a higher priority,
4512 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4513 clock);
4514 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4515 reset_selected_candidate_pair_switches();
4516
4517 // conn2 is nominated; it becomes selected.
4518 NominateConnection(conn2);
4519 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4520 EXPECT_EQ(conn2, ch.selected_connection());
4521 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4522
4523 // conn1 is selected because of its priority.
4524 NominateConnection(conn1);
4525 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4526 EXPECT_EQ(conn1, ch.selected_connection());
4527 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4528
4529 // conn2 gets higher remote nomination; it is selected again.
4530 NominateConnection(conn2, 2U);
4531 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
4532 EXPECT_EQ(conn2, ch.selected_connection());
4533 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4534
4535 // Make sure sorting won't reselect candidate pair.
4536 SIMULATED_WAIT(false, 100, clock);
4537 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4538 }
4539
TEST_P(P2PTransportChannelPingTest,TestEstimatedDisconnectedTime)4540 TEST_P(P2PTransportChannelPingTest, TestEstimatedDisconnectedTime) {
4541 rtc::ScopedFakeClock clock;
4542 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4543
4544 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4545 P2PTransportChannel ch("test", 1, &pa, &field_trials_);
4546 PrepareChannel(&ch);
4547 ch.SetIceRole(ICEROLE_CONTROLLED);
4548 ch.MaybeStartGathering();
4549 // The connections have decreasing priority.
4550 Connection* conn1 =
4551 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", /* port= */ 1,
4552 /* priority= */ 10, /* writable= */ true);
4553 ASSERT_TRUE(conn1 != nullptr);
4554 Connection* conn2 =
4555 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", /* port= */ 2,
4556 /* priority= */ 9, /* writable= */ true);
4557 ASSERT_TRUE(conn2 != nullptr);
4558
4559 // conn1 is the selected connection because it has a higher priority,
4560 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4561 clock);
4562 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4563 // No estimateded disconnect time at first connect <=> value is 0.
4564 EXPECT_EQ(LastEstimatedDisconnectedTimeMs(), 0);
4565
4566 // Use nomination to force switching of selected connection.
4567 int nomination = 1;
4568
4569 {
4570 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4571 // This will not parse as STUN, and is considered data
4572 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4573 clock.AdvanceTime(webrtc::TimeDelta::Seconds(2));
4574
4575 // conn2 is nominated; it becomes selected.
4576 NominateConnection(conn2, nomination++);
4577 EXPECT_EQ(conn2, ch.selected_connection());
4578 // We got data 2s ago...guess that we lost 2s of connectivity.
4579 EXPECT_EQ(LastEstimatedDisconnectedTimeMs(), 2000);
4580 }
4581
4582 {
4583 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4584 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4585
4586 clock.AdvanceTime(webrtc::TimeDelta::Seconds(2));
4587 ReceivePingOnConnection(conn2, kIceUfrag[1], 1, nomination++);
4588
4589 clock.AdvanceTime(webrtc::TimeDelta::Millis(500));
4590
4591 ReceivePingOnConnection(conn1, kIceUfrag[1], 1, nomination++);
4592 EXPECT_EQ(conn1, ch.selected_connection());
4593 // We got ping 500ms ago...guess that we lost 500ms of connectivity.
4594 EXPECT_EQ(LastEstimatedDisconnectedTimeMs(), 500);
4595 }
4596 }
4597
TEST_P(P2PTransportChannelPingTest,TestControlledAgentIgnoresSmallerNomination)4598 TEST_P(P2PTransportChannelPingTest,
4599 TestControlledAgentIgnoresSmallerNomination) {
4600 rtc::ScopedFakeClock clock;
4601 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4602
4603 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4604 P2PTransportChannel ch("test", 1, &pa, &field_trials_);
4605 PrepareChannel(&ch);
4606 ch.SetIceRole(ICEROLE_CONTROLLED);
4607 ch.MaybeStartGathering();
4608 Connection* conn =
4609 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
4610 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
4611 EXPECT_EQ(2U, conn->remote_nomination());
4612 // Smaller nomination is ignored.
4613 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
4614 EXPECT_EQ(2U, conn->remote_nomination());
4615 }
4616
TEST_P(P2PTransportChannelPingTest,TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination)4617 TEST_P(P2PTransportChannelPingTest,
4618 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
4619 rtc::ScopedFakeClock clock;
4620
4621 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4622 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa, &field_trials_);
4623 PrepareChannel(&ch);
4624 ch.SetIceRole(ICEROLE_CONTROLLED);
4625 ch.MaybeStartGathering();
4626 // The connections have decreasing priority.
4627 Connection* conn1 =
4628 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
4629 ASSERT_TRUE(conn1 != nullptr);
4630 Connection* conn2 =
4631 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
4632 ASSERT_TRUE(conn2 != nullptr);
4633
4634 NominateConnection(conn1);
4635 // There is no selected connection because no connection is writable.
4636 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4637
4638 // conn2 becomes writable; it is selected even though it is not nominated.
4639 conn2->ReceivedPingResponse(LOW_RTT, "id");
4640 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
4641 kDefaultTimeout, clock);
4642 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4643 clock);
4644 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
4645
4646 // If conn1 is also writable, it will become selected.
4647 conn1->ReceivedPingResponse(LOW_RTT, "id");
4648 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
4649 kDefaultTimeout, clock);
4650 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4651 clock);
4652 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
4653
4654 // Make sure sorting won't reselect candidate pair.
4655 SIMULATED_WAIT(false, 10, clock);
4656 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4657 }
4658
4659 // Test that if a new remote candidate has the same address and port with
4660 // an old one, it will be used to create a new connection.
TEST_P(P2PTransportChannelPingTest,TestAddRemoteCandidateWithAddressReuse)4661 TEST_P(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
4662 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4663 P2PTransportChannel ch("candidate reuse", 1, &pa, &field_trials_);
4664 PrepareChannel(&ch);
4665 ch.MaybeStartGathering();
4666 const std::string host_address = "1.1.1.1";
4667 const int port_num = 1;
4668
4669 // kIceUfrag[1] is the current generation ufrag.
4670 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4671 port_num, 1, kIceUfrag[1]);
4672 ch.AddRemoteCandidate(candidate);
4673 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
4674 ASSERT_TRUE(conn1 != nullptr);
4675 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4676
4677 // Simply adding the same candidate again won't create a new connection.
4678 ch.AddRemoteCandidate(candidate);
4679 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
4680 EXPECT_EQ(conn1, conn2);
4681
4682 // Update the ufrag of the candidate and add it again.
4683 candidate.set_username(kIceUfrag[2]);
4684 ch.AddRemoteCandidate(candidate);
4685 conn2 = GetConnectionTo(&ch, host_address, port_num);
4686 EXPECT_NE(conn1, conn2);
4687 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4688 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4689
4690 // Verify that a ping with the new ufrag can be received on the new
4691 // connection.
4692 EXPECT_EQ(0, conn2->last_ping_received());
4693 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
4694 EXPECT_GT(conn2->last_ping_received(), 0);
4695 }
4696
4697 // When the current selected connection is strong, lower-priority connections
4698 // will be pruned. Otherwise, lower-priority connections are kept.
TEST_P(P2PTransportChannelPingTest,TestDontPruneWhenWeak)4699 TEST_P(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
4700 rtc::ScopedFakeClock clock;
4701 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4702 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4703 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4704 PrepareChannel(&ch);
4705 ch.SetIceRole(ICEROLE_CONTROLLED);
4706 ch.MaybeStartGathering();
4707 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4708 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4709 ASSERT_TRUE(conn1 != nullptr);
4710 EXPECT_EQ(nullptr, ch.selected_connection());
4711 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4712
4713 // When a higher-priority, nominated candidate comes in, the connections with
4714 // lower-priority are pruned.
4715 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
4716 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
4717 ASSERT_TRUE(conn2 != nullptr);
4718 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4719 NominateConnection(conn2);
4720 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
4721
4722 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
4723 // Wait until conn2 becomes not receiving.
4724 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
4725
4726 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
4727 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
4728 ASSERT_TRUE(conn3 != nullptr);
4729 // The selected connection should still be conn2. Even through conn3 has lower
4730 // priority and is not receiving/writable, it is not pruned because the
4731 // selected connection is not receiving.
4732 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
4733 EXPECT_FALSE(conn3->pruned());
4734 }
4735
TEST_P(P2PTransportChannelPingTest,TestDontPruneHighPriorityConnections)4736 TEST_P(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4737 rtc::ScopedFakeClock clock;
4738 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4739 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4740 PrepareChannel(&ch);
4741 ch.SetIceRole(ICEROLE_CONTROLLED);
4742 ch.MaybeStartGathering();
4743 Connection* conn1 =
4744 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
4745 ASSERT_TRUE(conn1 != nullptr);
4746 Connection* conn2 =
4747 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
4748 ASSERT_TRUE(conn2 != nullptr);
4749 // Even if conn1 is writable, nominated, receiving data, it should not prune
4750 // conn2.
4751 NominateConnection(conn1);
4752 SIMULATED_WAIT(false, 1, clock);
4753 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
4754 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4755 EXPECT_FALSE(conn2->pruned());
4756 }
4757
4758 // Test that GetState returns the state correctly.
TEST_P(P2PTransportChannelPingTest,TestGetState)4759 TEST_P(P2PTransportChannelPingTest, TestGetState) {
4760 rtc::ScopedFakeClock clock;
4761 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4762 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4763 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4764 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
4765 PrepareChannel(&ch);
4766 ch.MaybeStartGathering();
4767 // After gathering we are still in the kNew state because we aren't checking
4768 // any connections yet.
4769 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
4770 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
4771 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4772 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
4773 // Checking candidates that have been added with gathered candidates.
4774 ASSERT_GT(ch.connections().size(), 0u);
4775 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
4776 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4777 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
4778 ASSERT_TRUE(conn1 != nullptr);
4779 ASSERT_TRUE(conn2 != nullptr);
4780 // Now there are two connections, so the transport channel is connecting.
4781 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
4782 // No connections are writable yet, so we should still be in the kChecking
4783 // state.
4784 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
4785 // `conn1` becomes writable and receiving; it then should prune `conn2`.
4786 conn1->ReceivedPingResponse(LOW_RTT, "id");
4787 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
4788 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
4789 EXPECT_EQ(webrtc::IceTransportState::kConnected, ch.GetIceTransportState());
4790 conn1->Prune(); // All connections are pruned.
4791 // Need to wait until the channel state is updated.
4792 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
4793 kShortTimeout, clock);
4794 EXPECT_EQ(webrtc::IceTransportState::kFailed, ch.GetIceTransportState());
4795 }
4796
4797 // Test that when a low-priority connection is pruned, it is not deleted
4798 // right away, and it can become active and be pruned again.
TEST_P(P2PTransportChannelPingTest,TestConnectionPrunedAgain)4799 TEST_P(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
4800 rtc::ScopedFakeClock clock;
4801 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4802
4803 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4804 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4805 PrepareChannel(&ch);
4806 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
4807 config.receiving_switching_delay = 800;
4808 ch.SetIceConfig(config);
4809 ch.MaybeStartGathering();
4810 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4811 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4812 ASSERT_TRUE(conn1 != nullptr);
4813 EXPECT_EQ(nullptr, ch.selected_connection());
4814 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4815 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4816 clock);
4817
4818 // Add a low-priority connection `conn2`, which will be pruned, but it will
4819 // not be deleted right away. Once the current selected connection becomes not
4820 // receiving, `conn2` will start to ping and upon receiving the ping response,
4821 // it will become the selected connection.
4822 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
4823 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
4824 ASSERT_TRUE(conn2 != nullptr);
4825 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
4826 // `conn2` should not send a ping yet.
4827 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
4828 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
4829 // Wait for `conn1` becoming not receiving.
4830 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
4831 // Make sure conn2 is not deleted.
4832 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
4833 ASSERT_TRUE(conn2 != nullptr);
4834 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
4835 kDefaultTimeout, clock);
4836 conn2->ReceivedPingResponse(LOW_RTT, "id");
4837 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4838 clock);
4839 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
4840
4841 // When `conn1` comes back again, `conn2` will be pruned again.
4842 conn1->ReceivedPingResponse(LOW_RTT, "id");
4843 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4844 clock);
4845 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
4846 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
4847 }
4848
4849 // Test that if all connections in a channel has timed out on writing, they
4850 // will all be deleted. We use Prune to simulate write_time_out.
TEST_P(P2PTransportChannelPingTest,TestDeleteConnectionsIfAllWriteTimedout)4851 TEST_P(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
4852 rtc::ScopedFakeClock clock;
4853 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4854 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4855 PrepareChannel(&ch);
4856 ch.MaybeStartGathering();
4857 // Have one connection only but later becomes write-time-out.
4858 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4859 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4860 ASSERT_TRUE(conn1 != nullptr);
4861 conn1->ReceivedPing(); // Becomes receiving
4862 conn1->Prune();
4863 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
4864
4865 // Have two connections but both become write-time-out later.
4866 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
4867 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
4868 ASSERT_TRUE(conn2 != nullptr);
4869 conn2->ReceivedPing(); // Becomes receiving
4870 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
4871 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
4872 ASSERT_TRUE(conn3 != nullptr);
4873 conn3->ReceivedPing(); // Becomes receiving
4874 // Now prune both conn2 and conn3; they will be deleted soon.
4875 conn2->Prune();
4876 conn3->Prune();
4877 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
4878 }
4879
4880 // Tests that after a port allocator session is started, it will be stopped
4881 // when a new connection becomes writable and receiving. Also tests that if a
4882 // connection belonging to an old session becomes writable, it won't stop
4883 // the current port allocator session.
TEST_P(P2PTransportChannelPingTest,TestStopPortAllocatorSessions)4884 TEST_P(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
4885 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4886 P2PTransportChannel ch("test channel", 1, &pa, &field_trials_);
4887 PrepareChannel(&ch);
4888 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
4889 ch.MaybeStartGathering();
4890 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4891 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4892 ASSERT_TRUE(conn1 != nullptr);
4893 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4894 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4895
4896 // Start a new session. Even though conn1, which belongs to an older
4897 // session, becomes unwritable and writable again, it should not stop the
4898 // current session.
4899 ch.SetIceParameters(kIceParams[1]);
4900 ch.MaybeStartGathering();
4901 conn1->Prune();
4902 conn1->ReceivedPingResponse(LOW_RTT, "id");
4903 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4904
4905 // But if a new connection created from the new session becomes writable,
4906 // it will stop the current session.
4907 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4908 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4909 ASSERT_TRUE(conn2 != nullptr);
4910 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4911 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4912 }
4913
4914 // Test that the ICE role is updated even on ports that has been removed.
4915 // These ports may still have connections that need a correct role, in case that
4916 // the connections on it may still receive stun pings.
TEST_P(P2PTransportChannelPingTest,TestIceRoleUpdatedOnRemovedPort)4917 TEST_P(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
4918 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4919 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa,
4920 &field_trials_);
4921 // Starts with ICEROLE_CONTROLLING.
4922 PrepareChannel(&ch);
4923 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
4924 ch.SetIceConfig(config);
4925 ch.MaybeStartGathering();
4926 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4927
4928 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4929 ASSERT_TRUE(conn != nullptr);
4930
4931 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4932 // change the ICE role and expect it to be updated.
4933 std::vector<PortInterface*> ports(1, conn->PortForTest());
4934 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
4935 ch.SetIceRole(ICEROLE_CONTROLLED);
4936 EXPECT_EQ(ICEROLE_CONTROLLED, conn->PortForTest()->GetIceRole());
4937 }
4938
4939 // Test that the ICE role is updated even on ports with inactive networks.
4940 // These ports may still have connections that need a correct role, for the
4941 // pings sent by those connections until they're replaced by newer-generation
4942 // connections.
TEST_P(P2PTransportChannelPingTest,TestIceRoleUpdatedOnPortAfterIceRestart)4943 TEST_P(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
4944 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4945 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa,
4946 &field_trials_);
4947 // Starts with ICEROLE_CONTROLLING.
4948 PrepareChannel(&ch);
4949 ch.MaybeStartGathering();
4950 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4951
4952 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4953 ASSERT_TRUE(conn != nullptr);
4954
4955 // Do an ICE restart, change the role, and expect the old port to have its
4956 // role updated.
4957 ch.SetIceParameters(kIceParams[1]);
4958 ch.MaybeStartGathering();
4959 ch.SetIceRole(ICEROLE_CONTROLLED);
4960 EXPECT_EQ(ICEROLE_CONTROLLED, conn->PortForTest()->GetIceRole());
4961 }
4962
4963 // Test that after some amount of time without receiving data, the connection
4964 // will be destroyed. The port will only be destroyed after it is marked as
4965 // "pruned."
TEST_P(P2PTransportChannelPingTest,TestPortDestroyedAfterTimeoutAndPruned)4966 TEST_P(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
4967 rtc::ScopedFakeClock fake_clock;
4968
4969 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
4970 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa,
4971 &field_trials_);
4972 PrepareChannel(&ch);
4973 ch.SetIceRole(ICEROLE_CONTROLLED);
4974 ch.MaybeStartGathering();
4975 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4976
4977 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4978 ASSERT_TRUE(conn != nullptr);
4979
4980 // Simulate 2 minutes going by. This should be enough time for the port to
4981 // time out.
4982 for (int second = 0; second < 120; ++second) {
4983 fake_clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
4984 }
4985 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
4986 // Port will not be removed because it is not pruned yet.
4987 PortInterface* port = GetPort(&ch);
4988 ASSERT_NE(nullptr, port);
4989
4990 // If the session prunes all ports, the port will be destroyed.
4991 ch.allocator_session()->PruneAllPorts();
4992 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
4993 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
4994 }
4995
TEST_P(P2PTransportChannelPingTest,TestMaxOutstandingPingsFieldTrial)4996 TEST_P(P2PTransportChannelPingTest, TestMaxOutstandingPingsFieldTrial) {
4997 webrtc::test::ScopedKeyValueConfig field_trials(
4998 field_trials_, "WebRTC-IceFieldTrials/max_outstanding_pings:3/");
4999 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
5000 P2PTransportChannel ch("max", 1, &pa, &field_trials);
5001 ch.SetIceConfig(ch.config());
5002 PrepareChannel(&ch);
5003 ch.MaybeStartGathering();
5004 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
5005 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
5006
5007 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
5008 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
5009 ASSERT_TRUE(conn1 != nullptr);
5010 ASSERT_TRUE(conn2 != nullptr);
5011
5012 EXPECT_TRUE_WAIT(conn1->num_pings_sent() == 3 && conn2->num_pings_sent() == 3,
5013 kDefaultTimeout);
5014
5015 // Check that these connections don't send any more pings.
5016 EXPECT_EQ(nullptr, ch.FindNextPingableConnection());
5017 }
5018
5019 class P2PTransportChannelMostLikelyToWorkFirstTest
5020 : public P2PTransportChannelPingTest {
5021 public:
P2PTransportChannelMostLikelyToWorkFirstTest()5022 P2PTransportChannelMostLikelyToWorkFirstTest()
5023 : turn_server_(rtc::Thread::Current(),
5024 ss(),
5025 kTurnUdpIntAddr,
5026 kTurnUdpExtAddr) {
5027 network_manager_.AddInterface(kPublicAddrs[0]);
5028 allocator_.reset(
5029 CreateBasicPortAllocator(&network_manager_, ss(), ServerAddresses(),
5030 kTurnUdpIntAddr, rtc::SocketAddress()));
5031 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
5032 PORTALLOCATOR_DISABLE_TCP);
5033 allocator_->set_step_delay(kMinimumStepDelay);
5034 }
5035
StartTransportChannel(bool prioritize_most_likely_to_work,int stable_writable_connection_ping_interval,const webrtc::FieldTrialsView * field_trials=nullptr)5036 P2PTransportChannel& StartTransportChannel(
5037 bool prioritize_most_likely_to_work,
5038 int stable_writable_connection_ping_interval,
5039 const webrtc::FieldTrialsView* field_trials = nullptr) {
5040 channel_.reset(
5041 new P2PTransportChannel("checks", 1, allocator(), field_trials));
5042 IceConfig config = channel_->config();
5043 config.prioritize_most_likely_candidate_pairs =
5044 prioritize_most_likely_to_work;
5045 config.stable_writable_connection_ping_interval =
5046 stable_writable_connection_ping_interval;
5047 channel_->SetIceConfig(config);
5048 PrepareChannel(channel_.get());
5049 channel_->MaybeStartGathering();
5050 return *channel_.get();
5051 }
5052
allocator()5053 BasicPortAllocator* allocator() { return allocator_.get(); }
turn_server()5054 TestTurnServer* turn_server() { return &turn_server_; }
5055
5056 // This verifies the next pingable connection has the expected candidates'
5057 // types and, for relay local candidate, the expected relay protocol and ping
5058 // it.
VerifyNextPingableConnection(absl::string_view local_candidate_type,absl::string_view remote_candidate_type,absl::string_view relay_protocol_type=UDP_PROTOCOL_NAME)5059 void VerifyNextPingableConnection(
5060 absl::string_view local_candidate_type,
5061 absl::string_view remote_candidate_type,
5062 absl::string_view relay_protocol_type = UDP_PROTOCOL_NAME) {
5063 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
5064 ASSERT_TRUE(conn != nullptr);
5065 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
5066 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
5067 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
5068 }
5069 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
5070 }
5071
5072 private:
5073 std::unique_ptr<BasicPortAllocator> allocator_;
5074 rtc::FakeNetworkManager network_manager_;
5075 TestTurnServer turn_server_;
5076 std::unique_ptr<P2PTransportChannel> channel_;
5077 };
5078
5079 INSTANTIATE_TEST_SUITE_P(Legacy,
5080 P2PTransportChannelMostLikelyToWorkFirstTest,
5081 Values(""));
5082 INSTANTIATE_TEST_SUITE_P(Active,
5083 P2PTransportChannelMostLikelyToWorkFirstTest,
5084 Values("WebRTC-UseActiveIceController/Enabled/"));
5085
5086 // Test that Relay/Relay connections will be pinged first when no other
5087 // connections have been pinged yet, unless we need to ping a trigger check or
5088 // we have a selected connection.
TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,TestRelayRelayFirstWhenNothingPingedYet)5089 TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,
5090 TestRelayRelayFirstWhenNothingPingedYet) {
5091 const int max_strong_interval = 500;
5092 P2PTransportChannel& ch =
5093 StartTransportChannel(true, max_strong_interval, &field_trials_);
5094 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
5095 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
5096 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
5097
5098 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
5099 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
5100
5101 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
5102
5103 // Relay/Relay should be the first pingable connection.
5104 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
5105 ASSERT_TRUE(conn != nullptr);
5106 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
5107 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
5108
5109 // Unless that we have a trigger check waiting to be pinged.
5110 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
5111 ASSERT_TRUE(conn2 != nullptr);
5112 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
5113 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
5114 conn2->ReceivedPing();
5115 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
5116
5117 // Make conn3 the selected connection.
5118 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
5119 ASSERT_TRUE(conn3 != nullptr);
5120 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
5121 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
5122 conn3->ReceivedPingResponse(LOW_RTT, "id");
5123 ASSERT_TRUE(conn3->writable());
5124 conn3->ReceivedPing();
5125
5126 /*
5127
5128 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
5129 the flakiness. The following test becomes flaky because we now ping the
5130 connections with fast rates until every connection is pinged at least three
5131 times. The selected connection may have been pinged before
5132 `max_strong_interval`, so it may not be the next connection to be pinged as
5133 expected in the test.
5134
5135 // Verify that conn3 will be the "selected connection" since it is readable
5136 // and writable. After `MAX_CURRENT_STRONG_INTERVAL`, it should be the next
5137 // pingable connection.
5138 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
5139 WAIT(false, max_strong_interval + 100);
5140 conn3->ReceivedPingResponse(LOW_RTT, "id");
5141 ASSERT_TRUE(conn3->writable());
5142 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
5143
5144 */
5145 }
5146
5147 // Test that Relay/Relay connections will be pinged first when everything has
5148 // been pinged even if the Relay/Relay connection wasn't the first to be pinged
5149 // in the first round.
TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,TestRelayRelayFirstWhenEverythingPinged)5150 TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,
5151 TestRelayRelayFirstWhenEverythingPinged) {
5152 P2PTransportChannel& ch = StartTransportChannel(true, 500, &field_trials_);
5153 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
5154 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
5155 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
5156
5157 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
5158 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
5159
5160 // Initially, only have Local/Local and Local/Relay.
5161 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
5162 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
5163
5164 // Remote Relay candidate arrives.
5165 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
5166 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
5167
5168 // Relay/Relay should be the first since it hasn't been pinged before.
5169 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
5170
5171 // Local/Relay is the final one.
5172 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
5173
5174 // Now, every connection has been pinged once. The next one should be
5175 // Relay/Relay.
5176 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
5177 }
5178
5179 // Test that when we receive a new remote candidate, they will be tried first
5180 // before we re-ping Relay/Relay connections again.
TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,TestNoStarvationOnNonRelayConnection)5181 TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,
5182 TestNoStarvationOnNonRelayConnection) {
5183 P2PTransportChannel& ch = StartTransportChannel(true, 500, &field_trials_);
5184 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
5185 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
5186 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
5187
5188 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
5189 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
5190
5191 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
5192 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
5193
5194 // Next, ping Local/Relay.
5195 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
5196
5197 // Remote Local candidate arrives.
5198 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
5199 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
5200
5201 // Local/Local should be the first since it hasn't been pinged before.
5202 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
5203
5204 // Relay/Local is the final one.
5205 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
5206
5207 // Now, every connection has been pinged once. The next one should be
5208 // Relay/Relay.
5209 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
5210 }
5211
5212 // Test skip_relay_to_non_relay_connections field-trial.
5213 // I.e that we never create connection between relay and non-relay.
TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,TestSkipRelayToNonRelayConnectionsFieldTrial)5214 TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,
5215 TestSkipRelayToNonRelayConnectionsFieldTrial) {
5216 webrtc::test::ScopedKeyValueConfig field_trials(
5217 field_trials_,
5218 "WebRTC-IceFieldTrials/skip_relay_to_non_relay_connections:true/");
5219 P2PTransportChannel& ch = StartTransportChannel(true, 500, &field_trials);
5220 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
5221 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
5222 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
5223
5224 // Remote Relay candidate arrives.
5225 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
5226 EXPECT_TRUE_WAIT(ch.connections().size() == 1, kDefaultTimeout);
5227
5228 // Remote Local candidate arrives.
5229 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
5230 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
5231 }
5232
5233 // Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
5234 // followed by the rest.
TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest,TestTcpTurn)5235 TEST_P(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
5236 // Add a Tcp Turn server.
5237 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
5238 RelayServerConfig config;
5239 config.credentials = kRelayCredentials;
5240 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
5241 allocator()->AddTurnServerForTesting(config);
5242
5243 P2PTransportChannel& ch = StartTransportChannel(true, 500, &field_trials_);
5244 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
5245 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
5246 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
5247 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
5248
5249 // Remote Relay candidate arrives.
5250 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
5251 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
5252
5253 // UDP Relay/Relay should be pinged first.
5254 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
5255
5256 // TCP Relay/Relay is the next.
5257 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
5258 TCP_PROTOCOL_NAME);
5259
5260 // Finally, Local/Relay will be pinged.
5261 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
5262 }
5263
5264 class P2PTransportChannelResolverTest : public TestWithParam<std::string> {};
5265
5266 INSTANTIATE_TEST_SUITE_P(Legacy, P2PTransportChannelResolverTest, Values(""));
5267 INSTANTIATE_TEST_SUITE_P(Active,
5268 P2PTransportChannelResolverTest,
5269 Values("WebRTC-UseActiveIceController/Enabled/"));
5270
5271 // Test that a resolver is created, asked for a result, and destroyed
5272 // when the address is a hostname. The destruction should happen even
5273 // if the channel is not destroyed.
TEST_P(P2PTransportChannelResolverTest,HostnameCandidateIsResolved)5274 TEST_P(P2PTransportChannelResolverTest, HostnameCandidateIsResolved) {
5275 ResolverFactoryFixture resolver_fixture;
5276 std::unique_ptr<rtc::SocketServer> socket_server =
5277 rtc::CreateDefaultSocketServer();
5278 rtc::AutoSocketServerThread main_thread(socket_server.get());
5279 rtc::BasicPacketSocketFactory packet_socket_factory(socket_server.get());
5280 FakePortAllocator allocator(rtc::Thread::Current(), &packet_socket_factory);
5281 webrtc::test::ScopedKeyValueConfig field_trials(GetParam());
5282 webrtc::IceTransportInit init;
5283 init.set_port_allocator(&allocator);
5284 init.set_async_dns_resolver_factory(&resolver_fixture);
5285 init.set_field_trials(&field_trials);
5286 auto channel = P2PTransportChannel::Create("tn", 0, std::move(init));
5287 Candidate hostname_candidate;
5288 SocketAddress hostname_address("fake.test", 1000);
5289 hostname_candidate.set_address(hostname_address);
5290 channel->AddRemoteCandidate(hostname_candidate);
5291
5292 ASSERT_EQ_WAIT(1u, channel->remote_candidates().size(), kDefaultTimeout);
5293 const RemoteCandidate& candidate = channel->remote_candidates()[0];
5294 EXPECT_FALSE(candidate.address().IsUnresolvedIP());
5295 }
5296
5297 // Test that if we signal a hostname candidate after the remote endpoint
5298 // discovers a prflx remote candidate with the same underlying IP address, the
5299 // prflx candidate is updated to a host candidate after the name resolution is
5300 // done.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveCandidateBeforeSignalingWithMdnsName)5301 TEST_P(P2PTransportChannelTestWithFieldTrials,
5302 PeerReflexiveCandidateBeforeSignalingWithMdnsName) {
5303 // ep1 and ep2 will only gather host candidates with addresses
5304 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
5305 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
5306 // ICE parameter will be set up when creating the channels.
5307 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5308 GetEndpoint(0)->network_manager_.set_mdns_responder(
5309 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
5310
5311 ResolverFactoryFixture resolver_fixture;
5312 GetEndpoint(1)->async_dns_resolver_factory_ = &resolver_fixture;
5313 CreateChannels();
5314 // Pause sending candidates from both endpoints until we find out what port
5315 // number is assgined to ep1's host candidate.
5316 PauseCandidates(0);
5317 PauseCandidates(1);
5318 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5319 const auto& local_candidate = GetEndpoint(0)->saved_candidates_[0].candidate;
5320 // The IP address of ep1's host candidate should be obfuscated.
5321 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
5322 // This is the underlying private IP address of the same candidate at ep1.
5323 const auto local_address = rtc::SocketAddress(
5324 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
5325
5326 // Let ep2 signal its candidate to ep1. ep1 should form a candidate
5327 // pair and start to ping. After receiving the ping, ep2 discovers a prflx
5328 // remote candidate and form a candidate pair as well.
5329 ResumeCandidates(1);
5330 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
5331 // ep2 should have the selected connection connected to the prflx remote
5332 // candidate.
5333 const Connection* selected_connection = nullptr;
5334 ASSERT_TRUE_WAIT(
5335 (selected_connection = ep2_ch1()->selected_connection()) != nullptr,
5336 kMediumTimeout);
5337 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
5338 EXPECT_EQ(kIceUfrag[0], selected_connection->remote_candidate().username());
5339 EXPECT_EQ(kIcePwd[0], selected_connection->remote_candidate().password());
5340 // Set expectation before ep1 signals a hostname candidate.
5341 resolver_fixture.SetAddressToReturn(local_address);
5342 ResumeCandidates(0);
5343 // Verify ep2's selected connection is updated to use the 'local' candidate.
5344 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
5345 ep2_ch1()->selected_connection()->remote_candidate().type(),
5346 kMediumTimeout);
5347 EXPECT_EQ(selected_connection, ep2_ch1()->selected_connection());
5348
5349 DestroyChannels();
5350 }
5351
5352 // Test that if we discover a prflx candidate during the process of name
5353 // resolution for a remote hostname candidate, we update the prflx candidate to
5354 // a host candidate if the hostname candidate turns out to have the same IP
5355 // address after the resolution completes.
TEST_P(P2PTransportChannelTestWithFieldTrials,PeerReflexiveCandidateDuringResolvingHostCandidateWithMdnsName)5356 TEST_P(P2PTransportChannelTestWithFieldTrials,
5357 PeerReflexiveCandidateDuringResolvingHostCandidateWithMdnsName) {
5358 ResolverFactoryFixture resolver_fixture;
5359 // Prevent resolution until triggered by FireDelayedResolution.
5360 resolver_fixture.DelayResolution();
5361
5362 // ep1 and ep2 will only gather host candidates with addresses
5363 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
5364 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
5365 // ICE parameter will be set up when creating the channels.
5366 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5367 GetEndpoint(0)->network_manager_.set_mdns_responder(
5368 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
5369 GetEndpoint(1)->async_dns_resolver_factory_ = &resolver_fixture;
5370 CreateChannels();
5371 // Pause sending candidates from both endpoints until we find out what port
5372 // number is assgined to ep1's host candidate.
5373 PauseCandidates(0);
5374 PauseCandidates(1);
5375
5376 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5377 const auto& local_candidate = GetEndpoint(0)->saved_candidates_[0].candidate;
5378 // The IP address of ep1's host candidate should be obfuscated.
5379 ASSERT_TRUE(local_candidate.address().IsUnresolvedIP());
5380 // This is the underlying private IP address of the same candidate at ep1.
5381 const auto local_address = rtc::SocketAddress(
5382 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
5383 // Let ep1 signal its hostname candidate to ep2.
5384 ResumeCandidates(0);
5385 // Now that ep2 is in the process of resolving the hostname candidate signaled
5386 // by ep1. Let ep2 signal its host candidate with an IP address to ep1, so
5387 // that ep1 can form a candidate pair, select it and start to ping ep2.
5388 ResumeCandidates(1);
5389 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
5390 // Let the mock resolver of ep2 receives the correct resolution.
5391 resolver_fixture.SetAddressToReturn(local_address);
5392
5393 // Upon receiving a ping from ep1, ep2 adds a prflx candidate from the
5394 // unknown address and establishes a connection.
5395 //
5396 // There is a caveat in our implementation associated with this expectation.
5397 // See the big comment in P2PTransportChannel::OnUnknownAddress.
5398 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
5399 EXPECT_EQ(PRFLX_PORT_TYPE,
5400 ep2_ch1()->selected_connection()->remote_candidate().type());
5401 // ep2 should also be able resolve the hostname candidate. The resolved remote
5402 // host candidate should be merged with the prflx remote candidate.
5403
5404 resolver_fixture.FireDelayedResolution();
5405
5406 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
5407 ep2_ch1()->selected_connection()->remote_candidate().type(),
5408 kMediumTimeout);
5409 EXPECT_EQ(1u, ep2_ch1()->remote_candidates().size());
5410
5411 DestroyChannels();
5412 }
5413
5414 // Test that if we only gather and signal a host candidate, the IP address of
5415 // which is obfuscated by an mDNS name, and if the peer can complete the name
5416 // resolution with the correct IP address, we can have a p2p connection.
TEST_P(P2PTransportChannelTestWithFieldTrials,CanConnectWithHostCandidateWithMdnsName)5417 TEST_P(P2PTransportChannelTestWithFieldTrials,
5418 CanConnectWithHostCandidateWithMdnsName) {
5419 ResolverFactoryFixture resolver_fixture;
5420
5421 // ep1 and ep2 will only gather host candidates with addresses
5422 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
5423 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
5424 // ICE parameter will be set up when creating the channels.
5425 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5426 GetEndpoint(0)->network_manager_.set_mdns_responder(
5427 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
5428 GetEndpoint(1)->async_dns_resolver_factory_ = &resolver_fixture;
5429 CreateChannels();
5430 // Pause sending candidates from both endpoints until we find out what port
5431 // number is assgined to ep1's host candidate.
5432 PauseCandidates(0);
5433 PauseCandidates(1);
5434 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5435 const auto& local_candidate_ep1 =
5436 GetEndpoint(0)->saved_candidates_[0].candidate;
5437 // The IP address of ep1's host candidate should be obfuscated.
5438 EXPECT_TRUE(local_candidate_ep1.address().IsUnresolvedIP());
5439 // This is the underlying private IP address of the same candidate at ep1,
5440 // and let the mock resolver of ep2 receive the correct resolution.
5441 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
5442 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
5443
5444 resolver_fixture.SetAddressToReturn(resolved_address_ep1);
5445 // Let ep1 signal its hostname candidate to ep2.
5446 ResumeCandidates(0);
5447
5448 // We should be able to receive a ping from ep2 and establish a connection
5449 // with a peer reflexive candidate from ep2.
5450 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
5451 kMediumTimeout);
5452 EXPECT_EQ(LOCAL_PORT_TYPE,
5453 ep1_ch1()->selected_connection()->local_candidate().type());
5454 EXPECT_EQ(PRFLX_PORT_TYPE,
5455 ep1_ch1()->selected_connection()->remote_candidate().type());
5456
5457 DestroyChannels();
5458 }
5459
5460 // Test that when the IP of a host candidate is concealed by an mDNS name, the
5461 // stats from the gathering ICE endpoint do not reveal the address of this local
5462 // host candidate or the related address of a local srflx candidate from the
5463 // same endpoint. Also, the remote ICE endpoint that successfully resolves a
5464 // signaled host candidate with an mDNS name should not reveal the address of
5465 // this remote host candidate in stats.
TEST_P(P2PTransportChannelTestWithFieldTrials,CandidatesSanitizedInStatsWhenMdnsObfuscationEnabled)5466 TEST_P(P2PTransportChannelTestWithFieldTrials,
5467 CandidatesSanitizedInStatsWhenMdnsObfuscationEnabled) {
5468 ResolverFactoryFixture resolver_fixture;
5469
5470 // ep1 and ep2 will gather host candidates with addresses
5471 // kPublicAddrs[0] and kPublicAddrs[1], respectively. ep1 also gathers a srflx
5472 // and a relay candidates.
5473 ConfigureEndpoints(OPEN, OPEN,
5474 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_TCP,
5475 kOnlyLocalPorts);
5476 // ICE parameter will be set up when creating the channels.
5477 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5478 GetEndpoint(0)->network_manager_.set_mdns_responder(
5479 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
5480 GetEndpoint(1)->async_dns_resolver_factory_ = &resolver_fixture;
5481 CreateChannels();
5482 // Pause sending candidates from both endpoints until we find out what port
5483 // number is assigned to ep1's host candidate.
5484 PauseCandidates(0);
5485 PauseCandidates(1);
5486 // Ep1 has a UDP host, a srflx and a relay candidates.
5487 ASSERT_EQ_WAIT(3u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5488 ASSERT_EQ_WAIT(1u, GetEndpoint(1)->saved_candidates_.size(), kMediumTimeout);
5489
5490 for (const auto& candidates_data : GetEndpoint(0)->saved_candidates_) {
5491 const auto& local_candidate_ep1 = candidates_data.candidate;
5492 if (local_candidate_ep1.type() == LOCAL_PORT_TYPE) {
5493 // This is the underlying private IP address of the same candidate at ep1,
5494 // and let the mock resolver of ep2 receive the correct resolution.
5495 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
5496 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
5497 resolver_fixture.SetAddressToReturn(resolved_address_ep1);
5498 break;
5499 }
5500 }
5501 ResumeCandidates(0);
5502 ResumeCandidates(1);
5503
5504 ASSERT_EQ_WAIT(kIceGatheringComplete, ep1_ch1()->gathering_state(),
5505 kMediumTimeout);
5506 // We should have the following candidate pairs on both endpoints:
5507 // ep1_host <-> ep2_host, ep1_srflx <-> ep2_host, ep1_relay <-> ep2_host
5508 ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout);
5509 ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout);
5510
5511 IceTransportStats ice_transport_stats1;
5512 IceTransportStats ice_transport_stats2;
5513 ep1_ch1()->GetStats(&ice_transport_stats1);
5514 ep2_ch1()->GetStats(&ice_transport_stats2);
5515 EXPECT_EQ(3u, ice_transport_stats1.connection_infos.size());
5516 EXPECT_EQ(3u, ice_transport_stats1.candidate_stats_list.size());
5517 EXPECT_EQ(3u, ice_transport_stats2.connection_infos.size());
5518 // Check the stats of ep1 seen by ep1.
5519 for (const auto& connection_info : ice_transport_stats1.connection_infos) {
5520 const auto& local_candidate = connection_info.local_candidate;
5521 if (local_candidate.type() == LOCAL_PORT_TYPE) {
5522 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
5523 } else if (local_candidate.type() == STUN_PORT_TYPE) {
5524 EXPECT_TRUE(local_candidate.related_address().IsAnyIP());
5525 } else if (local_candidate.type() == RELAY_PORT_TYPE) {
5526 // The related address of the relay candidate should be equal to the
5527 // srflx address. Note that NAT is not configured, hence the following
5528 // expectation.
5529 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
5530 local_candidate.related_address().ipaddr());
5531 } else {
5532 FAIL();
5533 }
5534 }
5535 // Check the stats of ep1 seen by ep2.
5536 for (const auto& connection_info : ice_transport_stats2.connection_infos) {
5537 const auto& remote_candidate = connection_info.remote_candidate;
5538 if (remote_candidate.type() == LOCAL_PORT_TYPE) {
5539 EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP());
5540 } else if (remote_candidate.type() == STUN_PORT_TYPE) {
5541 EXPECT_TRUE(remote_candidate.related_address().IsAnyIP());
5542 } else if (remote_candidate.type() == RELAY_PORT_TYPE) {
5543 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
5544 remote_candidate.related_address().ipaddr());
5545 } else {
5546 FAIL();
5547 }
5548 }
5549 DestroyChannels();
5550 }
5551
TEST_P(P2PTransportChannelTestWithFieldTrials,ConnectingIncreasesSelectedCandidatePairChanges)5552 TEST_P(P2PTransportChannelTestWithFieldTrials,
5553 ConnectingIncreasesSelectedCandidatePairChanges) {
5554 rtc::ScopedFakeClock clock;
5555 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5556 kDefaultPortAllocatorFlags);
5557 CreateChannels();
5558
5559 IceTransportStats ice_transport_stats;
5560 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5561 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5562
5563 // Let the channels connect.
5564 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5565 kMediumTimeout, clock);
5566
5567 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5568 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5569
5570 DestroyChannels();
5571 }
5572
TEST_P(P2PTransportChannelTestWithFieldTrials,DisconnectedIncreasesSelectedCandidatePairChanges)5573 TEST_P(P2PTransportChannelTestWithFieldTrials,
5574 DisconnectedIncreasesSelectedCandidatePairChanges) {
5575 rtc::ScopedFakeClock clock;
5576 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5577 kDefaultPortAllocatorFlags);
5578 CreateChannels();
5579
5580 IceTransportStats ice_transport_stats;
5581 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5582 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5583
5584 // Let the channels connect.
5585 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5586 kMediumTimeout, clock);
5587
5588 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5589 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5590
5591 // Prune connections and wait for disconnect.
5592 for (Connection* con : ep1_ch1()->connections()) {
5593 con->Prune();
5594 }
5595 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() == nullptr,
5596 kMediumTimeout, clock);
5597
5598 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5599 EXPECT_EQ(2u, ice_transport_stats.selected_candidate_pair_changes);
5600
5601 DestroyChannels();
5602 }
5603
TEST_P(P2PTransportChannelTestWithFieldTrials,NewSelectionIncreasesSelectedCandidatePairChanges)5604 TEST_P(P2PTransportChannelTestWithFieldTrials,
5605 NewSelectionIncreasesSelectedCandidatePairChanges) {
5606 rtc::ScopedFakeClock clock;
5607 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5608 kDefaultPortAllocatorFlags);
5609 CreateChannels();
5610
5611 IceTransportStats ice_transport_stats;
5612 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5613 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5614
5615 // Let the channels connect.
5616 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5617 kMediumTimeout, clock);
5618
5619 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5620 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5621
5622 // Prune the currently selected connection and wait for selection
5623 // of a new one.
5624 const Connection* selected_connection = ep1_ch1()->selected_connection();
5625 for (Connection* con : ep1_ch1()->connections()) {
5626 if (con == selected_connection) {
5627 con->Prune();
5628 }
5629 }
5630 EXPECT_TRUE_SIMULATED_WAIT(
5631 ep1_ch1()->selected_connection() != nullptr &&
5632 (ep1_ch1()->GetStats(&ice_transport_stats),
5633 ice_transport_stats.selected_candidate_pair_changes >= 2u),
5634 kMediumTimeout, clock);
5635
5636 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5637 EXPECT_GE(ice_transport_stats.selected_candidate_pair_changes, 2u);
5638
5639 DestroyChannels();
5640 }
5641
5642 // A similar test as above to check the selected candidate pair is sanitized
5643 // when it is queried via GetSelectedCandidatePair.
TEST_P(P2PTransportChannelTestWithFieldTrials,SelectedCandidatePairSanitizedWhenMdnsObfuscationEnabled)5644 TEST_P(P2PTransportChannelTestWithFieldTrials,
5645 SelectedCandidatePairSanitizedWhenMdnsObfuscationEnabled) {
5646 ResolverFactoryFixture resolver_fixture;
5647
5648 // ep1 and ep2 will gather host candidates with addresses
5649 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
5650 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
5651 // ICE parameter will be set up when creating the channels.
5652 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5653 GetEndpoint(0)->network_manager_.set_mdns_responder(
5654 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
5655 GetEndpoint(1)->async_dns_resolver_factory_ = &resolver_fixture;
5656 CreateChannels();
5657 // Pause sending candidates from both endpoints until we find out what port
5658 // number is assigned to ep1's host candidate.
5659 PauseCandidates(0);
5660 PauseCandidates(1);
5661 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5662 const auto& candidates_data = GetEndpoint(0)->saved_candidates_[0];
5663 const auto& local_candidate_ep1 = candidates_data.candidate;
5664 ASSERT_TRUE(local_candidate_ep1.type() == LOCAL_PORT_TYPE);
5665 // This is the underlying private IP address of the same candidate at ep1,
5666 // and let the mock resolver of ep2 receive the correct resolution.
5667 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
5668 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
5669 resolver_fixture.SetAddressToReturn(resolved_address_ep1);
5670
5671 ResumeCandidates(0);
5672 ResumeCandidates(1);
5673
5674 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr &&
5675 ep2_ch1()->selected_connection() != nullptr,
5676 kMediumTimeout);
5677
5678 const auto pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
5679 ASSERT_TRUE(pair_ep1.has_value());
5680 EXPECT_EQ(LOCAL_PORT_TYPE, pair_ep1->local_candidate().type());
5681 EXPECT_TRUE(pair_ep1->local_candidate().address().IsUnresolvedIP());
5682
5683 const auto pair_ep2 = ep2_ch1()->GetSelectedCandidatePair();
5684 ASSERT_TRUE(pair_ep2.has_value());
5685 EXPECT_EQ(LOCAL_PORT_TYPE, pair_ep2->remote_candidate().type());
5686 EXPECT_TRUE(pair_ep2->remote_candidate().address().IsUnresolvedIP());
5687
5688 DestroyChannels();
5689 }
5690
TEST_P(P2PTransportChannelTestWithFieldTrials,NoPairOfLocalRelayCandidateWithRemoteMdnsCandidate)5691 TEST_P(P2PTransportChannelTestWithFieldTrials,
5692 NoPairOfLocalRelayCandidateWithRemoteMdnsCandidate) {
5693 const int kOnlyRelayPorts = cricket::PORTALLOCATOR_DISABLE_UDP |
5694 cricket::PORTALLOCATOR_DISABLE_STUN |
5695 cricket::PORTALLOCATOR_DISABLE_TCP;
5696 // We use one endpoint to test the behavior of adding remote candidates, and
5697 // this endpoint only gathers relay candidates.
5698 ConfigureEndpoints(OPEN, OPEN, kOnlyRelayPorts, kDefaultPortAllocatorFlags);
5699 GetEndpoint(0)->cd1_.ch_ = CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
5700 kIceParams[0], kIceParams[1]);
5701 IceConfig config;
5702 // Start gathering and we should have only a single relay port.
5703 ep1_ch1()->SetIceConfig(config);
5704 ep1_ch1()->MaybeStartGathering();
5705 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
5706 ep1_ch1()->gathering_state(), kDefaultTimeout);
5707 EXPECT_EQ(1u, ep1_ch1()->ports().size());
5708 // Add a plain remote host candidate and three remote mDNS candidates with the
5709 // host, srflx and relay types. Note that the candidates differ in their
5710 // ports.
5711 cricket::Candidate host_candidate = CreateUdpCandidate(
5712 LOCAL_PORT_TYPE, "1.1.1.1", 1 /* port */, 0 /* priority */);
5713 ep1_ch1()->AddRemoteCandidate(host_candidate);
5714
5715 std::vector<cricket::Candidate> mdns_candidates;
5716 mdns_candidates.push_back(CreateUdpCandidate(LOCAL_PORT_TYPE, "example.local",
5717 2 /* port */, 0 /* priority */));
5718 mdns_candidates.push_back(CreateUdpCandidate(STUN_PORT_TYPE, "example.local",
5719 3 /* port */, 0 /* priority */));
5720 mdns_candidates.push_back(CreateUdpCandidate(RELAY_PORT_TYPE, "example.local",
5721 4 /* port */, 0 /* priority */));
5722 // We just resolve the hostname to 1.1.1.1, and add the candidates with this
5723 // address directly to simulate the process of adding remote candidates with
5724 // the name resolution.
5725 for (auto& mdns_candidate : mdns_candidates) {
5726 rtc::SocketAddress resolved_address(mdns_candidate.address());
5727 resolved_address.SetResolvedIP(0x1111); // 1.1.1.1
5728 mdns_candidate.set_address(resolved_address);
5729 EXPECT_FALSE(mdns_candidate.address().IsUnresolvedIP());
5730 ep1_ch1()->AddRemoteCandidate(mdns_candidate);
5731 }
5732
5733 // All remote candidates should have been successfully added.
5734 EXPECT_EQ(4u, ep1_ch1()->remote_candidates().size());
5735
5736 // Expect that there is no connection paired with any mDNS candidate.
5737 ASSERT_EQ(1u, ep1_ch1()->connections().size());
5738 ASSERT_NE(nullptr, ep1_ch1()->connections()[0]);
5739 EXPECT_EQ(
5740 "1.1.1.1:1",
5741 ep1_ch1()->connections()[0]->remote_candidate().address().ToString());
5742 DestroyChannels();
5743 }
5744
5745 class MockMdnsResponder : public webrtc::MdnsResponderInterface {
5746 public:
5747 MOCK_METHOD(void,
5748 CreateNameForAddress,
5749 (const rtc::IPAddress&, NameCreatedCallback),
5750 (override));
5751 MOCK_METHOD(void,
5752 RemoveNameForAddress,
5753 (const rtc::IPAddress&, NameRemovedCallback),
5754 (override));
5755 };
5756
TEST_P(P2PTransportChannelTestWithFieldTrials,SrflxCandidateCanBeGatheredBeforeMdnsCandidateToCreateConnection)5757 TEST_P(P2PTransportChannelTestWithFieldTrials,
5758 SrflxCandidateCanBeGatheredBeforeMdnsCandidateToCreateConnection) {
5759 // ep1 and ep2 will only gather host and srflx candidates with base addresses
5760 // kPublicAddrs[0] and kPublicAddrs[1], respectively, and we use a shared
5761 // socket in gathering.
5762 const auto kOnlyLocalAndStunPorts =
5763 cricket::PORTALLOCATOR_DISABLE_RELAY |
5764 cricket::PORTALLOCATOR_DISABLE_TCP |
5765 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET;
5766 // ep1 is configured with a NAT so that we do gather a srflx candidate.
5767 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kOnlyLocalAndStunPorts,
5768 kOnlyLocalAndStunPorts);
5769 // ICE parameter will be set up when creating the channels.
5770 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5771 // Use a mock mDNS responder, which does not complete the name registration by
5772 // ignoring the completion callback.
5773 auto mock_mdns_responder = std::make_unique<MockMdnsResponder>();
5774 EXPECT_CALL(*mock_mdns_responder, CreateNameForAddress(_, _))
5775 .Times(1)
5776 .WillOnce(Return());
5777 GetEndpoint(0)->network_manager_.set_mdns_responder(
5778 std::move(mock_mdns_responder));
5779
5780 CreateChannels();
5781
5782 // We should be able to form a srflx-host connection to ep2.
5783 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
5784 kMediumTimeout);
5785 EXPECT_EQ(STUN_PORT_TYPE,
5786 ep1_ch1()->selected_connection()->local_candidate().type());
5787 EXPECT_EQ(LOCAL_PORT_TYPE,
5788 ep1_ch1()->selected_connection()->remote_candidate().type());
5789
5790 DestroyChannels();
5791 }
5792
5793 // Test that after changing the candidate filter from relay-only to allowing all
5794 // types of candidates when doing continual gathering, we can gather without ICE
5795 // restart the other types of candidates that are now enabled and form candidate
5796 // pairs. Also, we verify that the relay candidates gathered previously are not
5797 // removed and are still usable for necessary route switching.
TEST_P(P2PTransportChannelTestWithFieldTrials,SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll)5798 TEST_P(P2PTransportChannelTestWithFieldTrials,
5799 SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll) {
5800 rtc::ScopedFakeClock clock;
5801
5802 ConfigureEndpoints(
5803 OPEN, OPEN,
5804 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5805 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5806 auto* ep1 = GetEndpoint(0);
5807 auto* ep2 = GetEndpoint(1);
5808 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5809 ep2->allocator_->SetCandidateFilter(CF_RELAY);
5810 // Enable continual gathering and also resurfacing gathered candidates upon
5811 // the candidate filter changed in the ICE configuration.
5812 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5813 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5814 CreateChannels(ice_config, ice_config);
5815 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5816 kDefaultTimeout, clock);
5817 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5818 kDefaultTimeout, clock);
5819 EXPECT_EQ(RELAY_PORT_TYPE,
5820 ep1_ch1()->selected_connection()->local_candidate().type());
5821 EXPECT_EQ(RELAY_PORT_TYPE,
5822 ep2_ch1()->selected_connection()->local_candidate().type());
5823
5824 // Loosen the candidate filter at ep1.
5825 ep1->allocator_->SetCandidateFilter(CF_ALL);
5826 EXPECT_TRUE_SIMULATED_WAIT(
5827 ep1_ch1()->selected_connection() != nullptr &&
5828 ep1_ch1()->selected_connection()->local_candidate().type() ==
5829 LOCAL_PORT_TYPE,
5830 kDefaultTimeout, clock);
5831 EXPECT_EQ(RELAY_PORT_TYPE,
5832 ep1_ch1()->selected_connection()->remote_candidate().type());
5833
5834 // Loosen the candidate filter at ep2.
5835 ep2->allocator_->SetCandidateFilter(CF_ALL);
5836 EXPECT_TRUE_SIMULATED_WAIT(
5837 ep2_ch1()->selected_connection() != nullptr &&
5838 ep2_ch1()->selected_connection()->local_candidate().type() ==
5839 LOCAL_PORT_TYPE,
5840 kDefaultTimeout, clock);
5841 // We have migrated to a host-host candidate pair.
5842 EXPECT_EQ(LOCAL_PORT_TYPE,
5843 ep2_ch1()->selected_connection()->remote_candidate().type());
5844
5845 // Block the traffic over non-relay-to-relay routes and expect a route change.
5846 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kPublicAddrs[1]);
5847 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kPublicAddrs[0]);
5848 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kTurnUdpExtAddr);
5849 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kTurnUdpExtAddr);
5850
5851 // We should be able to reuse the previously gathered relay candidates.
5852 EXPECT_EQ_SIMULATED_WAIT(
5853 RELAY_PORT_TYPE,
5854 ep1_ch1()->selected_connection()->local_candidate().type(),
5855 kDefaultTimeout, clock);
5856 EXPECT_EQ(RELAY_PORT_TYPE,
5857 ep1_ch1()->selected_connection()->remote_candidate().type());
5858 DestroyChannels();
5859 }
5860
5861 // A similar test as SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll,
5862 // and we should surface server-reflexive candidates that are enabled after
5863 // changing the candidate filter.
TEST_P(P2PTransportChannelTestWithFieldTrials,SurfaceSrflxCandidateOnCandidateFilterChangeFromRelayToNoHost)5864 TEST_P(P2PTransportChannelTestWithFieldTrials,
5865 SurfaceSrflxCandidateOnCandidateFilterChangeFromRelayToNoHost) {
5866 rtc::ScopedFakeClock clock;
5867 // We need an actual NAT so that the host candidate is not equivalent to the
5868 // srflx candidate; otherwise, the host candidate would still surface even
5869 // though we disable it via the candidate filter below. This is a result of
5870 // the following limitation in the current implementation:
5871 // 1. We don't generate the srflx candidate when we have public IP.
5872 // 2. We keep the host candidate in this case in CheckCandidateFilter even
5873 // though we intend to filter them.
5874 ConfigureEndpoints(
5875 NAT_FULL_CONE, NAT_FULL_CONE,
5876 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5877 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5878 auto* ep1 = GetEndpoint(0);
5879 auto* ep2 = GetEndpoint(1);
5880 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5881 ep2->allocator_->SetCandidateFilter(CF_RELAY);
5882 // Enable continual gathering and also resurfacing gathered candidates upon
5883 // the candidate filter changed in the ICE configuration.
5884 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5885 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5886 CreateChannels(ice_config, ice_config);
5887 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5888 kDefaultTimeout, clock);
5889 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5890 kDefaultTimeout, clock);
5891 const uint32_t kCandidateFilterNoHost = CF_ALL & ~CF_HOST;
5892 // Loosen the candidate filter at ep1.
5893 ep1->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5894 EXPECT_TRUE_SIMULATED_WAIT(
5895 ep1_ch1()->selected_connection() != nullptr &&
5896 ep1_ch1()->selected_connection()->local_candidate().type() ==
5897 STUN_PORT_TYPE,
5898 kDefaultTimeout, clock);
5899 EXPECT_EQ(RELAY_PORT_TYPE,
5900 ep1_ch1()->selected_connection()->remote_candidate().type());
5901
5902 // Loosen the candidate filter at ep2.
5903 ep2->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5904 EXPECT_TRUE_SIMULATED_WAIT(
5905 ep2_ch1()->selected_connection() != nullptr &&
5906 ep2_ch1()->selected_connection()->local_candidate().type() ==
5907 STUN_PORT_TYPE,
5908 kDefaultTimeout, clock);
5909 // We have migrated to a srflx-srflx candidate pair.
5910 EXPECT_EQ(STUN_PORT_TYPE,
5911 ep2_ch1()->selected_connection()->remote_candidate().type());
5912
5913 // Block the traffic over non-relay-to-relay routes and expect a route change.
5914 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kPublicAddrs[1]);
5915 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kPublicAddrs[0]);
5916 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kTurnUdpExtAddr);
5917 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kTurnUdpExtAddr);
5918 // We should be able to reuse the previously gathered relay candidates.
5919 EXPECT_EQ_SIMULATED_WAIT(
5920 RELAY_PORT_TYPE,
5921 ep1_ch1()->selected_connection()->local_candidate().type(),
5922 kDefaultTimeout, clock);
5923 EXPECT_EQ(RELAY_PORT_TYPE,
5924 ep1_ch1()->selected_connection()->remote_candidate().type());
5925 DestroyChannels();
5926 }
5927
5928 // This is the complement to
5929 // SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll, and instead of
5930 // gathering continually we only gather once, which makes the config
5931 // `surface_ice_candidates_on_ice_transport_type_changed` ineffective after the
5932 // gathering stopped.
TEST_P(P2PTransportChannelTestWithFieldTrials,CannotSurfaceTheNewlyAllowedOnFilterChangeIfNotGatheringContinually)5933 TEST_P(P2PTransportChannelTestWithFieldTrials,
5934 CannotSurfaceTheNewlyAllowedOnFilterChangeIfNotGatheringContinually) {
5935 rtc::ScopedFakeClock clock;
5936
5937 ConfigureEndpoints(
5938 OPEN, OPEN,
5939 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5940 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5941 auto* ep1 = GetEndpoint(0);
5942 auto* ep2 = GetEndpoint(1);
5943 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5944 ep2->allocator_->SetCandidateFilter(CF_RELAY);
5945 // Only gather once.
5946 IceConfig ice_config = CreateIceConfig(1000, GATHER_ONCE);
5947 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5948 CreateChannels(ice_config, ice_config);
5949 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5950 kDefaultTimeout, clock);
5951 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5952 kDefaultTimeout, clock);
5953 // Loosen the candidate filter at ep1.
5954 ep1->allocator_->SetCandidateFilter(CF_ALL);
5955 // Wait for a period for any potential surfacing of new candidates.
5956 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5957 EXPECT_EQ(RELAY_PORT_TYPE,
5958 ep1_ch1()->selected_connection()->local_candidate().type());
5959
5960 // Loosen the candidate filter at ep2.
5961 ep2->allocator_->SetCandidateFilter(CF_ALL);
5962 EXPECT_EQ(RELAY_PORT_TYPE,
5963 ep2_ch1()->selected_connection()->local_candidate().type());
5964 DestroyChannels();
5965 }
5966
5967 // Test that when the candidate filter is updated to be more restrictive,
5968 // candidates that 1) have already been gathered and signaled 2) but no longer
5969 // match the filter, are not removed.
TEST_P(P2PTransportChannelTestWithFieldTrials,RestrictingCandidateFilterDoesNotRemoveRegatheredCandidates)5970 TEST_P(P2PTransportChannelTestWithFieldTrials,
5971 RestrictingCandidateFilterDoesNotRemoveRegatheredCandidates) {
5972 rtc::ScopedFakeClock clock;
5973
5974 ConfigureEndpoints(
5975 OPEN, OPEN,
5976 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5977 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5978 auto* ep1 = GetEndpoint(0);
5979 auto* ep2 = GetEndpoint(1);
5980 ep1->allocator_->SetCandidateFilter(CF_ALL);
5981 ep2->allocator_->SetCandidateFilter(CF_ALL);
5982 // Enable continual gathering and also resurfacing gathered candidates upon
5983 // the candidate filter changed in the ICE configuration.
5984 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5985 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5986 // Pause candidates so we can gather all types of candidates. See
5987 // P2PTransportChannel::OnConnectionStateChange, where we would stop the
5988 // gathering when we have a strongly connected candidate pair.
5989 PauseCandidates(0);
5990 PauseCandidates(1);
5991 CreateChannels(ice_config, ice_config);
5992
5993 // We have gathered host, srflx and relay candidates.
5994 EXPECT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 3u,
5995 kDefaultTimeout, clock);
5996 ResumeCandidates(0);
5997 ResumeCandidates(1);
5998 ASSERT_TRUE_SIMULATED_WAIT(
5999 ep1_ch1()->selected_connection() != nullptr &&
6000 LOCAL_PORT_TYPE ==
6001 ep1_ch1()->selected_connection()->local_candidate().type() &&
6002 ep2_ch1()->selected_connection() != nullptr &&
6003 LOCAL_PORT_TYPE ==
6004 ep1_ch1()->selected_connection()->remote_candidate().type(),
6005 kDefaultTimeout, clock);
6006 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
6007 kDefaultTimeout, clock);
6008 // Test that we have a host-host candidate pair selected and the number of
6009 // candidates signaled to the remote peer stays the same.
6010 auto test_invariants = [this]() {
6011 EXPECT_EQ(LOCAL_PORT_TYPE,
6012 ep1_ch1()->selected_connection()->local_candidate().type());
6013 EXPECT_EQ(LOCAL_PORT_TYPE,
6014 ep1_ch1()->selected_connection()->remote_candidate().type());
6015 EXPECT_THAT(ep2_ch1()->remote_candidates(), SizeIs(3));
6016 };
6017
6018 test_invariants();
6019
6020 // Set a more restrictive candidate filter at ep1.
6021 ep1->allocator_->SetCandidateFilter(CF_HOST | CF_REFLEXIVE);
6022 SIMULATED_WAIT(false, kDefaultTimeout, clock);
6023 test_invariants();
6024
6025 ep1->allocator_->SetCandidateFilter(CF_HOST);
6026 SIMULATED_WAIT(false, kDefaultTimeout, clock);
6027 test_invariants();
6028
6029 ep1->allocator_->SetCandidateFilter(CF_NONE);
6030 SIMULATED_WAIT(false, kDefaultTimeout, clock);
6031 test_invariants();
6032 DestroyChannels();
6033 }
6034
6035 // Verify that things break unless
6036 // - both parties use the surface_ice_candidates_on_ice_transport_type_changed
6037 // - both parties loosen candidate filter at the same time (approx.).
6038 //
6039 // i.e surface_ice_candidates_on_ice_transport_type_changed requires
6040 // coordination outside of webrtc to function properly.
TEST_P(P2PTransportChannelTestWithFieldTrials,SurfaceRequiresCoordination)6041 TEST_P(P2PTransportChannelTestWithFieldTrials, SurfaceRequiresCoordination) {
6042 webrtc::test::ScopedKeyValueConfig field_trials(
6043 field_trials_,
6044 "WebRTC-IceFieldTrials/skip_relay_to_non_relay_connections:true/");
6045 rtc::ScopedFakeClock clock;
6046
6047 ConfigureEndpoints(
6048 OPEN, OPEN,
6049 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
6050 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
6051 auto* ep1 = GetEndpoint(0);
6052 auto* ep2 = GetEndpoint(1);
6053 ep1->allocator_->SetCandidateFilter(CF_RELAY);
6054 ep2->allocator_->SetCandidateFilter(CF_ALL);
6055 // Enable continual gathering and also resurfacing gathered candidates upon
6056 // the candidate filter changed in the ICE configuration.
6057 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
6058 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
6059 // Pause candidates gathering so we can gather all types of candidates. See
6060 // P2PTransportChannel::OnConnectionStateChange, where we would stop the
6061 // gathering when we have a strongly connected candidate pair.
6062 PauseCandidates(0);
6063 PauseCandidates(1);
6064 CreateChannels(ice_config, ice_config);
6065
6066 // On the caller we only have relay,
6067 // on the callee we have host, srflx and relay.
6068 EXPECT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 1u,
6069 kDefaultTimeout, clock);
6070 EXPECT_TRUE_SIMULATED_WAIT(ep2->saved_candidates_.size() == 3u,
6071 kDefaultTimeout, clock);
6072
6073 ResumeCandidates(0);
6074 ResumeCandidates(1);
6075 ASSERT_TRUE_SIMULATED_WAIT(
6076 ep1_ch1()->selected_connection() != nullptr &&
6077 RELAY_PORT_TYPE ==
6078 ep1_ch1()->selected_connection()->local_candidate().type() &&
6079 ep2_ch1()->selected_connection() != nullptr &&
6080 RELAY_PORT_TYPE ==
6081 ep1_ch1()->selected_connection()->remote_candidate().type(),
6082 kDefaultTimeout, clock);
6083 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
6084 kDefaultTimeout, clock);
6085
6086 // Wait until the callee discards it's candidates
6087 // since they don't manage to connect.
6088 SIMULATED_WAIT(false, 300000, clock);
6089
6090 // And then loosen caller candidate filter.
6091 ep1->allocator_->SetCandidateFilter(CF_ALL);
6092
6093 SIMULATED_WAIT(false, kDefaultTimeout, clock);
6094
6095 // No p2p connection will be made, it will remain on relay.
6096 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr &&
6097 RELAY_PORT_TYPE ==
6098 ep1_ch1()->selected_connection()->local_candidate().type() &&
6099 ep2_ch1()->selected_connection() != nullptr &&
6100 RELAY_PORT_TYPE ==
6101 ep1_ch1()->selected_connection()->remote_candidate().type());
6102
6103 DestroyChannels();
6104 }
6105
TEST_P(P2PTransportChannelPingTest,TestInitialSelectDampening0)6106 TEST_P(P2PTransportChannelPingTest, TestInitialSelectDampening0) {
6107 webrtc::test::ScopedKeyValueConfig field_trials(
6108 field_trials_, "WebRTC-IceFieldTrials/initial_select_dampening:0/");
6109
6110 constexpr int kMargin = 10;
6111 rtc::ScopedFakeClock clock;
6112 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
6113
6114 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
6115 P2PTransportChannel ch("test channel", 1, &pa, &field_trials);
6116 PrepareChannel(&ch);
6117 ch.SetIceConfig(ch.config());
6118 ch.MaybeStartGathering();
6119
6120 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
6121 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
6122 ASSERT_TRUE(conn1 != nullptr);
6123 EXPECT_EQ(nullptr, ch.selected_connection());
6124 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
6125 // It shall not be selected until 0ms has passed....i.e it should be connected
6126 // directly.
6127 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kMargin, clock);
6128 }
6129
TEST_P(P2PTransportChannelPingTest,TestInitialSelectDampening)6130 TEST_P(P2PTransportChannelPingTest, TestInitialSelectDampening) {
6131 webrtc::test::ScopedKeyValueConfig field_trials(
6132 field_trials_, "WebRTC-IceFieldTrials/initial_select_dampening:100/");
6133
6134 constexpr int kMargin = 10;
6135 rtc::ScopedFakeClock clock;
6136 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
6137
6138 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
6139 P2PTransportChannel ch("test channel", 1, &pa, &field_trials);
6140 PrepareChannel(&ch);
6141 ch.SetIceConfig(ch.config());
6142 ch.MaybeStartGathering();
6143
6144 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
6145 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
6146 ASSERT_TRUE(conn1 != nullptr);
6147 EXPECT_EQ(nullptr, ch.selected_connection());
6148 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
6149 // It shall not be selected until 100ms has passed.
6150 SIMULATED_WAIT(conn1 == ch.selected_connection(), 100 - kMargin, clock);
6151 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
6152 }
6153
TEST_P(P2PTransportChannelPingTest,TestInitialSelectDampeningPingReceived)6154 TEST_P(P2PTransportChannelPingTest, TestInitialSelectDampeningPingReceived) {
6155 webrtc::test::ScopedKeyValueConfig field_trials(
6156 field_trials_,
6157 "WebRTC-IceFieldTrials/initial_select_dampening_ping_received:100/");
6158
6159 constexpr int kMargin = 10;
6160 rtc::ScopedFakeClock clock;
6161 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
6162
6163 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
6164 P2PTransportChannel ch("test channel", 1, &pa, &field_trials);
6165 PrepareChannel(&ch);
6166 ch.SetIceConfig(ch.config());
6167 ch.MaybeStartGathering();
6168
6169 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
6170 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
6171 ASSERT_TRUE(conn1 != nullptr);
6172 EXPECT_EQ(nullptr, ch.selected_connection());
6173 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
6174 conn1->ReceivedPing("id1"); //
6175 // It shall not be selected until 100ms has passed.
6176 SIMULATED_WAIT(conn1 == ch.selected_connection(), 100 - kMargin, clock);
6177 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
6178 }
6179
TEST_P(P2PTransportChannelPingTest,TestInitialSelectDampeningBoth)6180 TEST_P(P2PTransportChannelPingTest, TestInitialSelectDampeningBoth) {
6181 webrtc::test::ScopedKeyValueConfig field_trials(
6182 field_trials_,
6183 "WebRTC-IceFieldTrials/"
6184 "initial_select_dampening:100,initial_select_dampening_ping_received:"
6185 "50/");
6186
6187 constexpr int kMargin = 10;
6188 rtc::ScopedFakeClock clock;
6189 clock.AdvanceTime(webrtc::TimeDelta::Seconds(1));
6190
6191 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
6192 P2PTransportChannel ch("test channel", 1, &pa, &field_trials);
6193 PrepareChannel(&ch);
6194 ch.SetIceConfig(ch.config());
6195 ch.MaybeStartGathering();
6196
6197 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
6198 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
6199 ASSERT_TRUE(conn1 != nullptr);
6200 EXPECT_EQ(nullptr, ch.selected_connection());
6201 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
6202 // It shall not be selected until 100ms has passed....but only wait ~50 now.
6203 SIMULATED_WAIT(conn1 == ch.selected_connection(), 50 - kMargin, clock);
6204 // Now receiving ping and new timeout should kick in.
6205 conn1->ReceivedPing("id1"); //
6206 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
6207 }
6208
6209 class P2PTransportChannelIceControllerTest : public TestWithParam<std::string> {
6210 };
6211
6212 INSTANTIATE_TEST_SUITE_P(Legacy,
6213 P2PTransportChannelIceControllerTest,
6214 Values(""));
6215 INSTANTIATE_TEST_SUITE_P(Active,
6216 P2PTransportChannelIceControllerTest,
6217 Values("WebRTC-UseActiveIceController/Enabled/"));
6218
TEST_P(P2PTransportChannelIceControllerTest,InjectIceController)6219 TEST_P(P2PTransportChannelIceControllerTest, InjectIceController) {
6220 std::unique_ptr<rtc::SocketServer> socket_server =
6221 rtc::CreateDefaultSocketServer();
6222 rtc::AutoSocketServerThread main_thread(socket_server.get());
6223 rtc::BasicPacketSocketFactory packet_socket_factory(socket_server.get());
6224 MockIceControllerFactory factory;
6225 FakePortAllocator pa(rtc::Thread::Current(), &packet_socket_factory);
6226 webrtc::test::ScopedKeyValueConfig field_trials(GetParam());
6227 EXPECT_CALL(factory, RecordIceControllerCreated()).Times(1);
6228 webrtc::IceTransportInit init;
6229 init.set_port_allocator(&pa);
6230 init.set_ice_controller_factory(&factory);
6231 init.set_field_trials(&field_trials);
6232 auto dummy =
6233 P2PTransportChannel::Create("transport_name",
6234 /* component= */ 77, std::move(init));
6235 }
6236
TEST(P2PTransportChannel,InjectActiveIceController)6237 TEST(P2PTransportChannel, InjectActiveIceController) {
6238 std::unique_ptr<rtc::SocketServer> socket_server =
6239 rtc::CreateDefaultSocketServer();
6240 rtc::AutoSocketServerThread main_thread(socket_server.get());
6241 rtc::BasicPacketSocketFactory packet_socket_factory(socket_server.get());
6242 MockActiveIceControllerFactory factory;
6243 FakePortAllocator pa(rtc::Thread::Current(), &packet_socket_factory);
6244 webrtc::test::ScopedKeyValueConfig field_trials(
6245 "WebRTC-UseActiveIceController/Enabled/");
6246 EXPECT_CALL(factory, RecordActiveIceControllerCreated()).Times(1);
6247 webrtc::IceTransportInit init;
6248 init.set_port_allocator(&pa);
6249 init.set_active_ice_controller_factory(&factory);
6250 init.set_field_trials(&field_trials);
6251 auto dummy =
6252 P2PTransportChannel::Create("transport_name",
6253 /* component= */ 77, std::move(init));
6254 }
6255
6256 class ForgetLearnedStateController : public cricket::BasicIceController {
6257 public:
ForgetLearnedStateController(const cricket::IceControllerFactoryArgs & args)6258 explicit ForgetLearnedStateController(
6259 const cricket::IceControllerFactoryArgs& args)
6260 : cricket::BasicIceController(args) {}
6261
SortAndSwitchConnection(IceSwitchReason reason)6262 SwitchResult SortAndSwitchConnection(IceSwitchReason reason) override {
6263 auto result = cricket::BasicIceController::SortAndSwitchConnection(reason);
6264 if (forget_connnection_) {
6265 result.connections_to_forget_state_on.push_back(forget_connnection_);
6266 forget_connnection_ = nullptr;
6267 }
6268 result.recheck_event.emplace(IceSwitchReason::ICE_CONTROLLER_RECHECK, 100);
6269 return result;
6270 }
6271
ForgetThisConnectionNextTimeSortAndSwitchConnectionIsCalled(Connection * con)6272 void ForgetThisConnectionNextTimeSortAndSwitchConnectionIsCalled(
6273 Connection* con) {
6274 forget_connnection_ = con;
6275 }
6276
6277 private:
6278 Connection* forget_connnection_ = nullptr;
6279 };
6280
6281 class ForgetLearnedStateControllerFactory
6282 : public cricket::IceControllerFactoryInterface {
6283 public:
Create(const cricket::IceControllerFactoryArgs & args)6284 std::unique_ptr<cricket::IceControllerInterface> Create(
6285 const cricket::IceControllerFactoryArgs& args) override {
6286 auto controller = std::make_unique<ForgetLearnedStateController>(args);
6287 // Keep a pointer to allow modifying calls.
6288 // Must not be used after the p2ptransportchannel has been destructed.
6289 controller_ = controller.get();
6290 return controller;
6291 }
6292 virtual ~ForgetLearnedStateControllerFactory() = default;
6293
6294 ForgetLearnedStateController* controller_;
6295 };
6296
TEST_P(P2PTransportChannelPingTest,TestForgetLearnedState)6297 TEST_P(P2PTransportChannelPingTest, TestForgetLearnedState) {
6298 ForgetLearnedStateControllerFactory factory;
6299 FakePortAllocator pa(rtc::Thread::Current(), packet_socket_factory());
6300 webrtc::IceTransportInit init;
6301 init.set_port_allocator(&pa);
6302 init.set_ice_controller_factory(&factory);
6303 init.set_field_trials(&field_trials_);
6304 auto ch =
6305 P2PTransportChannel::Create("ping sufficiently", 1, std::move(init));
6306
6307 PrepareChannel(ch.get());
6308 ch->MaybeStartGathering();
6309 ch->AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
6310 ch->AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
6311
6312 Connection* conn1 = WaitForConnectionTo(ch.get(), "1.1.1.1", 1);
6313 Connection* conn2 = WaitForConnectionTo(ch.get(), "2.2.2.2", 2);
6314 ASSERT_TRUE(conn1 != nullptr);
6315 ASSERT_TRUE(conn2 != nullptr);
6316
6317 // Wait for conn1 to be selected.
6318 conn1->ReceivedPingResponse(LOW_RTT, "id");
6319 EXPECT_EQ_WAIT(conn1, ch->selected_connection(), kMediumTimeout);
6320
6321 conn2->ReceivedPingResponse(LOW_RTT, "id");
6322 EXPECT_TRUE(conn2->writable());
6323
6324 // Now let the ice controller signal to P2PTransportChannel that it
6325 // should Forget conn2.
6326 factory.controller_
6327 ->ForgetThisConnectionNextTimeSortAndSwitchConnectionIsCalled(conn2);
6328
6329 // We don't have a mock Connection, so verify this by checking that it
6330 // is no longer writable.
6331 EXPECT_EQ_WAIT(false, conn2->writable(), kMediumTimeout);
6332 }
6333
TEST_P(P2PTransportChannelTestWithFieldTrials,DisableDnsLookupsWithTransportPolicyRelay)6334 TEST_P(P2PTransportChannelTestWithFieldTrials,
6335 DisableDnsLookupsWithTransportPolicyRelay) {
6336 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
6337 kDefaultPortAllocatorFlags);
6338 auto* ep1 = GetEndpoint(0);
6339 ep1->allocator_->SetCandidateFilter(CF_RELAY);
6340
6341 std::unique_ptr<webrtc::MockAsyncDnsResolver> mock_async_resolver =
6342 std::make_unique<webrtc::MockAsyncDnsResolver>();
6343 // This test expects resolution to not be started.
6344 EXPECT_CALL(*mock_async_resolver, Start(_, _)).Times(0);
6345
6346 webrtc::MockAsyncDnsResolverFactory mock_async_resolver_factory;
6347 ON_CALL(mock_async_resolver_factory, Create())
6348 .WillByDefault(
6349 [&mock_async_resolver]() { return std::move(mock_async_resolver); });
6350
6351 ep1->async_dns_resolver_factory_ = &mock_async_resolver_factory;
6352
6353 CreateChannels();
6354
6355 ep1_ch1()->AddRemoteCandidate(
6356 CreateUdpCandidate(LOCAL_PORT_TYPE, "hostname.test", 1, 100));
6357
6358 DestroyChannels();
6359 }
6360
TEST_P(P2PTransportChannelTestWithFieldTrials,DisableDnsLookupsWithTransportPolicyNone)6361 TEST_P(P2PTransportChannelTestWithFieldTrials,
6362 DisableDnsLookupsWithTransportPolicyNone) {
6363 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
6364 kDefaultPortAllocatorFlags);
6365 auto* ep1 = GetEndpoint(0);
6366 ep1->allocator_->SetCandidateFilter(CF_NONE);
6367
6368 std::unique_ptr<webrtc::MockAsyncDnsResolver> mock_async_resolver =
6369 std::make_unique<webrtc::MockAsyncDnsResolver>();
6370 // This test expects resolution to not be started.
6371 EXPECT_CALL(*mock_async_resolver, Start(_, _)).Times(0);
6372
6373 webrtc::MockAsyncDnsResolverFactory mock_async_resolver_factory;
6374 ON_CALL(mock_async_resolver_factory, Create())
6375 .WillByDefault(
6376 [&mock_async_resolver]() { return std::move(mock_async_resolver); });
6377
6378 ep1->async_dns_resolver_factory_ = &mock_async_resolver_factory;
6379
6380 CreateChannels();
6381
6382 ep1_ch1()->AddRemoteCandidate(
6383 CreateUdpCandidate(LOCAL_PORT_TYPE, "hostname.test", 1, 100));
6384
6385 DestroyChannels();
6386 }
6387
TEST_P(P2PTransportChannelTestWithFieldTrials,EnableDnsLookupsWithTransportPolicyNoHost)6388 TEST_P(P2PTransportChannelTestWithFieldTrials,
6389 EnableDnsLookupsWithTransportPolicyNoHost) {
6390 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
6391 kDefaultPortAllocatorFlags);
6392 auto* ep1 = GetEndpoint(0);
6393 ep1->allocator_->SetCandidateFilter(CF_ALL & ~CF_HOST);
6394
6395 std::unique_ptr<webrtc::MockAsyncDnsResolver> mock_async_resolver =
6396 std::make_unique<webrtc::MockAsyncDnsResolver>();
6397 bool lookup_started = false;
6398 EXPECT_CALL(*mock_async_resolver, Start(_, _))
6399 .WillOnce(Assign(&lookup_started, true));
6400
6401 webrtc::MockAsyncDnsResolverFactory mock_async_resolver_factory;
6402 EXPECT_CALL(mock_async_resolver_factory, Create())
6403 .WillOnce(
6404 [&mock_async_resolver]() { return std::move(mock_async_resolver); });
6405
6406 ep1->async_dns_resolver_factory_ = &mock_async_resolver_factory;
6407
6408 CreateChannels();
6409
6410 ep1_ch1()->AddRemoteCandidate(
6411 CreateUdpCandidate(LOCAL_PORT_TYPE, "hostname.test", 1, 100));
6412
6413 EXPECT_TRUE(lookup_started);
6414
6415 DestroyChannels();
6416 }
6417
6418 class GatherAfterConnectedTest
6419 : public P2PTransportChannelTest,
6420 public WithParamInterface<std::tuple<bool, std::string>> {
6421 public:
GatherAfterConnectedTest()6422 GatherAfterConnectedTest()
6423 : P2PTransportChannelTest(std::get<1>(GetParam())) {}
6424 };
6425
TEST_P(GatherAfterConnectedTest,GatherAfterConnected)6426 TEST_P(GatherAfterConnectedTest, GatherAfterConnected) {
6427 const bool stop_gather_on_strongly_connected = std::get<0>(GetParam());
6428 const std::string field_trial =
6429 std::string("WebRTC-IceFieldTrials/stop_gather_on_strongly_connected:") +
6430 (stop_gather_on_strongly_connected ? "true/" : "false/");
6431 webrtc::test::ScopedKeyValueConfig field_trials(field_trials_, field_trial);
6432
6433 rtc::ScopedFakeClock clock;
6434 // Use local + relay
6435 constexpr uint32_t flags =
6436 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET |
6437 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP;
6438 ConfigureEndpoints(OPEN, OPEN, flags, flags);
6439 auto* ep1 = GetEndpoint(0);
6440 auto* ep2 = GetEndpoint(1);
6441 ep1->allocator_->SetCandidateFilter(CF_ALL);
6442 ep2->allocator_->SetCandidateFilter(CF_ALL);
6443
6444 // Use step delay 3s which is long enough for
6445 // connection to be established before managing to gather relay candidates.
6446 int delay = 3000;
6447 SetAllocationStepDelay(0, delay);
6448 SetAllocationStepDelay(1, delay);
6449 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
6450 CreateChannels(ice_config, ice_config);
6451
6452 PauseCandidates(0);
6453 PauseCandidates(1);
6454
6455 // We have gathered host candidates but not relay.
6456 ASSERT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 1u &&
6457 ep2->saved_candidates_.size() == 1u,
6458 kDefaultTimeout, clock);
6459
6460 ResumeCandidates(0);
6461 ResumeCandidates(1);
6462
6463 PauseCandidates(0);
6464 PauseCandidates(1);
6465
6466 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->remote_candidates().size() == 1 &&
6467 ep2_ch1()->remote_candidates().size() == 1,
6468 kDefaultTimeout, clock);
6469
6470 ASSERT_TRUE_SIMULATED_WAIT(
6471 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection(),
6472 kDefaultTimeout, clock);
6473
6474 clock.AdvanceTime(webrtc::TimeDelta::Millis(10 * delay));
6475
6476 if (stop_gather_on_strongly_connected) {
6477 // The relay candidates gathered has not been propagated to channel.
6478 EXPECT_EQ(ep1->saved_candidates_.size(), 0u);
6479 EXPECT_EQ(ep2->saved_candidates_.size(), 0u);
6480 } else {
6481 // The relay candidates gathered has been propagated to channel.
6482 EXPECT_EQ(ep1->saved_candidates_.size(), 1u);
6483 EXPECT_EQ(ep2->saved_candidates_.size(), 1u);
6484 }
6485 }
6486
TEST_P(GatherAfterConnectedTest,GatherAfterConnectedMultiHomed)6487 TEST_P(GatherAfterConnectedTest, GatherAfterConnectedMultiHomed) {
6488 const bool stop_gather_on_strongly_connected = std::get<0>(GetParam());
6489 const std::string field_trial =
6490 std::string("WebRTC-IceFieldTrials/stop_gather_on_strongly_connected:") +
6491 (stop_gather_on_strongly_connected ? "true/" : "false/");
6492 webrtc::test::ScopedKeyValueConfig field_trials(field_trials_, field_trial);
6493
6494 rtc::ScopedFakeClock clock;
6495 // Use local + relay
6496 constexpr uint32_t flags =
6497 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET |
6498 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP;
6499 AddAddress(0, kAlternateAddrs[0]);
6500 ConfigureEndpoints(OPEN, OPEN, flags, flags);
6501 auto* ep1 = GetEndpoint(0);
6502 auto* ep2 = GetEndpoint(1);
6503 ep1->allocator_->SetCandidateFilter(CF_ALL);
6504 ep2->allocator_->SetCandidateFilter(CF_ALL);
6505
6506 // Use step delay 3s which is long enough for
6507 // connection to be established before managing to gather relay candidates.
6508 int delay = 3000;
6509 SetAllocationStepDelay(0, delay);
6510 SetAllocationStepDelay(1, delay);
6511 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
6512 CreateChannels(ice_config, ice_config);
6513
6514 PauseCandidates(0);
6515 PauseCandidates(1);
6516
6517 // We have gathered host candidates but not relay.
6518 ASSERT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 2u &&
6519 ep2->saved_candidates_.size() == 1u,
6520 kDefaultTimeout, clock);
6521
6522 ResumeCandidates(0);
6523 ResumeCandidates(1);
6524
6525 PauseCandidates(0);
6526 PauseCandidates(1);
6527
6528 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->remote_candidates().size() == 1 &&
6529 ep2_ch1()->remote_candidates().size() == 2,
6530 kDefaultTimeout, clock);
6531
6532 ASSERT_TRUE_SIMULATED_WAIT(
6533 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection(),
6534 kDefaultTimeout, clock);
6535
6536 clock.AdvanceTime(webrtc::TimeDelta::Millis(10 * delay));
6537
6538 if (stop_gather_on_strongly_connected) {
6539 // The relay candidates gathered has not been propagated to channel.
6540 EXPECT_EQ(ep1->saved_candidates_.size(), 0u);
6541 EXPECT_EQ(ep2->saved_candidates_.size(), 0u);
6542 } else {
6543 // The relay candidates gathered has been propagated.
6544 EXPECT_EQ(ep1->saved_candidates_.size(), 2u);
6545 EXPECT_EQ(ep2->saved_candidates_.size(), 1u);
6546 }
6547 }
6548
6549 INSTANTIATE_TEST_SUITE_P(Legacy,
6550 GatherAfterConnectedTest,
6551 Combine(Values(true, false), Values("")));
6552 INSTANTIATE_TEST_SUITE_P(
6553 Active,
6554 GatherAfterConnectedTest,
6555 Combine(Values(true, false),
6556 Values("WebRTC-UseActiveIceController/Enabled/")));
6557
6558 // Tests no candidates are generated with old ice ufrag/passwd after an ice
6559 // restart even if continual gathering is enabled.
TEST_P(P2PTransportChannelTestWithFieldTrials,TestIceNoOldCandidatesAfterIceRestart)6560 TEST_P(P2PTransportChannelTestWithFieldTrials,
6561 TestIceNoOldCandidatesAfterIceRestart) {
6562 rtc::ScopedFakeClock clock;
6563 AddAddress(0, kAlternateAddrs[0]);
6564 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
6565 kDefaultPortAllocatorFlags);
6566
6567 // gathers continually.
6568 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
6569 CreateChannels(config, config);
6570
6571 EXPECT_TRUE_SIMULATED_WAIT(CheckConnected(ep1_ch1(), ep2_ch1()),
6572 kDefaultTimeout, clock);
6573
6574 PauseCandidates(0);
6575
6576 ep1_ch1()->SetIceParameters(kIceParams[3]);
6577 ep1_ch1()->MaybeStartGathering();
6578
6579 EXPECT_TRUE_SIMULATED_WAIT(GetEndpoint(0)->saved_candidates_.size() > 0,
6580 kDefaultTimeout, clock);
6581
6582 for (const auto& cd : GetEndpoint(0)->saved_candidates_) {
6583 EXPECT_EQ(cd.candidate.username(), kIceUfrag[3]);
6584 }
6585
6586 DestroyChannels();
6587 }
6588
6589 } // namespace cricket
6590