blob: 39dfaa350744bfb992280fd5ecb8292513bdd0f9 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
Taylor Brandstettera1c30352016-05-13 08:15:11 -070011#include <algorithm>
Steve Antone9324572017-11-29 10:18:21 -080012#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070013#include <memory>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/fakemetricsobserver.h"
16#include "p2p/base/fakeportallocator.h"
17#include "p2p/base/icetransportinternal.h"
18#include "p2p/base/p2ptransportchannel.h"
19#include "p2p/base/packettransportinternal.h"
20#include "p2p/base/testrelayserver.h"
21#include "p2p/base/teststunserver.h"
22#include "p2p/base/testturnserver.h"
23#include "p2p/client/basicportallocator.h"
24#include "rtc_base/checks.h"
25#include "rtc_base/dscp.h"
26#include "rtc_base/fakeclock.h"
27#include "rtc_base/fakenetwork.h"
28#include "rtc_base/firewallsocketserver.h"
29#include "rtc_base/gunit.h"
30#include "rtc_base/helpers.h"
31#include "rtc_base/logging.h"
32#include "rtc_base/natserver.h"
33#include "rtc_base/natsocketfactory.h"
34#include "rtc_base/proxyserver.h"
35#include "rtc_base/ptr_util.h"
36#include "rtc_base/socketaddress.h"
37#include "rtc_base/ssladapter.h"
38#include "rtc_base/thread.h"
39#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000040
deadbeef14f97f52016-06-22 17:14:15 -070041namespace {
42
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000043using rtc::SocketAddress;
44
deadbeef14f97f52016-06-22 17:14:15 -070045// Default timeout for tests in this file.
46// Should be large enough for slow buildbots to run the tests reliably.
47static const int kDefaultTimeout = 10000;
Honghai Zhang161a5862016-10-20 11:47:02 -070048static const int kMediumTimeout = 3000;
49static const int kShortTimeout = 1000;
deadbeef14f97f52016-06-22 17:14:15 -070050
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
52 cricket::PORTALLOCATOR_DISABLE_RELAY |
53 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070054static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000055// Addresses on the public internet.
56static const SocketAddress kPublicAddrs[2] =
57 { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
58// IPv6 Addresses on the public internet.
59static const SocketAddress kIPv6PublicAddrs[2] = {
60 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
honghaiz7252a002016-11-08 20:04:09 -080061 SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000062// For configuring multihomed clients.
Honghai Zhangfd16da22016-08-17 16:12:46 -070063static const SocketAddress kAlternateAddrs[2] = {
64 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
honghaiz7252a002016-11-08 20:04:09 -080065static const SocketAddress kIPv6AlternateAddrs[2] = {
66 SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
67 SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
deadbeeff137e972017-03-23 15:45:49 -070068// Addresses for HTTP proxy servers.
69static const SocketAddress kHttpsProxyAddrs[2] =
70 { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
71// Addresses for SOCKS proxy servers.
72static const SocketAddress kSocksProxyAddrs[2] =
73 { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000074// Internal addresses for NAT boxes.
75static const SocketAddress kNatAddrs[2] =
76 { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
77// Private addresses inside the NAT private networks.
78static const SocketAddress kPrivateAddrs[2] =
79 { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
80// For cascaded NATs, the internal addresses of the inner NAT boxes.
81static const SocketAddress kCascadedNatAddrs[2] =
82 { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
83// For cascaded NATs, private addresses inside the inner private networks.
84static const SocketAddress kCascadedPrivateAddrs[2] =
85 { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
86// The address of the public STUN server.
87static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000088// The addresses for the public turn server.
Honghai Zhangb73d2692016-09-29 22:46:09 -070089static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -080091static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
92 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000093static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
94static const cricket::RelayCredentials kRelayCredentials("test", "test");
95
96// Based on ICE_UFRAG_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070097const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098// Based on ICE_PWD_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070099const char* kIcePwd[4] = {
100 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
101 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
102const cricket::IceParameters kIceParams[4] = {
103 {kIceUfrag[0], kIcePwd[0], false},
104 {kIceUfrag[1], kIcePwd[1], false},
105 {kIceUfrag[2], kIcePwd[2], false},
106 {kIceUfrag[3], kIcePwd[3], false}};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000107
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700108const uint64_t kLowTiebreaker = 11111;
109const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000110
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700111enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000112
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700113cricket::IceConfig CreateIceConfig(
114 int receiving_timeout,
115 cricket::ContinualGatheringPolicy continual_gathering_policy,
Danil Chapovalov00c71832018-06-15 15:58:38 +0200116 absl::optional<int> backup_ping_interval = absl::nullopt) {
honghaiz1f429e32015-09-28 07:57:34 -0700117 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800118 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700119 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800120 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700121 return config;
122}
123
deadbeef14f97f52016-06-22 17:14:15 -0700124cricket::Candidate CreateUdpCandidate(const std::string& type,
125 const std::string& ip,
126 int port,
127 int priority,
128 const std::string& ufrag = "") {
129 cricket::Candidate c;
130 c.set_address(rtc::SocketAddress(ip, port));
131 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
132 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
133 c.set_priority(priority);
134 c.set_username(ufrag);
135 c.set_type(type);
136 return c;
137}
138
Honghai Zhangb73d2692016-09-29 22:46:09 -0700139cricket::BasicPortAllocator* CreateBasicPortAllocator(
140 rtc::NetworkManager* network_manager,
141 const cricket::ServerAddresses& stun_servers,
142 const rtc::SocketAddress& turn_server_udp,
143 const rtc::SocketAddress& turn_server_tcp) {
144 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
145 turn_server.credentials = kRelayCredentials;
146 if (!turn_server_udp.IsNil()) {
147 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800148 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700149 }
150 if (!turn_server_tcp.IsNil()) {
151 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800152 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700153 }
154 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
155
156 cricket::BasicPortAllocator* allocator =
157 new cricket::BasicPortAllocator(network_manager);
Qingsi Wanga2d60672018-04-11 16:57:45 -0700158 allocator->Initialize();
Honghai Zhangb73d2692016-09-29 22:46:09 -0700159 allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
160 return allocator;
161}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700162} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700163
164namespace cricket {
165
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166// This test simulates 2 P2P endpoints that want to establish connectivity
167// with each other over various network topologies and conditions, which can be
168// specified in each individial test.
169// A virtual network (via VirtualSocketServer) along with virtual firewalls and
170// NATs (via Firewall/NATSocketServer) are used to simulate the various network
171// conditions. We can configure the IP addresses of the endpoints,
172// block various types of connectivity, or add arbitrary levels of NAT.
173// We also run a STUN server and a relay server on the virtual network to allow
174// our typical P2P mechanisms to do their thing.
175// For each case, we expect the P2P stack to eventually settle on a specific
176// form of connectivity to the other side. The test checks that the P2P
177// negotiation successfully establishes connectivity within a certain time,
178// and that the result is what we expect.
179// Note that this class is a base class for use by other tests, who will provide
180// specialized test behavior.
181class P2PTransportChannelTestBase : public testing::Test,
182 public rtc::MessageHandler,
183 public sigslot::has_slots<> {
184 public:
185 P2PTransportChannelTestBase()
deadbeef98e186c2017-05-16 18:00:06 -0700186 : vss_(new rtc::VirtualSocketServer()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187 nss_(new rtc::NATSocketServer(vss_.get())),
188 ss_(new rtc::FirewallSocketServer(nss_.get())),
nisse7eaa4ea2017-05-08 05:25:41 -0700189 main_(ss_.get()),
190 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
191 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeeff137e972017-03-23 15:45:49 -0700192 socks_server1_(ss_.get(),
193 kSocksProxyAddrs[0],
194 ss_.get(),
195 kSocksProxyAddrs[0]),
196 socks_server2_(ss_.get(),
197 kSocksProxyAddrs[1],
198 ss_.get(),
199 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000200 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700201 ep1_.role_ = ICEROLE_CONTROLLING;
202 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000203
204 ServerAddresses stun_servers;
205 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700206 ep1_.allocator_.reset(
207 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
208 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700209 ep1_.metrics_observer_ =
210 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
211 ep1_.allocator_->SetMetricsObserver(ep1_.metrics_observer_);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700212 ep2_.allocator_.reset(
213 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
214 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700215 ep2_.metrics_observer_ =
216 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
217 ep2_.allocator_->SetMetricsObserver(ep2_.metrics_observer_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000218 }
219
220 protected:
221 enum Config {
222 OPEN, // Open to the Internet
223 NAT_FULL_CONE, // NAT, no filtering
224 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
225 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
226 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
227 NAT_DOUBLE_CONE, // Double NAT, both cone
228 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
229 BLOCK_UDP, // Firewall, UDP in/out blocked
230 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
deadbeeff137e972017-03-23 15:45:49 -0700231 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
232 PROXY_HTTPS, // All traffic through HTTPS proxy
233 PROXY_SOCKS, // All traffic through SOCKS proxy
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000234 NUM_CONFIGS
235 };
236
237 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700238 Result(const std::string& controlling_type,
239 const std::string& controlling_protocol,
240 const std::string& controlled_type,
241 const std::string& controlled_protocol,
242 int wait)
243 : controlling_type(controlling_type),
244 controlling_protocol(controlling_protocol),
245 controlled_type(controlled_type),
246 controlled_protocol(controlled_protocol),
247 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700248
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700249 // The expected candidate type and protocol of the controlling ICE agent.
250 std::string controlling_type;
251 std::string controlling_protocol;
252 // The expected candidate type and protocol of the controlled ICE agent.
253 std::string controlled_type;
254 std::string controlled_protocol;
255 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000256 int connect_wait;
257 };
258
259 struct ChannelData {
260 bool CheckData(const char* data, int len) {
261 bool ret = false;
262 if (!ch_packets_.empty()) {
263 std::string packet = ch_packets_.front();
264 ret = (packet == std::string(data, len));
265 ch_packets_.pop_front();
266 }
267 return ret;
268 }
269
Steve Antone9324572017-11-29 10:18:21 -0800270 std::string name_; // TODO(?) - Currently not used.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000271 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700272 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273 };
274
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700275 struct CandidatesData : public rtc::MessageData {
zhihuangd06adf62017-01-12 15:58:31 -0800276 CandidatesData(IceTransportInternal* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700277 : channel(ch), candidates(1, c) {}
zhihuangd06adf62017-01-12 15:58:31 -0800278 CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700279 : channel(ch), candidates(cc) {}
zhihuangd06adf62017-01-12 15:58:31 -0800280 IceTransportInternal* channel;
deadbeef14f97f52016-06-22 17:14:15 -0700281 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000282 };
283
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000284 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000285 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700286 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000287 tiebreaker_(0),
288 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700289 save_candidates_(false) {}
deadbeef5bd5ca32017-02-10 11:31:50 -0800290 bool HasTransport(const rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700291 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000292 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800293 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700294 if (!HasTransport(transport))
295 return NULL;
296 if (cd1_.ch_.get() == transport)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000297 return &cd1_;
298 else
299 return &cd2_;
300 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301
deadbeef14f97f52016-06-22 17:14:15 -0700302 void SetIceRole(IceRole role) { role_ = role; }
303 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200304 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
305 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000306 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
307 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200308 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000309 allocator_->set_step_delay(delay);
310 }
311 void SetAllowTcpListen(bool allow_tcp_listen) {
312 allocator_->set_allow_tcp_listen(allow_tcp_listen);
313 }
314
315 rtc::FakeNetworkManager network_manager_;
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700316 // |metrics_observer_| should outlive |allocator_| as the former may be
317 // used by the latter.
318 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer_;
deadbeef14f97f52016-06-22 17:14:15 -0700319 std::unique_ptr<BasicPortAllocator> allocator_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000320 ChannelData cd1_;
321 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700322 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200323 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000324 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000325 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700326 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700327 bool ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000328 };
329
deadbeef5bd5ca32017-02-10 11:31:50 -0800330 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700331 if (ep1_.HasTransport(transport))
332 return ep1_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000333 else
johand89ab142016-10-25 10:50:32 -0700334 return ep2_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000335 }
336
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700337 IceParameters IceParamsWithRenomination(const IceParameters& ice,
338 bool renomination) {
339 IceParameters new_ice = ice;
340 new_ice.renomination = renomination;
341 return new_ice;
342 }
343
johan02bd5122016-09-20 00:23:27 -0700344 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700345 const IceConfig& ep2_config,
346 bool renomination = false) {
347 IceParameters ice_ep1_cd1_ch =
348 IceParamsWithRenomination(kIceParams[0], renomination);
349 IceParameters ice_ep2_cd1_ch =
350 IceParamsWithRenomination(kIceParams[1], renomination);
351 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
352 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
353 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
354 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700355 ep1_.cd1_.ch_->SetMetricsObserver(ep1_.metrics_observer_);
356 ep2_.cd1_.ch_->SetMetricsObserver(ep2_.metrics_observer_);
deadbeefb60a8192016-08-24 15:15:00 -0700357 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
358 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700359 ep1_.cd1_.ch_->MaybeStartGathering();
360 ep2_.cd1_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000361 }
deadbeefb60a8192016-08-24 15:15:00 -0700362
johan02bd5122016-09-20 00:23:27 -0700363 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700364 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700365 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700366 }
367
deadbeef14f97f52016-06-22 17:14:15 -0700368 P2PTransportChannel* CreateChannel(int endpoint,
369 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700370 const IceParameters& local_ice,
371 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700372 P2PTransportChannel* channel = new P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800373 "test content name", component, GetAllocator(endpoint));
deadbeef14f97f52016-06-22 17:14:15 -0700374 channel->SignalReadyToSend.connect(
375 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700376 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700377 this, &P2PTransportChannelTestBase::OnCandidateGathered);
378 channel->SignalCandidatesRemoved.connect(
379 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000380 channel->SignalReadPacket.connect(
381 this, &P2PTransportChannelTestBase::OnReadPacket);
382 channel->SignalRoleConflict.connect(
383 this, &P2PTransportChannelTestBase::OnRoleConflict);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800384 channel->SignalNetworkRouteChanged.connect(
385 this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
Qingsi Wang6e641e62018-04-11 20:14:17 -0700386 channel->SignalSentPacket.connect(
387 this, &P2PTransportChannelTestBase::OnSentPacket);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700388 channel->SetIceParameters(local_ice);
389 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
390 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000391 }
392 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
393 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000394 return channel;
395 }
396 void DestroyChannels() {
397 ep1_.cd1_.ch_.reset();
398 ep2_.cd1_.ch_.reset();
399 ep1_.cd2_.ch_.reset();
400 ep2_.cd2_.ch_.reset();
401 }
deadbeef14f97f52016-06-22 17:14:15 -0700402 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
403 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
404 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
405 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000406
Taylor Brandstetteref184702016-06-23 17:35:47 -0700407 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700408 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700409
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000410 // Common results.
411 static const Result kLocalUdpToLocalUdp;
412 static const Result kLocalUdpToStunUdp;
413 static const Result kLocalUdpToPrflxUdp;
414 static const Result kPrflxUdpToLocalUdp;
415 static const Result kStunUdpToLocalUdp;
416 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700417 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000418 static const Result kPrflxUdpToStunUdp;
419 static const Result kLocalUdpToRelayUdp;
420 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700421 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000422 static const Result kLocalTcpToLocalTcp;
423 static const Result kLocalTcpToPrflxTcp;
424 static const Result kPrflxTcpToLocalTcp;
425
426 rtc::NATSocketServer* nat() { return nss_.get(); }
427 rtc::FirewallSocketServer* fw() { return ss_.get(); }
428
429 Endpoint* GetEndpoint(int endpoint) {
430 if (endpoint == 0) {
431 return &ep1_;
432 } else if (endpoint == 1) {
433 return &ep2_;
434 } else {
435 return NULL;
436 }
437 }
honghaiz7252a002016-11-08 20:04:09 -0800438 BasicPortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000439 return GetEndpoint(endpoint)->allocator_.get();
440 }
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700441 webrtc::FakeMetricsObserver* GetMetricsObserver(int endpoint) {
442 return GetEndpoint(endpoint)->metrics_observer_;
443 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000444 void AddAddress(int endpoint, const SocketAddress& addr) {
445 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
446 }
honghaize1a0c942016-02-16 14:54:56 -0800447 void AddAddress(int endpoint,
448 const SocketAddress& addr,
449 const std::string& ifname,
450 rtc::AdapterType adapter_type) {
451 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
452 adapter_type);
453 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000454 void RemoveAddress(int endpoint, const SocketAddress& addr) {
455 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700456 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000457 }
deadbeeff137e972017-03-23 15:45:49 -0700458 void SetProxy(int endpoint, rtc::ProxyType type) {
459 rtc::ProxyInfo info;
460 info.type = type;
461 info.address = (type == rtc::PROXY_HTTPS) ?
462 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
463 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
464 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000465 void SetAllocatorFlags(int endpoint, int flags) {
466 GetAllocator(endpoint)->set_flags(flags);
467 }
deadbeef14f97f52016-06-22 17:14:15 -0700468 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000469 GetEndpoint(endpoint)->SetIceRole(role);
470 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200471 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000472 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
473 }
474 bool GetRoleConflict(int endpoint) {
475 return GetEndpoint(endpoint)->role_conflict();
476 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200477 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000478 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
479 }
480 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
481 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
482 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700483
484 // Return true if the approprite parts of the expected Result, based
485 // on the local and remote candidate of ep1_ch1, match. This can be
486 // used in an EXPECT_TRUE_WAIT.
487 bool CheckCandidate1(const Result& expected) {
488 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700489 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700490 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700491 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
492 return (local_protocol == expected.controlling_protocol &&
493 remote_protocol == expected.controlled_protocol &&
494 local_type == expected.controlling_type &&
495 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700496 }
497
498 // EXPECT_EQ on the approprite parts of the expected Result, based
499 // on the local and remote candidate of ep1_ch1. This is like
500 // CheckCandidate1, except that it will provide more detail about
501 // what didn't match.
502 void ExpectCandidate1(const Result& expected) {
503 if (CheckCandidate1(expected)) {
504 return;
505 }
506
507 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700508 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700509 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700510 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
511 EXPECT_EQ(expected.controlling_type, local_type);
512 EXPECT_EQ(expected.controlled_type, remote_type);
513 EXPECT_EQ(expected.controlling_protocol, local_protocol);
514 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700515 }
516
517 // Return true if the approprite parts of the expected Result, based
518 // on the local and remote candidate of ep2_ch1, match. This can be
519 // used in an EXPECT_TRUE_WAIT.
520 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700521 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
522 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
523 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
524 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
525 return (local_protocol == expected.controlled_protocol &&
526 remote_protocol == expected.controlling_protocol &&
527 local_type == expected.controlled_type &&
528 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700529 }
530
531 // EXPECT_EQ on the approprite parts of the expected Result, based
532 // on the local and remote candidate of ep2_ch1. This is like
533 // CheckCandidate2, except that it will provide more detail about
534 // what didn't match.
535 void ExpectCandidate2(const Result& expected) {
536 if (CheckCandidate2(expected)) {
537 return;
538 }
539
540 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700541 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700542 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700543 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
544 EXPECT_EQ(expected.controlled_type, local_type);
545 EXPECT_EQ(expected.controlling_type, remote_type);
546 EXPECT_EQ(expected.controlled_protocol, local_protocol);
547 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700548 }
549
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000550 void Test(const Result& expected) {
honghaize58d73d2016-10-24 16:38:26 -0700551 rtc::ScopedFakeClock clock;
nisse1bffc1d2016-05-02 08:18:55 -0700552 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700553 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000554
555 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700556 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -0700557 EXPECT_TRUE_SIMULATED_WAIT(
558 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
559 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
560 ep2_ch1()->writable(),
561 expected.connect_wait + kShortTimeout, clock);
nisse1bffc1d2016-05-02 08:18:55 -0700562 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000563 if (connect_time < expected.connect_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100564 RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000565 } else {
Jonas Olssond7d762d2018-03-28 09:47:51 +0200566 RTC_LOG(LS_INFO) << "Connect time: TIMEOUT ("
567 << expected.connect_wait << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000568 }
569
Honghai Zhang572b0942016-06-23 12:26:57 -0700570 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000571 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700572 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700573 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700574 int64_t converge_time;
Honghai Zhang572b0942016-06-23 12:26:57 -0700575 // Verifying local and remote channel selected connection information.
576 // This is done only for the RFC 5245 as controlled agent will use
577 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
578 // EP1 result matrix.
honghaize58d73d2016-10-24 16:38:26 -0700579 EXPECT_TRUE_SIMULATED_WAIT(
580 CheckCandidate1(expected) && CheckCandidate2(expected),
581 kMediumTimeout, clock);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700582 // Also do EXPECT_EQ on each part so that failures are more verbose.
583 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700584 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000585
nisse1bffc1d2016-05-02 08:18:55 -0700586 converge_time = rtc::TimeMillis() - converge_start;
honghaize58d73d2016-10-24 16:38:26 -0700587 int64_t converge_wait = 2000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000588 if (converge_time < converge_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100589 RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000590 } else {
Jonas Olssond7d762d2018-03-28 09:47:51 +0200591 RTC_LOG(LS_INFO) << "Converge time: TIMEOUT ("
592 << converge_wait << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000593 }
594 }
595 // Try sending some data to other end.
Steve Antone9324572017-11-29 10:18:21 -0800596 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000597
598 // Destroy the channels, and wait for them to be fully cleaned up.
599 DestroyChannels();
600 }
601
Steve Antone9324572017-11-29 10:18:21 -0800602 void TestSendRecv(rtc::FakeClock* clock) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000603 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700604 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000605 int len = static_cast<int>(strlen(data));
606 // local_channel1 <==> remote_channel1
honghaize58d73d2016-10-24 16:38:26 -0700607 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800608 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700609 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800610 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700611 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800612 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700613 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800614 kMediumTimeout, *clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000615 }
616 }
617
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700618 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700619 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000620 // restart the ice gathering. Finally it waits for the transport to select a
621 // new connection using the newly generated ice candidates.
622 // Before calling this function the end points must be configured.
623 void TestHandleIceUfragPasswordChanged() {
honghaize58d73d2016-10-24 16:38:26 -0700624 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700625 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
626 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
honghaize58d73d2016-10-24 16:38:26 -0700627 EXPECT_TRUE_SIMULATED_WAIT(
628 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
629 ep2_ch1()->receiving() && ep2_ch1()->writable(),
630 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000631
deadbeef14f97f52016-06-22 17:14:15 -0700632 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
633 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
634 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
635 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000636
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700637 ep1_ch1()->SetIceParameters(kIceParams[2]);
638 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700639 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700640 ep2_ch1()->SetIceParameters(kIceParams[3]);
641
642 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700643 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000644
honghaize58d73d2016-10-24 16:38:26 -0700645 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
646 old_local_candidate1->generation(),
647 kMediumTimeout, clock);
648 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
649 old_local_candidate2->generation(),
650 kMediumTimeout, clock);
651 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
652 old_remote_candidate1->generation(),
653 kMediumTimeout, clock);
654 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
655 old_remote_candidate2->generation(),
656 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000657 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
658 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
659 }
660
661 void TestSignalRoleConflict() {
honghaize58d73d2016-10-24 16:38:26 -0700662 rtc::ScopedFakeClock clock;
663 // Default EP1 is in controlling state.
664 SetIceTiebreaker(0, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000665
deadbeef14f97f52016-06-22 17:14:15 -0700666 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700667 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000668
669 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700670 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000671 // Since both the channels initiated with controlling state and channel2
672 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
honghaize58d73d2016-10-24 16:38:26 -0700673 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000674 EXPECT_FALSE(GetRoleConflict(1));
675
honghaize58d73d2016-10-24 16:38:26 -0700676 EXPECT_TRUE_SIMULATED_WAIT(
677 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
678 ep2_ch1()->receiving() && ep2_ch1()->writable(),
679 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000680
Honghai Zhang572b0942016-06-23 12:26:57 -0700681 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
682 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000683
Steve Antone9324572017-11-29 10:18:21 -0800684 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000685 }
686
Qingsi Wang6e641e62018-04-11 20:14:17 -0700687 void TestPacketInfoIsSet(rtc::PacketInfo info) {
688 EXPECT_NE(info.packet_type, rtc::PacketType::kUnknown);
689 EXPECT_NE(info.protocol, rtc::PacketInfoProtocolType::kUnknown);
690 EXPECT_TRUE(info.network_id.has_value());
691 EXPECT_FALSE(info.local_socket_address.IsNil());
692 }
693
deadbeef5bd5ca32017-02-10 11:31:50 -0800694 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700695 GetEndpoint(transport)->ready_to_send_ = true;
deadbeef14f97f52016-06-22 17:14:15 -0700696 }
697
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000698 // We pass the candidates directly to the other side.
zhihuangd06adf62017-01-12 15:58:31 -0800699 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
deadbeef14f97f52016-06-22 17:14:15 -0700700 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000701 return;
702
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000703 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700704 GetEndpoint(ch)->saved_candidates_.push_back(
705 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000706 } else {
nisse7eaa4ea2017-05-08 05:25:41 -0700707 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
708 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000709 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000710 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800711
Danil Chapovalov00c71832018-06-15 15:58:38 +0200712 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800713 // If the |network_route| is unset, don't count. This is used in the case
714 // when the network on remote side is down, the signal will be fired with an
715 // unset network route and it shouldn't trigger a connection switch.
716 if (network_route) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700717 ++selected_candidate_pair_switches_;
718 }
honghaiz9ad0db52016-07-14 19:30:28 -0700719 }
720
721 int reset_selected_candidate_pair_switches() {
722 int switches = selected_candidate_pair_switches_;
723 selected_candidate_pair_switches_ = 0;
724 return switches;
725 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000726
727 void PauseCandidates(int endpoint) {
728 GetEndpoint(endpoint)->save_candidates_ = true;
729 }
730
zhihuangd06adf62017-01-12 15:58:31 -0800731 void OnCandidatesRemoved(IceTransportInternal* ch,
deadbeef14f97f52016-06-22 17:14:15 -0700732 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700733 // Candidate removals are not paused.
734 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
nisse7eaa4ea2017-05-08 05:25:41 -0700735 main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700736 }
737
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800738 // Tcp candidate verification has to be done when they are generated.
739 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
740 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700741 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700742 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700743 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700744 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
745 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
746 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
747 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700748 } else {
749 FAIL() << "Unknown tcptype: " << candidate.tcptype();
750 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800751 }
752 }
753 }
754
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000755 void ResumeCandidates(int endpoint) {
756 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700757 for (auto& candidate : ed->saved_candidates_) {
nisse7eaa4ea2017-05-08 05:25:41 -0700758 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000759 }
760 ed->saved_candidates_.clear();
761 ed->save_candidates_ = false;
762 }
763
764 void OnMessage(rtc::Message* msg) {
765 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700766 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700767 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700768 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700769 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
770 if (!rch) {
771 return;
772 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700773 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700774 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700775 c.set_username("");
776 c.set_password("");
777 }
Mirko Bonadei675513b2017-11-09 11:09:25 +0100778 RTC_LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
779 << rch->component() << "): " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700780 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000781 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700782 break;
783 }
784 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700785 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700786 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700787 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
788 if (!rch) {
789 return;
790 }
791 for (Candidate& c : data->candidates) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100792 RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700793 rch->RemoveRemoteCandidate(c);
794 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000795 break;
796 }
797 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000798 }
johand89ab142016-10-25 10:50:32 -0700799
deadbeef5bd5ca32017-02-10 11:31:50 -0800800 void OnReadPacket(rtc::PacketTransportInternal* transport,
deadbeef14f97f52016-06-22 17:14:15 -0700801 const char* data,
802 size_t len,
803 const rtc::PacketTime& packet_time,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000804 int flags) {
johand89ab142016-10-25 10:50:32 -0700805 std::list<std::string>& packets = GetPacketList(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000806 packets.push_front(std::string(data, len));
807 }
johand89ab142016-10-25 10:50:32 -0700808
zhihuangd06adf62017-01-12 15:58:31 -0800809 void OnRoleConflict(IceTransportInternal* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000810 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700811 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
812 ? ICEROLE_CONTROLLED
813 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000814 channel->SetIceRole(new_role);
815 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700816
Qingsi Wang6e641e62018-04-11 20:14:17 -0700817 void OnSentPacket(rtc::PacketTransportInternal* transport,
818 const rtc::SentPacket& packet) {
819 TestPacketInfoIsSet(packet.info);
820 }
821
zhihuangd06adf62017-01-12 15:58:31 -0800822 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000823 rtc::PacketOptions options;
824 return channel->SendPacket(data, len, options, 0);
825 }
zhihuangd06adf62017-01-12 15:58:31 -0800826 bool CheckDataOnChannel(IceTransportInternal* channel,
deadbeef14f97f52016-06-22 17:14:15 -0700827 const char* data,
828 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000829 return GetChannelData(channel)->CheckData(data, len);
830 }
deadbeef14f97f52016-06-22 17:14:15 -0700831 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700832 return (ch && ch->selected_connection())
833 ? &ch->selected_connection()->local_candidate()
834 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000835 }
deadbeef14f97f52016-06-22 17:14:15 -0700836 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700837 return (ch && ch->selected_connection())
838 ? &ch->selected_connection()->remote_candidate()
839 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000840 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800841 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700842 if (ep1_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000843 return &ep1_;
johand89ab142016-10-25 10:50:32 -0700844 } else if (ep2_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000845 return &ep2_;
846 } else {
847 return NULL;
848 }
849 }
zhihuangd06adf62017-01-12 15:58:31 -0800850 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000851 if (ch == ep1_ch1())
852 return ep2_ch1();
853 else if (ch == ep1_ch2())
854 return ep2_ch2();
855 else if (ch == ep2_ch1())
856 return ep1_ch1();
857 else if (ch == ep2_ch2())
858 return ep1_ch2();
859 else
860 return NULL;
861 }
johand89ab142016-10-25 10:50:32 -0700862 std::list<std::string>& GetPacketList(
deadbeef5bd5ca32017-02-10 11:31:50 -0800863 rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700864 return GetChannelData(transport)->ch_packets_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000865 }
866
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700867 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700868
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700869 // How does the test pass ICE parameters to the P2PTransportChannel?
870 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700871 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700872 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
873 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000874 }
875
876 void set_force_relay(bool relay) {
877 force_relay_ = relay;
878 }
879
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700880 void ConnectSignalNominated(Connection* conn) {
881 conn->SignalNominated.connect(this,
882 &P2PTransportChannelTestBase::OnNominated);
883 }
884
885 void OnNominated(Connection* conn) { nominated_ = true; }
886 bool nominated() { return nominated_; }
887
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000888 private:
kwiberg3ec46792016-04-27 07:22:53 -0700889 std::unique_ptr<rtc::VirtualSocketServer> vss_;
890 std::unique_ptr<rtc::NATSocketServer> nss_;
891 std::unique_ptr<rtc::FirewallSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700892 rtc::AutoSocketServerThread main_;
deadbeef14f97f52016-06-22 17:14:15 -0700893 std::unique_ptr<TestStunServer> stun_server_;
894 TestTurnServer turn_server_;
deadbeeff137e972017-03-23 15:45:49 -0700895 rtc::SocksProxyServer socks_server1_;
896 rtc::SocksProxyServer socks_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000897 Endpoint ep1_;
898 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700899 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000900 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700901 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700902
903 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000904};
905
906// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700907const P2PTransportChannelTestBase::Result
908 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
909 "udp",
910 "local",
911 "udp",
912 1000);
913const P2PTransportChannelTestBase::Result
914 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
915 "udp",
916 "stun",
917 "udp",
918 1000);
919const P2PTransportChannelTestBase::Result
920 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
921 "udp",
922 "prflx",
923 "udp",
924 1000);
925const P2PTransportChannelTestBase::Result
926 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
927 "udp",
928 "local",
929 "udp",
930 1000);
931const P2PTransportChannelTestBase::Result
932 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
933 "udp",
934 "local",
935 "udp",
936 1000);
937const P2PTransportChannelTestBase::Result
938 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
939 "udp",
940 "stun",
941 "udp",
942 1000);
943const P2PTransportChannelTestBase::Result
944 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
945 "udp",
946 "prflx",
947 "udp",
948 1000);
949const P2PTransportChannelTestBase::Result
950 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
951 "udp",
952 "stun",
953 "udp",
954 1000);
955const P2PTransportChannelTestBase::Result
956 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
957 "udp",
958 "relay",
959 "udp",
960 2000);
961const P2PTransportChannelTestBase::Result
962 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
963 "udp",
964 "relay",
965 "udp",
966 2000);
967const P2PTransportChannelTestBase::Result
968 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
969 "udp",
970 "prflx",
971 "udp",
972 2000);
973const P2PTransportChannelTestBase::Result
974 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
975 "tcp",
976 "local",
977 "tcp",
978 3000);
979const P2PTransportChannelTestBase::Result
980 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
981 "tcp",
982 "prflx",
983 "tcp",
984 3000);
985const P2PTransportChannelTestBase::Result
986 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
987 "tcp",
988 "local",
989 "tcp",
990 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000991
992// Test the matrix of all the connectivity types we expect to see in the wild.
993// Just test every combination of the configs in the Config enum.
994class P2PTransportChannelTest : public P2PTransportChannelTestBase {
995 protected:
996 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700997 void ConfigureEndpoints(Config config1,
998 Config config2,
999 int allocator_flags1,
1000 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001001 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001002 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001003 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001004 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001005 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001006 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001007
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001008 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001009 }
1010 void ConfigureEndpoint(int endpoint, Config config) {
1011 switch (config) {
1012 case OPEN:
1013 AddAddress(endpoint, kPublicAddrs[endpoint]);
1014 break;
1015 case NAT_FULL_CONE:
1016 case NAT_ADDR_RESTRICTED:
1017 case NAT_PORT_RESTRICTED:
1018 case NAT_SYMMETRIC:
1019 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1020 // Add a single NAT of the desired type
1021 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1022 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
1023 AddClient(kPrivateAddrs[endpoint]);
1024 break;
1025 case NAT_DOUBLE_CONE:
1026 case NAT_SYMMETRIC_THEN_CONE:
1027 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1028 // Add a two cascaded NATs of the desired types
1029 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1030 (config == NAT_DOUBLE_CONE) ?
1031 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
1032 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1033 rtc::NAT_OPEN_CONE)->
1034 AddClient(kCascadedPrivateAddrs[endpoint]);
1035 break;
1036 case BLOCK_UDP:
1037 case BLOCK_UDP_AND_INCOMING_TCP:
deadbeeff137e972017-03-23 15:45:49 -07001038 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1039 case PROXY_HTTPS:
1040 case PROXY_SOCKS:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001041 AddAddress(endpoint, kPublicAddrs[endpoint]);
1042 // Block all UDP
1043 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
1044 kPublicAddrs[endpoint]);
1045 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1046 // Block TCP inbound to the endpoint
1047 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1048 kPublicAddrs[endpoint]);
deadbeeff137e972017-03-23 15:45:49 -07001049 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1050 // Block all TCP to/from the endpoint except 80/443 out
1051 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1052 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1053 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1054 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1055 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1056 kPublicAddrs[endpoint]);
1057 } else if (config == PROXY_HTTPS) {
1058 // Block all TCP to/from the endpoint except to the proxy server
1059 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1060 kHttpsProxyAddrs[endpoint]);
1061 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1062 kPublicAddrs[endpoint]);
1063 SetProxy(endpoint, rtc::PROXY_HTTPS);
1064 } else if (config == PROXY_SOCKS) {
1065 // Block all TCP to/from the endpoint except to the proxy server
1066 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1067 kSocksProxyAddrs[endpoint]);
1068 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1069 kPublicAddrs[endpoint]);
1070 SetProxy(endpoint, rtc::PROXY_SOCKS5);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001071 }
1072 break;
1073 default:
deadbeef1ee21252017-06-13 15:49:45 -07001074 RTC_NOTREACHED();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001075 break;
1076 }
1077 }
1078};
1079
1080// Shorthands for use in the test matrix.
1081#define LULU &kLocalUdpToLocalUdp
1082#define LUSU &kLocalUdpToStunUdp
1083#define LUPU &kLocalUdpToPrflxUdp
1084#define PULU &kPrflxUdpToLocalUdp
1085#define SULU &kStunUdpToLocalUdp
1086#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001087#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001088#define PUSU &kPrflxUdpToStunUdp
1089#define LURU &kLocalUdpToRelayUdp
1090#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001091#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001092#define LTLT &kLocalTcpToLocalTcp
1093#define LTPT &kLocalTcpToPrflxTcp
1094#define PTLT &kPrflxTcpToLocalTcp
Steve Antone9324572017-11-29 10:18:21 -08001095// TODO(?): Enable these once TestRelayServer can accept external TCP.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001096#define LTRT NULL
1097#define LSRS NULL
1098
1099// Test matrix. Originator behavior defined by rows, receiever by columns.
1100
Steve Antone9324572017-11-29 10:18:21 -08001101// TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
1102// TODO(?): Fix NULLs caused by no HTTP proxy support.
1103// TODO(?): Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001104const P2PTransportChannelTest::Result*
1105 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
deadbeeff137e972017-03-23 15:45:49 -07001106// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1107/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL, LTPT},
1108/*CO*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1109/*AD*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1110/*PO*/ {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, LTRT},
1111/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1112/*2C*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1113/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1114/*!U*/ {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, LTRT},
1115/*!T*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1116/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1117/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1118/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001119};
1120
1121// The actual tests that exercise all the various configurations.
1122// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001123#define P2P_TEST_DECLARATION(x, y, z) \
1124 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1125 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1126 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001127 if (kMatrix[x][y] != NULL) \
1128 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001129 else \
Mirko Bonadei675513b2017-11-09 11:09:25 +01001130 RTC_LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001131 }
1132
Steve Antone9324572017-11-29 10:18:21 -08001133#define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001134
deadbeeff137e972017-03-23 15:45:49 -07001135#define P2P_TEST_SET(x) \
1136 P2P_TEST(x, OPEN) \
1137 P2P_TEST(x, NAT_FULL_CONE) \
1138 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1139 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1140 P2P_TEST(x, NAT_SYMMETRIC) \
1141 P2P_TEST(x, NAT_DOUBLE_CONE) \
1142 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1143 P2P_TEST(x, BLOCK_UDP) \
1144 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1145 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1146 P2P_TEST(x, PROXY_HTTPS) \
1147 P2P_TEST(x, PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001148
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001149P2P_TEST_SET(OPEN)
1150P2P_TEST_SET(NAT_FULL_CONE)
1151P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1152P2P_TEST_SET(NAT_PORT_RESTRICTED)
1153P2P_TEST_SET(NAT_SYMMETRIC)
1154P2P_TEST_SET(NAT_DOUBLE_CONE)
1155P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1156P2P_TEST_SET(BLOCK_UDP)
1157P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
deadbeeff137e972017-03-23 15:45:49 -07001158P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1159P2P_TEST_SET(PROXY_HTTPS)
1160P2P_TEST_SET(PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001161
1162// Test that we restart candidate allocation when local ufrag&pwd changed.
1163// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001164TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001165 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001166 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001167 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001168 TestHandleIceUfragPasswordChanged();
1169 DestroyChannels();
1170}
1171
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001172// Same as above test, but with a symmetric NAT.
1173// We should end up with relay<->prflx candidate pairs, with generation "1".
1174TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1175 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1176 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001177 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001178 TestHandleIceUfragPasswordChanged();
1179 DestroyChannels();
1180}
1181
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001182// Test the operation of GetStats.
1183TEST_F(P2PTransportChannelTest, GetStats) {
honghaize58d73d2016-10-24 16:38:26 -07001184 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001185 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001186 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001187 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -07001188 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1189 ep2_ch1()->receiving() &&
1190 ep2_ch1()->writable(),
1191 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001192 TestSendRecv(&clock);
deadbeef14f97f52016-06-22 17:14:15 -07001193 ConnectionInfos infos;
Qingsi Wang72a43a12018-02-20 16:03:18 -08001194 CandidateStatsList candidate_stats_list;
1195 ASSERT_TRUE(ep1_ch1()->GetStats(&infos, &candidate_stats_list));
Steve Antone9324572017-11-29 10:18:21 -08001196 ASSERT_GE(infos.size(), 1u);
Qingsi Wang72a43a12018-02-20 16:03:18 -08001197 ASSERT_GE(candidate_stats_list.size(), 1u);
deadbeef14f97f52016-06-22 17:14:15 -07001198 ConnectionInfo* best_conn_info = nullptr;
1199 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001200 if (info.best_connection) {
1201 best_conn_info = &info;
1202 break;
1203 }
1204 }
1205 ASSERT_TRUE(best_conn_info != nullptr);
1206 EXPECT_TRUE(best_conn_info->new_connection);
1207 EXPECT_TRUE(best_conn_info->receiving);
1208 EXPECT_TRUE(best_conn_info->writable);
1209 EXPECT_FALSE(best_conn_info->timeout);
1210 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1211 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1212 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1213 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001214 DestroyChannels();
1215}
1216
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001217// Tests that UMAs are recorded when ICE restarts while the channel
1218// is disconnected.
1219TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1220 rtc::ScopedFakeClock clock;
1221 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1222
1223 CreateChannels();
1224 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1225 ep2_ch1()->receiving() &&
1226 ep2_ch1()->writable(),
1227 kDefaultTimeout, clock);
1228
1229 // Drop all packets so that both channels become not writable.
1230 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
skvlad51072462017-02-02 11:50:14 -08001231 const int kWriteTimeoutDelay = 8000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001232 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1233 kWriteTimeoutDelay, clock);
1234
1235 ep1_ch1()->SetIceParameters(kIceParams[2]);
1236 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1237 ep1_ch1()->MaybeStartGathering();
1238 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1239 webrtc::kEnumCounterIceRestart,
1240 static_cast<int>(IceRestartState::DISCONNECTED)));
1241
1242 ep2_ch1()->SetIceParameters(kIceParams[3]);
1243 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1244 ep2_ch1()->MaybeStartGathering();
1245 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1246 webrtc::kEnumCounterIceRestart,
1247 static_cast<int>(IceRestartState::DISCONNECTED)));
1248
1249 DestroyChannels();
1250}
1251
1252// Tests that UMAs are recorded when ICE restarts while the channel
1253// is connected.
1254TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1255 rtc::ScopedFakeClock clock;
1256 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1257
1258 CreateChannels();
1259 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1260 ep2_ch1()->receiving() &&
1261 ep2_ch1()->writable(),
1262 kDefaultTimeout, clock);
1263
1264 ep1_ch1()->SetIceParameters(kIceParams[2]);
1265 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1266 ep1_ch1()->MaybeStartGathering();
1267 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1268 webrtc::kEnumCounterIceRestart,
1269 static_cast<int>(IceRestartState::CONNECTED)));
1270
1271 ep2_ch1()->SetIceParameters(kIceParams[3]);
1272 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1273 ep2_ch1()->MaybeStartGathering();
1274 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1275 webrtc::kEnumCounterIceRestart,
1276 static_cast<int>(IceRestartState::CONNECTED)));
1277
1278 DestroyChannels();
1279}
1280
1281// Tests that UMAs are recorded when ICE restarts while the channel
1282// is connecting.
1283TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1284 rtc::ScopedFakeClock clock;
1285 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1286
1287 // Create the channels without waiting for them to become connected.
1288 CreateChannels();
1289
1290 ep1_ch1()->SetIceParameters(kIceParams[2]);
1291 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1292 ep1_ch1()->MaybeStartGathering();
1293 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1294 webrtc::kEnumCounterIceRestart,
1295 static_cast<int>(IceRestartState::CONNECTING)));
1296
1297 ep2_ch1()->SetIceParameters(kIceParams[3]);
1298 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1299 ep2_ch1()->MaybeStartGathering();
1300 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1301 webrtc::kEnumCounterIceRestart,
1302 static_cast<int>(IceRestartState::CONNECTING)));
1303
1304 DestroyChannels();
1305}
1306
1307// Tests that a UMA on ICE regathering is recorded when there is a network
1308// change if and only if continual gathering is enabled.
1309TEST_F(P2PTransportChannelTest,
1310 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1311 rtc::ScopedFakeClock clock;
1312 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1313
1314 // ep1 gathers continually but ep2 does not.
1315 IceConfig continual_gathering_config =
1316 CreateIceConfig(1000, GATHER_CONTINUALLY);
1317 IceConfig default_config;
1318 CreateChannels(continual_gathering_config, default_config);
1319
1320 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1321 ep2_ch1()->receiving() &&
1322 ep2_ch1()->writable(),
1323 kDefaultTimeout, clock);
1324
1325 // Adding address in ep1 will trigger continual gathering.
1326 AddAddress(0, kAlternateAddrs[0]);
1327 EXPECT_EQ_SIMULATED_WAIT(
1328 1, GetMetricsObserver(0)->GetEnumCounter(
1329 webrtc::kEnumCounterIceRegathering,
1330 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)),
1331 kDefaultTimeout, clock);
1332
1333 ep2_ch1()->SetIceParameters(kIceParams[3]);
1334 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1335 ep2_ch1()->MaybeStartGathering();
1336
1337 AddAddress(1, kAlternateAddrs[1]);
1338 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1339 // ep2 has not enabled continual gathering.
1340 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1341 webrtc::kEnumCounterIceRegathering,
1342 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)));
1343
1344 DestroyChannels();
1345}
1346
1347// Tests that a UMA on ICE regathering is recorded when there is a network
1348// failure if and only if continual gathering is enabled.
1349TEST_F(P2PTransportChannelTest,
1350 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1351 rtc::ScopedFakeClock clock;
1352 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1353
1354 // ep1 gathers continually but ep2 does not.
1355 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001356 config1.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001357 IceConfig config2;
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001358 config2.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001359 CreateChannels(config1, config2);
1360
1361 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1362 ep2_ch1()->receiving() &&
1363 ep2_ch1()->writable(),
1364 kDefaultTimeout, clock);
1365
1366 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1367 // Timeout value such that all connections are deleted.
1368 const int kNetworkFailureTimeout = 35000;
1369 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
1370 EXPECT_LE(1, GetMetricsObserver(0)->GetEnumCounter(
1371 webrtc::kEnumCounterIceRegathering,
1372 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1373 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1374 webrtc::kEnumCounterIceRegathering,
1375 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1376
1377 DestroyChannels();
1378}
1379
Steve Anton300bf8e2017-07-14 10:13:10 -07001380// Tests that ICE regathering occurs regularly when
1381// regather_all_networks_interval_range configuration value is set.
1382TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
1383 rtc::ScopedFakeClock clock;
1384 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1385
1386 // ep1 gathers continually but ep2 does not.
1387 const int kRegatherInterval = 2000;
1388 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1389 config1.regather_all_networks_interval_range.emplace(
1390 kRegatherInterval, kRegatherInterval);
1391 IceConfig config2;
Steve Anton300bf8e2017-07-14 10:13:10 -07001392 CreateChannels(config1, config2);
1393
1394 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1395 ep2_ch1()->receiving() &&
1396 ep2_ch1()->writable(),
1397 kDefaultTimeout, clock);
1398
1399 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1400 // Timeout value such that all connections are deleted.
1401 const int kNetworkGatherDuration = 11000;
1402 SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
1403 // Expect regathering to happen 5 times in 11s with 2s interval.
1404 EXPECT_LE(5, GetMetricsObserver(0)->GetEnumCounter(
1405 webrtc::kEnumCounterIceRegathering,
1406 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1407 // Expect no regathering if continual gathering not configured.
1408 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1409 webrtc::kEnumCounterIceRegathering,
1410 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1411
1412 DestroyChannels();
1413}
1414
1415// Test that ICE periodic regathering can change the selected connection on the
1416// specified interval and that the peers can communicate over the new
1417// connection. The test is parameterized to test that it works when regathering
1418// is done by the ICE controlling peer and when done by the controlled peer.
1419class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
1420 protected:
1421 void TestWithRoles(IceRole p1_role, IceRole p2_role) {
1422 rtc::ScopedFakeClock clock;
1423 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1424 kDefaultPortAllocatorFlags);
1425 set_force_relay(true);
1426
1427 const int kRegatherInterval = 2000;
1428 const int kNumRegathers = 2;
1429
1430 // Set up peer 1 to auto regather every 2s.
1431 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1432 config1.regather_all_networks_interval_range.emplace(
1433 kRegatherInterval, kRegatherInterval);
1434 IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1435
1436 // Set peer roles.
1437 SetIceRole(0, p1_role);
1438 SetIceRole(1, p2_role);
1439
1440 CreateChannels(config1, config2);
1441
1442 // Wait for initial connection to be made.
1443 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() &&
1444 ep1_ch1()->writable() &&
1445 ep2_ch1()->receiving() &&
1446 ep2_ch1()->writable(),
1447 kMediumTimeout, clock);
1448
1449 const Connection* initial_selected = ep1_ch1()->selected_connection();
1450
1451 // Wait long enough for 2 regathering cycles to happen plus some extra so
1452 // the new connection has time to settle.
1453 const int kWaitRegather =
1454 kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
1455 SIMULATED_WAIT(false, kWaitRegather, clock);
1456 EXPECT_EQ(kNumRegathers, GetMetricsObserver(0)->GetEnumCounter(
1457 webrtc::kEnumCounterIceRegathering,
1458 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1459
1460 const Connection* new_selected = ep1_ch1()->selected_connection();
1461
1462 // Want the new selected connection to be different.
1463 ASSERT_NE(initial_selected, new_selected);
1464
1465 // Make sure we can communicate over the new connection too.
Steve Antone9324572017-11-29 10:18:21 -08001466 TestSendRecv(&clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001467 }
1468};
1469
1470TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
1471 TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
1472}
1473
1474TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
1475 TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
1476}
1477
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001478// Test that we properly create a connection on a STUN ping from unknown address
1479// when the signaling is slow.
1480TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001481 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001482 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001483 // Emulate no remote parameters coming in.
1484 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001485 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001486 // Only have remote parameters come in for ep2, not ep1.
1487 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001488
1489 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1490 // candidate.
1491 PauseCandidates(1);
1492
Honghai Zhange05bcc22016-08-16 18:19:14 -07001493 // Wait until the callee becomes writable to make sure that a ping request is
1494 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001495 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001496 // Add two sets of remote ICE credentials, so that the ones used by the
1497 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001498 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1499 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001500 // The caller should have the selected connection connected to the peer
1501 // reflexive candidate.
1502 const Connection* selected_connection = nullptr;
1503 ASSERT_TRUE_WAIT(
1504 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001505 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001506 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001507 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1508 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1509 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001510
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001511 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001512 // Verify ep1's selected connection is updated to use the 'local' candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001513 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001514 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001515 kMediumTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001516 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001517 DestroyChannels();
1518}
1519
1520// Test that we properly create a connection on a STUN ping from unknown address
1521// when the signaling is slow and the end points are behind NAT.
1522TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001523 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001524 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001525 // Emulate no remote parameters coming in.
1526 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001527 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001528 // Only have remote parameters come in for ep2, not ep1.
1529 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001530 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1531 // candidate.
1532 PauseCandidates(1);
1533
Honghai Zhange05bcc22016-08-16 18:19:14 -07001534 // Wait until the callee becomes writable to make sure that a ping request is
1535 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001536 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001537 // Add two sets of remote ICE credentials, so that the ones used by the
1538 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001539 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1540 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001541
1542 // The caller's selected connection should be connected to the peer reflexive
1543 // candidate.
1544 const Connection* selected_connection = nullptr;
1545 ASSERT_TRUE_WAIT(
1546 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001547 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001548 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001549 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1550 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1551 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001552
1553 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001554
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001555 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhange05bcc22016-08-16 18:19:14 -07001556 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001557 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001558 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001559 DestroyChannels();
1560}
1561
deadbeef0af180b2016-06-21 13:15:32 -07001562// Test that we properly create a connection on a STUN ping from unknown address
1563// when the signaling is slow, even if the new candidate is created due to the
1564// remote peer doing an ICE restart, pairing this candidate across generations.
1565//
1566// Previously this wasn't working due to a bug where the peer reflexive
1567// candidate was only updated for the newest generation candidate pairs, and
1568// not older-generation candidate pairs created by pairing candidates across
1569// generations. This resulted in the old-generation prflx candidate being
1570// prioritized above new-generation candidate pairs.
1571TEST_F(P2PTransportChannelTest,
1572 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1573 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1574 kDefaultPortAllocatorFlags);
1575 // Only gather relay candidates, so that when the prflx candidate arrives
1576 // it's prioritized above the current candidate pair.
deadbeef14f97f52016-06-22 17:14:15 -07001577 GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
1578 GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001579 // Setting this allows us to control when SetRemoteIceParameters is called.
1580 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001581 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001582 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001583 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1584 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001585 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1586 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1587 kDefaultTimeout);
1588
1589 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001590 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001591 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001592 ep2_ch1()->SetIceParameters(kIceParams[3]);
1593
1594 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001595 ep2_ch1()->MaybeStartGathering();
1596
Honghai Zhang572b0942016-06-23 12:26:57 -07001597 // The caller should have the selected connection connected to the peer
1598 // reflexive candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001599 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001600 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001601 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001602 const Connection* prflx_selected_connection =
1603 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001604
1605 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001606 ep1_ch1()->SetIceParameters(kIceParams[2]);
1607
1608 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001609 ep1_ch1()->MaybeStartGathering();
1610
1611 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1612 // their information to update the peer reflexive candidate.
1613 ResumeCandidates(1);
1614
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001615 EXPECT_EQ_WAIT(RELAY_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001616 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001617 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001618 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001619 DestroyChannels();
1620}
1621
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001622// Test that if remote candidates don't have ufrag and pwd, we still work.
1623TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001624 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001625 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001626 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001627 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001628 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001629 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001630 // Wait until the callee's connections are created.
Honghai Zhang161a5862016-10-20 11:47:02 -07001631 EXPECT_TRUE_SIMULATED_WAIT(
1632 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1633 kMediumTimeout, clock);
1634 // Wait to make sure the selected connection is not changed.
1635 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1636 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001637 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001638 DestroyChannels();
1639}
1640
1641// Test that a host behind NAT cannot be reached when incoming_only
1642// is set to true.
1643TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
honghaize58d73d2016-10-24 16:38:26 -07001644 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001645 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001646 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001647
1648 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001649 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001650 ep1_ch1()->set_incoming_only(true);
1651
1652 // Pump for 1 second and verify that the channels are not connected.
honghaize58d73d2016-10-24 16:38:26 -07001653 SIMULATED_WAIT(false, kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001654
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001655 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001656 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001657 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001658 EXPECT_FALSE(ep2_ch1()->writable());
1659
1660 DestroyChannels();
1661}
1662
1663// Test that a peer behind NAT can connect to a peer that has
1664// incoming_only flag set.
1665TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
honghaize58d73d2016-10-24 16:38:26 -07001666 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001667 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001668 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001669
1670 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001671 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001672 ep1_ch1()->set_incoming_only(true);
1673
honghaize58d73d2016-10-24 16:38:26 -07001674 EXPECT_TRUE_SIMULATED_WAIT(
1675 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1676 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1677 ep2_ch1()->writable(),
1678 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001679
1680 DestroyChannels();
1681}
1682
deadbeef1ee21252017-06-13 15:49:45 -07001683// Test that two peers can connect when one can only make outgoing TCP
1684// connections. This has been observed in some scenarios involving
1685// VPNs/firewalls.
1686TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
1687 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1688 // application needs this use case to work, since the application must accept
1689 // the tradeoff that more candidates need to be allocated.
1690 //
1691 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1692 // things to ensure extra candidates don't waste resources?
1693 ConfigureEndpoints(
1694 OPEN, OPEN,
1695 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1696 kDefaultPortAllocatorFlags);
1697 // In order to simulate nothing working but outgoing TCP connections, prevent
1698 // the endpoint from binding to its interface's address as well as the
1699 // "any" addresses. It can then only make a connection by using "Connect()".
1700 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1701 kPublicAddrs[0].ipaddr()});
1702 CreateChannels();
1703 // Expect a "prflx" candidate on the side that can only make outgoing
1704 // connections, endpoint 0.
1705 Test(kPrflxTcpToLocalTcp);
1706 DestroyChannels();
1707}
1708
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001709TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
honghaize58d73d2016-10-24 16:38:26 -07001710 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001711 AddAddress(0, kPublicAddrs[0]);
1712 AddAddress(1, kPublicAddrs[1]);
1713
1714 SetAllocationStepDelay(0, kMinimumStepDelay);
1715 SetAllocationStepDelay(1, kMinimumStepDelay);
1716
deadbeef14f97f52016-06-22 17:14:15 -07001717 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1718 PORTALLOCATOR_DISABLE_STUN |
1719 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001720 // Disable all protocols except TCP.
1721 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1722 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1723
1724 SetAllowTcpListen(0, true); // actpass.
1725 SetAllowTcpListen(1, false); // active.
1726
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001727 // We want SetRemoteIceParameters to be called as it normally would.
1728 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001729 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001730 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001731
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001732 // Pause candidate so we could verify the candidate properties.
1733 PauseCandidates(0);
1734 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001735 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001736
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001737 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001738 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1739 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001740
1741 // Resume candidates.
1742 ResumeCandidates(0);
1743 ResumeCandidates(1);
1744
honghaize58d73d2016-10-24 16:38:26 -07001745 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1746 ep2_ch1()->receiving() &&
1747 ep2_ch1()->writable(),
1748 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001749 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1750 ep2_ch1()->selected_connection() &&
1751 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1752 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001753
Steve Antone9324572017-11-29 10:18:21 -08001754 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001755 DestroyChannels();
1756}
1757
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001758TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001759 AddAddress(0, kPublicAddrs[0]);
1760 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001761 TestSignalRoleConflict();
1762}
1763
1764// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1765// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001766TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
honghaize58d73d2016-10-24 16:38:26 -07001767 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001768 AddAddress(0, kPublicAddrs[0]);
1769 AddAddress(1, kPublicAddrs[1]);
1770
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001771 // Give the first connection the higher tiebreaker so its role won't
1772 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001773 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001774 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001775 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001776 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001777
johan02bd5122016-09-20 00:23:27 -07001778 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001779
honghaize58d73d2016-10-24 16:38:26 -07001780 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001781
deadbeef14f97f52016-06-22 17:14:15 -07001782 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001783 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001784 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001785 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001786 }
1787
deadbeef14f97f52016-06-22 17:14:15 -07001788 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001789 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001790
deadbeef14f97f52016-06-22 17:14:15 -07001791 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001792 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001793 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001794 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001795 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001796 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001797 }
1798
honghaize58d73d2016-10-24 16:38:26 -07001799 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1800 ep2_ch1()->receiving() &&
1801 ep2_ch1()->writable(),
1802 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001803
Honghai Zhang572b0942016-06-23 12:26:57 -07001804 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1805 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001806
Steve Antone9324572017-11-29 10:18:21 -08001807 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001808 DestroyChannels();
1809}
1810
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001811// Verify that we can set DSCP value and retrieve properly from P2PTC.
1812TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1813 AddAddress(0, kPublicAddrs[0]);
1814 AddAddress(1, kPublicAddrs[1]);
1815
johan02bd5122016-09-20 00:23:27 -07001816 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001817 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1818 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1819 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1820 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1821 GetEndpoint(0)->cd1_.ch_->SetOption(
1822 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1823 GetEndpoint(1)->cd1_.ch_->SetOption(
1824 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1825 EXPECT_EQ(rtc::DSCP_CS6,
1826 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1827 EXPECT_EQ(rtc::DSCP_CS6,
1828 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1829 GetEndpoint(0)->cd1_.ch_->SetOption(
1830 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1831 GetEndpoint(1)->cd1_.ch_->SetOption(
1832 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1833 EXPECT_EQ(rtc::DSCP_AF41,
1834 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1835 EXPECT_EQ(rtc::DSCP_AF41,
1836 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1837}
1838
1839// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001840TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
honghaize58d73d2016-10-24 16:38:26 -07001841 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001842 AddAddress(0, kIPv6PublicAddrs[0]);
1843 AddAddress(0, kPublicAddrs[0]);
1844 AddAddress(1, kIPv6PublicAddrs[1]);
1845 AddAddress(1, kPublicAddrs[1]);
1846
1847 SetAllocationStepDelay(0, kMinimumStepDelay);
1848 SetAllocationStepDelay(1, kMinimumStepDelay);
1849
1850 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08001851 SetAllocatorFlags(
1852 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1853 SetAllocatorFlags(
1854 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001855
johan02bd5122016-09-20 00:23:27 -07001856 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001857
honghaize58d73d2016-10-24 16:38:26 -07001858 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1859 ep2_ch1()->receiving() &&
1860 ep2_ch1()->writable(),
1861 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001862 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001863 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001864 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1865 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1866
Steve Antone9324572017-11-29 10:18:21 -08001867 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001868 DestroyChannels();
1869}
1870
1871// Testing forceful TURN connections.
1872TEST_F(P2PTransportChannelTest, TestForceTurn) {
honghaize58d73d2016-10-24 16:38:26 -07001873 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001874 ConfigureEndpoints(
1875 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001876 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1877 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001878 set_force_relay(true);
1879
1880 SetAllocationStepDelay(0, kMinimumStepDelay);
1881 SetAllocationStepDelay(1, kMinimumStepDelay);
1882
johan02bd5122016-09-20 00:23:27 -07001883 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001884
honghaize58d73d2016-10-24 16:38:26 -07001885 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1886 ep2_ch1()->receiving() &&
1887 ep2_ch1()->writable(),
1888 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001889
Honghai Zhang572b0942016-06-23 12:26:57 -07001890 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1891 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001892
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001893 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1894 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1895 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type());
1896 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001897
Steve Antone9324572017-11-29 10:18:21 -08001898 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001899 DestroyChannels();
1900}
1901
honghaiz98db68f2015-09-29 07:58:17 -07001902// Test that if continual gathering is set to true, ICE gathering state will
1903// not change to "Complete", and vice versa.
1904TEST_F(P2PTransportChannelTest, TestContinualGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001905 rtc::ScopedFakeClock clock;
honghaiz98db68f2015-09-29 07:58:17 -07001906 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1907 kDefaultPortAllocatorFlags);
1908 SetAllocationStepDelay(0, kDefaultStepDelay);
1909 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07001910 IceConfig continual_gathering_config =
1911 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001912 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07001913 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07001914 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07001915
Honghai Zhang161a5862016-10-20 11:47:02 -07001916 EXPECT_TRUE_SIMULATED_WAIT(
1917 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1918 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1919 ep2_ch1()->writable(),
1920 kMediumTimeout, clock);
1921 SIMULATED_WAIT(
1922 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
1923 kShortTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07001924 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001925 ep1_ch1()->gathering_state());
1926 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001927 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001928 ep2_ch1()->gathering_state());
1929
1930 DestroyChannels();
1931}
1932
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001933// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1934// PortAllocatorSession that has not yet finished gathering candidates.
1935TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001936 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001937 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1938 kDefaultPortAllocatorFlags);
1939 // First create a pooled session for each endpoint.
1940 auto& allocator_1 = GetEndpoint(0)->allocator_;
1941 auto& allocator_2 = GetEndpoint(1)->allocator_;
1942 int pool_size = 1;
1943 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001944 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001945 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001946 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001947 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001948 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001949 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001950 allocator_2->GetPooledSession();
1951 ASSERT_NE(nullptr, pooled_session_1);
1952 ASSERT_NE(nullptr, pooled_session_2);
1953 // Sanity check that pooled sessions haven't gathered anything yet.
1954 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1955 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1956 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1957 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1958 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001959 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001960 EXPECT_TRUE_SIMULATED_WAIT(
1961 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1962 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1963 ep2_ch1()->writable(),
1964 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001965 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001966 // Make sure the P2PTransportChannels are actually using ports from the
1967 // pooled sessions.
1968 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1969 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1970 EXPECT_NE(pooled_ports_1.end(),
1971 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001972 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001973 EXPECT_NE(pooled_ports_2.end(),
1974 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001975 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001976}
1977
1978// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1979// PortAllocatorSession that already finished gathering candidates.
1980TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001981 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001982 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1983 kDefaultPortAllocatorFlags);
1984 // First create a pooled session for each endpoint.
1985 auto& allocator_1 = GetEndpoint(0)->allocator_;
1986 auto& allocator_2 = GetEndpoint(1)->allocator_;
1987 int pool_size = 1;
1988 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001989 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001990 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001991 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001992 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001993 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001994 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001995 allocator_2->GetPooledSession();
1996 ASSERT_NE(nullptr, pooled_session_1);
1997 ASSERT_NE(nullptr, pooled_session_2);
1998 // Wait for the pooled sessions to finish gathering before the
1999 // P2PTransportChannels try to use them.
Honghai Zhang161a5862016-10-20 11:47:02 -07002000 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
2001 pooled_session_2->CandidatesAllocationDone(),
2002 kDefaultTimeout, clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002003 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07002004 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07002005 EXPECT_TRUE_SIMULATED_WAIT(
2006 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
2007 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2008 ep2_ch1()->writable(),
2009 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08002010 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002011 // Make sure the P2PTransportChannels are actually using ports from the
2012 // pooled sessions.
2013 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2014 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
2015 EXPECT_NE(pooled_ports_1.end(),
2016 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002017 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002018 EXPECT_NE(pooled_ports_2.end(),
2019 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002020 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002021}
2022
deadbeef14f97f52016-06-22 17:14:15 -07002023// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07002024// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07002025// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07002026// TODO(deadbeef): Move this and other "presumed writable" tests into a test
2027// class that operates on a single P2PTransportChannel, once an appropriate one
2028// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07002029TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
2030 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2031 kDefaultPortAllocatorFlags);
2032 // Only configure one channel so we can control when the remote candidate
2033 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002034 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2035 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07002036 IceConfig config;
2037 config.presume_writable_when_fully_relayed = true;
2038 ep1_ch1()->SetIceConfig(config);
2039 ep1_ch1()->MaybeStartGathering();
2040 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2041 ep1_ch1()->gathering_state(), kDefaultTimeout);
2042 // Add two remote candidates; a host candidate (with higher priority)
2043 // and TURN candidate.
2044 ep1_ch1()->AddRemoteCandidate(
2045 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2046 ep1_ch1()->AddRemoteCandidate(
2047 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2048 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2049 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07002050 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002051 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2052 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2053 // Also expect that the channel instantly indicates that it's writable since
2054 // it has a TURN-TURN pair.
2055 EXPECT_TRUE(ep1_ch1()->writable());
2056 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002057 // Also make sure we can immediately send packets.
2058 const char* data = "test";
2059 int len = static_cast<int>(strlen(data));
2060 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07002061}
2062
Taylor Brandstetteref184702016-06-23 17:35:47 -07002063// Test that a TURN/peer reflexive candidate pair is also presumed writable.
2064TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
2065 rtc::ScopedFakeClock fake_clock;
2066
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002067 // We need to add artificial network delay to verify that the connection
2068 // is presumed writable before it's actually writable. Without this delay
2069 // it would become writable instantly.
2070 virtual_socket_server()->set_delay_mean(50);
2071 virtual_socket_server()->UpdateDelayDistribution();
2072
Taylor Brandstetteref184702016-06-23 17:35:47 -07002073 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2074 kDefaultPortAllocatorFlags);
2075 // We want the remote TURN candidate to show up as prflx. To do this we need
2076 // to configure the server to accept packets from an address we haven't
2077 // explicitly installed permission for.
2078 test_turn_server()->set_enable_permission_checks(false);
2079 IceConfig config;
2080 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002081 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2082 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2083 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2084 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07002085 ep1_ch1()->SetIceConfig(config);
2086 ep2_ch1()->SetIceConfig(config);
2087 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2088 // candidate as peer reflexive.
2089 PauseCandidates(1);
2090 ep1_ch1()->MaybeStartGathering();
2091 ep2_ch1()->MaybeStartGathering();
2092
2093 // Wait for the TURN<->prflx connection.
2094 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002095 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002096 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2097 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2098 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2099 // Make sure that at this point the connection is only presumed writable,
2100 // not fully writable.
2101 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2102
2103 // Now wait for it to actually become writable.
Honghai Zhang161a5862016-10-20 11:47:02 -07002104 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2105 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002106
2107 // Explitly destroy channels, before fake clock is destroyed.
2108 DestroyChannels();
2109}
2110
deadbeef14f97f52016-06-22 17:14:15 -07002111// Test that a presumed-writable TURN<->TURN connection is preferred above an
2112// unreliable connection (one that has failed to be pinged for some time).
2113TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
2114 rtc::ScopedFakeClock fake_clock;
2115
2116 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2117 kDefaultPortAllocatorFlags);
2118 IceConfig config;
2119 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002120 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2121 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2122 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2123 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07002124 ep1_ch1()->SetIceConfig(config);
2125 ep2_ch1()->SetIceConfig(config);
2126 ep1_ch1()->MaybeStartGathering();
2127 ep2_ch1()->MaybeStartGathering();
2128 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07002129 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2130 ep1_ch1()->selected_connection()->writable() &&
2131 ep2_ch1()->receiving() &&
2132 ep2_ch1()->writable() &&
2133 ep2_ch1()->selected_connection()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002134 kShortTimeout, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002135 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07002136 // Destroy the second channel and wait for the current connection on the
2137 // first channel to become "unreliable", making it no longer writable.
2138 GetEndpoint(1)->cd1_.ch_.reset();
Honghai Zhang161a5862016-10-20 11:47:02 -07002139 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2140 fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002141 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002142 // Add a remote TURN candidate. The first channel should still have a TURN
2143 // port available to make a TURN<->TURN pair that's presumed writable.
2144 ep1_ch1()->AddRemoteCandidate(
2145 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2146 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2147 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2148 EXPECT_TRUE(ep1_ch1()->writable());
2149 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07002150 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002151 // Explitly destroy channels, before fake clock is destroyed.
2152 DestroyChannels();
2153}
2154
deadbeefdd7fb432016-09-30 15:16:48 -07002155// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2156// writable" connection. Previously this did not work.
2157TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
2158 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2159 kDefaultPortAllocatorFlags);
2160 // Only test one endpoint, so we can ensure the connection doesn't receive a
2161 // binding response and advance beyond being "presumed" writable.
2162 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2163 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2164 IceConfig config;
2165 config.presume_writable_when_fully_relayed = true;
2166 ep1_ch1()->SetIceConfig(config);
2167 ep1_ch1()->MaybeStartGathering();
2168 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2169 ep1_ch1()->gathering_state(), kDefaultTimeout);
2170 ep1_ch1()->AddRemoteCandidate(
2171 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2172 // Sanity checking the type of the connection.
2173 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
2174 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2175 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2176
2177 // Tell the socket server to block packets (returning EWOULDBLOCK).
2178 virtual_socket_server()->SetSendingBlocked(true);
2179 const char* data = "test";
2180 int len = static_cast<int>(strlen(data));
2181 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2182
2183 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2184 // should.
2185 GetEndpoint(0)->ready_to_send_ = false;
2186 virtual_socket_server()->SetSendingBlocked(false);
2187 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2188 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2189}
2190
Qingsi Wang2bd41f92018-03-23 14:28:37 -07002191// Test that role conflict error responses are sent as expected when receiving a
2192// ping from an unknown address over a TURN connection. Regression test for
2193// crbug.com/webrtc/9034.
2194TEST_F(P2PTransportChannelTest,
2195 TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict) {
2196 rtc::ScopedFakeClock clock;
2197 // Gather only relay candidates.
2198 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC,
2199 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2200 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP,
2201 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2202 PORTALLOCATOR_DISABLE_STUN |
2203 PORTALLOCATOR_DISABLE_TCP);
2204 // With conflicting ICE roles, endpoint 1 has the higher tie breaker and will
2205 // send a binding error response.
2206 SetIceRole(0, ICEROLE_CONTROLLING);
2207 SetIceTiebreaker(0, kHighTiebreaker);
2208 SetIceRole(1, ICEROLE_CONTROLLING);
2209 SetIceTiebreaker(1, kLowTiebreaker);
2210 // We want the remote TURN candidate to show up as prflx. To do this we need
2211 // to configure the server to accept packets from an address we haven't
2212 // explicitly installed permission for.
2213 test_turn_server()->set_enable_permission_checks(false);
2214 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2215 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2216 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2217 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
2218 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2219 // candidate as peer reflexive.
2220 PauseCandidates(1);
2221 ep1_ch1()->MaybeStartGathering();
2222 ep2_ch1()->MaybeStartGathering();
2223
2224 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
2225 kMediumTimeout, clock);
2226
2227 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2228
2229 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2230 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2231
2232 DestroyChannels();
2233}
2234
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002235// Test what happens when we have 2 users behind the same NAT. This can lead
2236// to interesting behavior because the STUN server will only give out the
2237// address of the outermost NAT.
2238class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2239 protected:
2240 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
kwibergee89e782017-08-09 17:22:01 -07002241 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2242 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002243 rtc::NATSocketServer::Translator* outer_nat =
2244 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
2245 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
2246 ConfigureEndpoint(outer_nat, 0, config1);
2247 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002248 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002249 }
2250 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
2251 int endpoint, Config config) {
nissec8ee8822017-01-18 07:20:55 -08002252 RTC_CHECK(config <= NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002253 if (config == OPEN) {
2254 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2255 nat->AddClient(kPrivateAddrs[endpoint]);
2256 } else {
2257 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2258 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
2259 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
2260 kCascadedPrivateAddrs[endpoint]);
2261 }
2262 }
2263};
2264
2265TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2266 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002267 Test(
2268 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002269}
2270
2271// Test what happens when we have multiple available pathways.
2272// In the future we will try different RTTs and configs for the different
2273// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2274class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002275 public:
honghaiz7252a002016-11-08 20:04:09 -08002276 const Connection* GetConnectionWithRemoteAddress(
2277 P2PTransportChannel* channel,
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002278 const SocketAddress& address) {
honghaiz7252a002016-11-08 20:04:09 -08002279 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002280 if (conn->remote_candidate().address().EqualIPs(address)) {
2281 return conn;
2282 }
2283 }
2284 return nullptr;
2285 }
2286
honghaiz7252a002016-11-08 20:04:09 -08002287 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2288 const SocketAddress& address) {
2289 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002290 if (conn->local_candidate().address().EqualIPs(address)) {
2291 return conn;
2292 }
2293 }
2294 return nullptr;
2295 }
2296
honghaiz7252a002016-11-08 20:04:09 -08002297 Connection* GetConnection(P2PTransportChannel* channel,
2298 const SocketAddress& local,
2299 const SocketAddress& remote) {
2300 for (Connection* conn : channel->connections()) {
2301 if (conn->local_candidate().address().EqualIPs(local) &&
2302 conn->remote_candidate().address().EqualIPs(remote)) {
2303 return conn;
2304 }
2305 }
2306 return nullptr;
2307 }
2308
2309 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2310 const Connection* selected_connection = channel->selected_connection();
2311 for (Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002312 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002313 conn->Destroy();
2314 }
2315 }
2316 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002317};
2318
2319// Test that we can establish connectivity when both peers are multihomed.
zhihuanga3095d02016-11-10 13:59:46 -08002320TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002321 AddAddress(0, kPublicAddrs[0]);
2322 AddAddress(0, kAlternateAddrs[0]);
2323 AddAddress(1, kPublicAddrs[1]);
2324 AddAddress(1, kAlternateAddrs[1]);
2325 Test(kLocalUdpToLocalUdp);
2326}
2327
Honghai Zhang52dce732016-03-31 12:37:31 -07002328// Test that we can quickly switch links if an interface goes down.
2329// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002330TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002331 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002332 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002333 // Simulate failing over from Wi-Fi to cell interface.
2334 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2335 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002336
2337 // Use only local ports for simplicity.
2338 SetAllocatorFlags(0, kOnlyLocalPorts);
2339 SetAllocatorFlags(1, kOnlyLocalPorts);
2340
deadbeefb60a8192016-08-24 15:15:00 -07002341 // Make the receiving timeout shorter for testing.
2342 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002343 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002344 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002345
honghaiz9ad0db52016-07-14 19:30:28 -07002346 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2347 ep2_ch1()->receiving() &&
2348 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002349 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002350 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2351 ep2_ch1()->selected_connection() &&
2352 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2353 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002354
2355 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002356 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002357 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002358 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002359 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2360 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002361 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002362 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002363 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002364 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002365
honghaiz9ad0db52016-07-14 19:30:28 -07002366 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002367 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002368 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2369 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002370 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002371 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2372 EXPECT_TRUE(
2373 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2374 EXPECT_TRUE(
2375 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2376
2377 DestroyChannels();
2378}
2379
Honghai Zhang52dce732016-03-31 12:37:31 -07002380// Test that we can quickly switch links if an interface goes down.
2381// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002382TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002383 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002384 // Simulate failing over from Wi-Fi to cell interface.
2385 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2386 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiza58ea782015-09-24 08:13:36 -07002387 AddAddress(1, kPublicAddrs[1]);
2388
2389 // Use only local ports for simplicity.
2390 SetAllocatorFlags(0, kOnlyLocalPorts);
2391 SetAllocatorFlags(1, kOnlyLocalPorts);
2392
deadbeefb60a8192016-08-24 15:15:00 -07002393 // Make the receiving timeout shorter for testing.
2394 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002395 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002396 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002397 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2398 ep2_ch1()->receiving() &&
2399 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002400 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002401 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2402 ep2_ch1()->selected_connection() &&
2403 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2404 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002405
2406 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002407 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002408 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002409 // The selected connections will switch, so keep references to them.
2410 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2411 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002412 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002413 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002414 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002415 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002416
honghaiz9ad0db52016-07-14 19:30:28 -07002417 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002418 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002419 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2420 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002421 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002422 EXPECT_TRUE(
2423 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
2424 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2425 EXPECT_TRUE(
2426 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002427
2428 DestroyChannels();
2429}
2430
honghaiz7252a002016-11-08 20:04:09 -08002431// Tests that we can quickly switch links if an interface goes down when
2432// there are many connections.
2433TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2434 rtc::ScopedFakeClock clock;
2435 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
2436 RelayServerConfig turn_server(RELAY_TURN);
2437 turn_server.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08002438 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
honghaiz7252a002016-11-08 20:04:09 -08002439 GetAllocator(0)->AddTurnServer(turn_server);
2440 GetAllocator(1)->AddTurnServer(turn_server);
2441 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08002442 SetAllocatorFlags(
2443 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2444 SetAllocatorFlags(
2445 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002446 SetAllocationStepDelay(0, kMinimumStepDelay);
2447 SetAllocationStepDelay(1, kMinimumStepDelay);
2448
2449 auto& wifi = kPublicAddrs;
2450 auto& cellular = kAlternateAddrs;
2451 auto& wifiIpv6 = kIPv6PublicAddrs;
2452 auto& cellularIpv6 = kIPv6AlternateAddrs;
2453 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2454 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2455 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2456 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2457 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2458 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2459 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2460 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2461
2462 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2463 // will be created in time.
2464 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2465 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2466 virtual_socket_server()->set_delay_mean(500);
2467 virtual_socket_server()->UpdateDelayDistribution();
2468
2469 // Make the receiving timeout shorter for testing.
2470 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2471 // Create channels and let them go writable, as usual.
2472 CreateChannels(config, config, true /* ice_renomination */);
2473 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2474 ep2_ch1()->receiving() &&
2475 ep2_ch1()->writable(),
2476 kMediumTimeout, clock);
2477 EXPECT_TRUE_SIMULATED_WAIT(
2478 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
2479 LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
2480 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
2481 kMediumTimeout, clock);
2482
2483 // Blackhole any traffic to or from the wifi on endpoint 1.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002484 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz7252a002016-11-08 20:04:09 -08002485 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2486 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2487
2488 // The selected connections may switch, so keep references to them.
2489 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2490 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2491 EXPECT_TRUE_SIMULATED_WAIT(
2492 !selected_connection1->receiving() && !selected_connection2->receiving(),
2493 kMediumTimeout, clock);
2494
2495 // Per-network best connections will be pinged at relatively higher rate when
2496 // the selected connection becomes not receiving.
2497 Connection* per_network_best_connection1 =
2498 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2499 ASSERT_NE(nullptr, per_network_best_connection1);
2500 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2501 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2502 EXPECT_TRUE_SIMULATED_WAIT(
2503 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2504 kMediumTimeout, clock);
2505 int64_t ping_interval1 =
2506 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2507 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2508 constexpr int SCHEDULING_DELAY = 200;
2509 EXPECT_LT(
2510 ping_interval1,
2511 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2512
2513 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2514 // it timed out on writing.
2515 EXPECT_TRUE_SIMULATED_WAIT(
2516 ep1_ch1()->selected_connection()->receiving() &&
2517 ep2_ch1()->selected_connection()->receiving() &&
2518 RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
2519 LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
2520 kMediumTimeout, clock);
2521
2522 DestroyChannels();
2523}
2524
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002525// Test that when the controlling side switches the selected connection,
2526// the nomination of the selected connection on the controlled side will
2527// increase.
2528TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2529 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002530 // Simulate failing over from Wi-Fi to cell interface.
2531 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2532 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002533 AddAddress(1, kPublicAddrs[1]);
2534
2535 // Use only local ports for simplicity.
2536 SetAllocatorFlags(0, kOnlyLocalPorts);
2537 SetAllocatorFlags(1, kOnlyLocalPorts);
2538
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002539 // We want it to set the remote ICE parameters when creating channels.
2540 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002541 // Make the receiving timeout shorter for testing.
2542 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002543 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002544 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002545 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2546 ep2_ch1()->receiving() &&
2547 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002548 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002549 EXPECT_TRUE_SIMULATED_WAIT(
2550 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2551 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2552 kDefaultTimeout, clock);
2553 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2554 Connection* selected_connection2 =
2555 const_cast<Connection*>(ep2_ch1()->selected_connection());
2556 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2557 // |selected_connection2| should not be nominated any more since the previous
2558 // nomination has been acknowledged.
2559 ConnectSignalNominated(selected_connection2);
Honghai Zhang161a5862016-10-20 11:47:02 -07002560 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002561 EXPECT_FALSE(nominated());
2562
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002563 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002564 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002565 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2566
2567 // The selected connection on the controlling side should switch.
2568 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002569 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2570 clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002571 // The connection on the controlled side should be nominated again
2572 // and have an increased nomination.
2573 EXPECT_TRUE_SIMULATED_WAIT(
2574 ep2_ch1()->selected_connection()->remote_nomination() >
2575 remote_nomination2,
2576 kDefaultTimeout, clock);
2577
2578 DestroyChannels();
2579}
2580
honghaiz9ad0db52016-07-14 19:30:28 -07002581// Test that if an interface fails temporarily and then recovers quickly,
2582// the selected connection will not switch.
2583// The case that it will switch over to the backup connection if the selected
2584// connection does not recover after enough time is covered in
2585// TestFailoverControlledSide and TestFailoverControllingSide.
2586TEST_F(P2PTransportChannelMultihomedTest,
2587 TestConnectionSwitchDampeningControlledSide) {
2588 rtc::ScopedFakeClock clock;
2589 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002590 // Simulate failing over from Wi-Fi to cell interface.
2591 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2592 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002593
2594 // Use only local ports for simplicity.
2595 SetAllocatorFlags(0, kOnlyLocalPorts);
2596 SetAllocatorFlags(1, kOnlyLocalPorts);
2597
2598 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002599 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002600
2601 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2602 ep2_ch1()->receiving() &&
2603 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002604 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002605 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2606 ep2_ch1()->selected_connection() &&
2607 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2608 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2609
2610 // Make the receiving timeout shorter for testing.
2611 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2612 ep1_ch1()->SetIceConfig(config);
2613 ep2_ch1()->SetIceConfig(config);
2614 reset_selected_candidate_pair_switches();
2615
2616 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002617 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002618 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2619
2620 // The selected connections may switch, so keep references to them.
2621 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2622 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2623 // We should detect loss of receiving within 1 second or so.
2624 EXPECT_TRUE_SIMULATED_WAIT(
2625 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002626 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002627 // After a short while, the link recovers itself.
2628 SIMULATED_WAIT(false, 10, clock);
2629 fw()->ClearRules();
2630
2631 // We should remain on the public address on both sides and no connection
2632 // switches should have happened.
2633 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2634 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002635 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002636 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2637 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2638 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2639
2640 DestroyChannels();
2641}
2642
2643// Test that if an interface fails temporarily and then recovers quickly,
2644// the selected connection will not switch.
2645TEST_F(P2PTransportChannelMultihomedTest,
2646 TestConnectionSwitchDampeningControllingSide) {
2647 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002648 // Simulate failing over from Wi-Fi to cell interface.
2649 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2650 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002651 AddAddress(1, kPublicAddrs[1]);
2652
2653 // Use only local ports for simplicity.
2654 SetAllocatorFlags(0, kOnlyLocalPorts);
2655 SetAllocatorFlags(1, kOnlyLocalPorts);
2656
2657 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002658 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002659 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2660 ep2_ch1()->receiving() &&
2661 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002662 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002663 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2664 ep2_ch1()->selected_connection() &&
2665 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2666 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2667
2668 // Make the receiving timeout shorter for testing.
2669 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2670 ep1_ch1()->SetIceConfig(config);
2671 ep2_ch1()->SetIceConfig(config);
2672 reset_selected_candidate_pair_switches();
2673
2674 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002675 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002676 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2677 // The selected connections may switch, so keep references to them.
2678 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2679 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2680 // We should detect loss of receiving within 1 second or so.
2681 EXPECT_TRUE_SIMULATED_WAIT(
2682 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002683 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002684 // The link recovers after a short while.
2685 SIMULATED_WAIT(false, 10, clock);
2686 fw()->ClearRules();
2687
2688 // We should not switch to the alternate addr on both sides because of the
2689 // dampening.
2690 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2691 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002692 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002693 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2694 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2695 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2696 DestroyChannels();
2697}
2698
Honghai Zhangfd16da22016-08-17 16:12:46 -07002699// Tests that if the remote side's network failed, it won't cause the local
2700// side to switch connections and networks.
2701TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2702 rtc::ScopedFakeClock clock;
2703 // The interface names are chosen so that |cellular| would have higher
2704 // candidate priority and higher cost.
2705 auto& wifi = kPublicAddrs;
2706 auto& cellular = kAlternateAddrs;
2707 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2708 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2709 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2710
2711 // Use only local ports for simplicity.
2712 SetAllocatorFlags(0, kOnlyLocalPorts);
2713 SetAllocatorFlags(1, kOnlyLocalPorts);
2714 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002715 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002716 // Make the receiving timeout shorter for testing.
2717 // Set the backup connection ping interval to 25s.
2718 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2719 // Ping the best connection more frequently since we don't have traffic.
2720 config.stable_writable_connection_ping_interval = 900;
2721 ep1_ch1()->SetIceConfig(config);
2722 ep2_ch1()->SetIceConfig(config);
2723 // Need to wait to make sure the connections on both networks are writable.
2724 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2725 ep2_ch1()->receiving() &&
2726 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002727 kMediumTimeout, clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002728 EXPECT_TRUE_SIMULATED_WAIT(
2729 ep1_ch1()->selected_connection() &&
2730 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2731 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2732 kDefaultTimeout, clock);
2733 Connection* backup_conn =
2734 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2735 ASSERT_NE(nullptr, backup_conn);
2736 // After a short while, the backup connection will be writable but not
2737 // receiving because backup connection is pinged at a slower rate.
2738 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002739 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
2740 clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002741 reset_selected_candidate_pair_switches();
2742 // Blackhole any traffic to or from the remote WiFi networks.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002743 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhangfd16da22016-08-17 16:12:46 -07002744 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2745
2746 int num_switches = 0;
2747 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2748 20000, clock);
2749 EXPECT_EQ(0, num_switches);
2750 DestroyChannels();
2751}
2752
honghaize1a0c942016-02-16 14:54:56 -08002753// Tests that a Wifi-Wifi connection has the highest precedence.
2754TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2755 // The interface names are chosen so that |cellular| would have higher
2756 // candidate priority if it is not for the network type.
2757 auto& wifi = kAlternateAddrs;
2758 auto& cellular = kPublicAddrs;
2759 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2760 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2761 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2762 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2763
2764 // Use only local ports for simplicity.
2765 SetAllocatorFlags(0, kOnlyLocalPorts);
2766 SetAllocatorFlags(1, kOnlyLocalPorts);
2767
2768 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002769 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002770
2771 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2772 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2773 1000, 1000);
2774 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002775 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002776 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2777 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2778 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002779 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002780 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2781 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2782 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002783 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002784}
2785
2786// Tests that a Wifi-Cellular connection has higher precedence than
2787// a Cellular-Cellular connection.
2788TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2789 // The interface names are chosen so that |cellular| would have higher
2790 // candidate priority if it is not for the network type.
2791 auto& wifi = kAlternateAddrs;
2792 auto& cellular = kPublicAddrs;
2793 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2794 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2795 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2796
2797 // Use only local ports for simplicity.
2798 SetAllocatorFlags(0, kOnlyLocalPorts);
2799 SetAllocatorFlags(1, kOnlyLocalPorts);
2800
2801 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002802 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002803
2804 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2805 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2806 1000, 1000);
2807 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002808 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002809 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2810 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002811 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002812 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2813 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002814 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002815}
2816
Honghai Zhang381b4212015-12-04 12:24:03 -08002817// Test that the backup connection is pinged at a rate no faster than
2818// what was configured.
2819TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2820 AddAddress(0, kPublicAddrs[0]);
2821 // Adding alternate address will make sure |kPublicAddrs| has the higher
2822 // priority than others. This is due to FakeNetwork::AddInterface method.
2823 AddAddress(1, kAlternateAddrs[1]);
2824 AddAddress(1, kPublicAddrs[1]);
2825
2826 // Use only local ports for simplicity.
2827 SetAllocatorFlags(0, kOnlyLocalPorts);
2828 SetAllocatorFlags(1, kOnlyLocalPorts);
2829
2830 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002831 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002832 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2833 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2834 1000, 1000);
2835 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002836 ep2_ch1()->SetIceConfig(
2837 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002838 // After the state becomes COMPLETED, the backup connection will be pinged
2839 // once every |backup_ping_interval| milliseconds.
zhihuangd06adf62017-01-12 15:58:31 -08002840 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
2841 1000);
deadbeef14f97f52016-06-22 17:14:15 -07002842 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002843 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002844 Connection* backup_conn = connections[1];
Honghai Zhang161a5862016-10-20 11:47:02 -07002845 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
honghaiz34b11eb2016-03-16 08:55:44 -07002846 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002847 EXPECT_TRUE_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002848 last_ping_response_ms < backup_conn->last_ping_response_received(),
2849 kDefaultTimeout);
Honghai Zhang381b4212015-12-04 12:24:03 -08002850 int time_elapsed =
2851 backup_conn->last_ping_response_received() - last_ping_response_ms;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002852 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
Honghai Zhang381b4212015-12-04 12:24:03 -08002853 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002854
2855 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002856}
2857
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002858TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002859 rtc::ScopedFakeClock clock;
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002860 AddAddress(0, kAlternateAddrs[0]);
2861 AddAddress(0, kPublicAddrs[0]);
2862 AddAddress(1, kPublicAddrs[1]);
2863 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002864 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002865
2866 // Both transport channels will reach STATE_COMPLETED quickly.
zhihuangd06adf62017-01-12 15:58:31 -08002867 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002868 ep1_ch1()->GetState(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08002869 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002870 ep2_ch1()->GetState(), kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002871}
2872
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002873// Tests that when a network interface becomes inactive, if Continual Gathering
2874// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002875// will be removed from the port list of the channel, and the respective
2876// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002877TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002878 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002879 AddAddress(0, kPublicAddrs[0]);
2880 AddAddress(1, kPublicAddrs[1]);
2881 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07002882 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
2883 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07002884 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08002885
2886 SetAllocatorFlags(0, kOnlyLocalPorts);
2887 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002888 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2889 ep2_ch1()->receiving() &&
2890 ep2_ch1()->writable(),
2891 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002892 // More than one port has been created.
2893 EXPECT_LE(1U, ep1_ch1()->ports().size());
2894 // Endpoint 1 enabled continual gathering; the port will be removed
2895 // when the interface is removed.
2896 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002897 EXPECT_TRUE(ep1_ch1()->ports().empty());
2898 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002899 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2900 clock);
honghaize3c6c822016-02-17 13:00:28 -08002901
2902 size_t num_ports = ep2_ch1()->ports().size();
2903 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002904 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002905 // Endpoint 2 did not enable continual gathering; the local port will still be
2906 // removed when the interface is removed but the remote candidates on the
2907 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002908 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002909
2910 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2911 clock);
2912 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002913 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002914
2915 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002916}
2917
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002918// Tests that continual gathering will create new connections when a new
2919// interface is added.
2920TEST_F(P2PTransportChannelMultihomedTest,
2921 TestContinualGatheringOnNewInterface) {
2922 auto& wifi = kAlternateAddrs;
2923 auto& cellular = kPublicAddrs;
2924 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2925 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002926 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002927 IceConfig continual_gathering_config =
2928 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07002929 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002930 SetAllocatorFlags(0, kOnlyLocalPorts);
2931 SetAllocatorFlags(1, kOnlyLocalPorts);
2932 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2933 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2934 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002935
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002936 // Add a new wifi interface on end point 2. We should expect a new connection
2937 // to be created and the new one will be the best connection.
2938 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002939 const Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002940 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002941 conn->remote_candidate().address().EqualIPs(wifi[1]),
2942 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002943 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002944 conn->local_candidate().address().EqualIPs(wifi[1]),
2945 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002946
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002947 // Add a new cellular interface on end point 1, we should expect a new
2948 // backup connection created using this new interface.
2949 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002950 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002951 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002952 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2953 nullptr &&
2954 conn != ep1_ch1()->selected_connection() && conn->writable(),
2955 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002956 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002957 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002958 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
2959 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002960 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002961 kDefaultTimeout);
2962
2963 DestroyChannels();
2964}
2965
2966// Tests that we can switch links via continual gathering.
2967TEST_F(P2PTransportChannelMultihomedTest,
2968 TestSwitchLinksViaContinualGathering) {
2969 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002970 AddAddress(0, kPublicAddrs[0]);
2971 AddAddress(1, kPublicAddrs[1]);
2972 // Use only local ports for simplicity.
2973 SetAllocatorFlags(0, kOnlyLocalPorts);
2974 SetAllocatorFlags(1, kOnlyLocalPorts);
2975
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002976 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002977 IceConfig continual_gathering_config =
2978 CreateIceConfig(1000, GATHER_CONTINUALLY);
2979 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002980 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002981 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2982 ep2_ch1()->receiving() &&
2983 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002984 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002985 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07002986 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002987 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2988 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2989
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002990 // Add the new address first and then remove the other one.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002991 RTC_LOG(LS_INFO) << "Draining...";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002992 AddAddress(1, kAlternateAddrs[1]);
2993 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002994 // We should switch to use the alternate address after an exchange of pings.
2995 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002996 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002997 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2998 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002999 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003000
3001 // Remove one address first and then add another address.
Mirko Bonadei675513b2017-11-09 11:09:25 +01003002 RTC_LOG(LS_INFO) << "Draining again...";
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003003 RemoveAddress(1, kAlternateAddrs[1]);
3004 AddAddress(1, kAlternateAddrs[0]);
3005 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003006 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003007 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3008 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
Honghai Zhang161a5862016-10-20 11:47:02 -07003009 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003010
3011 DestroyChannels();
3012}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003013
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003014// Tests that the backup connection will be restored after it is destroyed.
3015TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3016 rtc::ScopedFakeClock clock;
3017 auto& wifi = kAlternateAddrs;
3018 auto& cellular = kPublicAddrs;
3019 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3020 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3021 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3022 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3023 // Use only local ports for simplicity.
3024 SetAllocatorFlags(0, kOnlyLocalPorts);
3025 SetAllocatorFlags(1, kOnlyLocalPorts);
3026
3027 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003028 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01003029 config.regather_on_failed_networks_interval = 2000;
johan02bd5122016-09-20 00:23:27 -07003030 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003031 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3032 ep2_ch1()->receiving() &&
3033 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003034 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003035 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3036 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003037 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
3038 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
3039
3040 // Destroy all backup connections.
3041 DestroyAllButBestConnection(ep1_ch1());
3042 // Ensure the backup connection is removed first.
3043 EXPECT_TRUE_SIMULATED_WAIT(
3044 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3045 kDefaultTimeout, clock);
honghaiz7252a002016-11-08 20:04:09 -08003046 const Connection* conn;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003047 EXPECT_TRUE_SIMULATED_WAIT(
3048 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3049 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003050 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003051 kDefaultTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003052
3053 DestroyChannels();
3054}
3055
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003056// A collection of tests which tests a single P2PTransportChannel by sending
3057// pings.
3058class P2PTransportChannelPingTest : public testing::Test,
3059 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003060 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003061 P2PTransportChannelPingTest()
deadbeef98e186c2017-05-16 18:00:06 -07003062 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003063
3064 protected:
deadbeef14f97f52016-06-22 17:14:15 -07003065 void PrepareChannel(P2PTransportChannel* ch) {
3066 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003067 ch->SetIceParameters(kIceParams[0]);
3068 ch->SetRemoteIceParameters(kIceParams[1]);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003069 ch->SignalNetworkRouteChanged.connect(
3070 this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07003071 ch->SignalReadyToSend.connect(this,
3072 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07003073 ch->SignalStateChanged.connect(
3074 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003075 }
3076
deadbeef14f97f52016-06-22 17:14:15 -07003077 Connection* WaitForConnectionTo(P2PTransportChannel* ch,
3078 const std::string& ip,
Honghai Zhange05bcc22016-08-16 18:19:14 -07003079 int port_num,
3080 rtc::FakeClock* clock = nullptr) {
3081 if (clock == nullptr) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003082 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3083 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003084 } else {
3085 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003086 kMediumTimeout, *clock);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003087 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003088 return GetConnectionTo(ch, ip, port_num);
3089 }
3090
sprang716978d2016-10-11 06:43:28 -07003091 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003092 if (ch->ports().empty()) {
3093 return nullptr;
3094 }
deadbeef14f97f52016-06-22 17:14:15 -07003095 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003096 }
3097
Honghai Zhanga74363c2016-07-28 18:06:15 -07003098 Port* GetPrunedPort(P2PTransportChannel* ch) {
3099 if (ch->pruned_ports().empty()) {
3100 return nullptr;
3101 }
3102 return static_cast<Port*>(ch->pruned_ports()[0]);
3103 }
3104
deadbeef14f97f52016-06-22 17:14:15 -07003105 Connection* GetConnectionTo(P2PTransportChannel* ch,
3106 const std::string& ip,
3107 int port_num) {
sprang716978d2016-10-11 06:43:28 -07003108 Port* port = GetPort(ch);
3109 if (!port) {
3110 return nullptr;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003111 }
sprang716978d2016-10-11 06:43:28 -07003112 return port->GetConnection(rtc::SocketAddress(ip, port_num));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003113 }
3114
deadbeef14f97f52016-06-22 17:14:15 -07003115 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3116 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08003117 if (conn) {
3118 ch->MarkConnectionPinged(conn);
3119 }
3120 return conn;
3121 }
3122
Steve Antone9324572017-11-29 10:18:21 -08003123 int SendData(IceTransportInternal* channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07003124 const char* data,
3125 size_t len,
3126 int packet_id) {
3127 rtc::PacketOptions options;
3128 options.packet_id = packet_id;
Steve Antone9324572017-11-29 10:18:21 -08003129 return channel->SendPacket(data, len, options, 0);
Honghai Zhang52dce732016-03-31 12:37:31 -07003130 }
3131
Steve Antone9324572017-11-29 10:18:21 -08003132 Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
3133 rtc::ScopedFakeClock* clock,
Honghai Zhang572b0942016-06-23 12:26:57 -07003134 const std::string& ip_addr,
3135 int port,
3136 int priority,
3137 bool writable) {
Steve Antone9324572017-11-29 10:18:21 -08003138 channel->AddRemoteCandidate(
Honghai Zhang572b0942016-06-23 12:26:57 -07003139 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3140 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antone9324572017-11-29 10:18:21 -08003141 GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
3142 *clock);
3143 Connection* conn = GetConnectionTo(channel, ip_addr, port);
Honghai Zhang572b0942016-06-23 12:26:57 -07003144
3145 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003146 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07003147 }
3148 return conn;
3149 }
3150
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003151 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3152 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07003153 conn->SignalNominated(conn);
3154 }
3155
Danil Chapovalov00c71832018-06-15 15:58:38 +02003156 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -08003157 last_network_route_ = network_route;
3158 if (last_network_route_) {
3159 last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
3160 }
Honghai Zhang572b0942016-06-23 12:26:57 -07003161 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07003162 }
3163
deadbeef14f97f52016-06-22 17:14:15 -07003164 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07003165 const std::string& remote_ufrag,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003166 int priority,
3167 uint32_t nomination = 0) {
deadbeef14f97f52016-06-22 17:14:15 -07003168 IceMessage msg;
3169 msg.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003170 msg.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
deadbeef14f97f52016-06-22 17:14:15 -07003171 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07003172 conn->local_candidate().username() + ":" + remote_ufrag));
zsteinf42cc9d2017-03-27 16:17:19 -07003173 msg.AddAttribute(
3174 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003175 if (nomination != 0) {
zsteinf42cc9d2017-03-27 16:17:19 -07003176 msg.AddAttribute(rtc::MakeUnique<StunUInt32Attribute>(
3177 STUN_ATTR_NOMINATION, nomination));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003178 }
deadbeef14f97f52016-06-22 17:14:15 -07003179 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07003180 msg.AddMessageIntegrity(conn->local_candidate().password());
3181 msg.AddFingerprint();
3182 rtc::ByteBufferWriter buf;
3183 msg.Write(&buf);
3184 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
3185 }
3186
deadbeef5bd5ca32017-02-10 11:31:50 -08003187 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07003188 channel_ready_to_send_ = true;
3189 }
zhihuangd06adf62017-01-12 15:58:31 -08003190 void OnChannelStateChanged(IceTransportInternal* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07003191 channel_state_ = channel->GetState();
3192 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003193
Honghai Zhang52dce732016-03-31 12:37:31 -07003194 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003195 bool channel_ready_to_send() { return channel_ready_to_send_; }
3196 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
zhihuangd06adf62017-01-12 15:58:31 -08003197 IceTransportState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07003198 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07003199 int switches = selected_candidate_pair_switches_;
3200 selected_candidate_pair_switches_ = 0;
3201 return switches;
3202 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003203
Zhi Huang942bc2e2017-11-13 13:26:07 -08003204 // Return true if the |pair| matches the last network route.
3205 bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
3206 if (!pair) {
3207 return !last_network_route_.has_value();
3208 } else {
3209 return pair->local_candidate().network_id() ==
3210 last_network_route_->local_network_id &&
3211 pair->remote_candidate().network_id() ==
3212 last_network_route_->remote_network_id;
3213 }
3214 }
3215
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003216 private:
kwiberg3ec46792016-04-27 07:22:53 -07003217 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -07003218 rtc::AutoSocketServerThread thread_;
Honghai Zhang572b0942016-06-23 12:26:57 -07003219 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07003220 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07003221 bool channel_ready_to_send_ = false;
zhihuangd06adf62017-01-12 15:58:31 -08003222 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
Danil Chapovalov00c71832018-06-15 15:58:38 +02003223 absl::optional<rtc::NetworkRoute> last_network_route_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003224};
3225
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003226TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07003227 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3228 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003229 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003230 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003231 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3232 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003233
deadbeef14f97f52016-06-22 17:14:15 -07003234 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3235 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003236 ASSERT_TRUE(conn1 != nullptr);
3237 ASSERT_TRUE(conn2 != nullptr);
3238
3239 // Before a triggered check, the first connection to ping is the
3240 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08003241 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003242
3243 // Receiving a ping causes a triggered check which should make conn1
3244 // be pinged first instead of conn2, even though conn2 has a higher
3245 // priority.
3246 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08003247 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003248}
3249
honghaiz524ecc22016-05-25 12:48:31 -07003250TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07003251 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3252 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07003253 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07003254 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003255 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3256 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07003257
deadbeef14f97f52016-06-22 17:14:15 -07003258 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3259 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07003260 ASSERT_TRUE(conn1 != nullptr);
3261 ASSERT_TRUE(conn2 != nullptr);
3262
3263 // Low-priority connection becomes writable so that the other connection
3264 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003265 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07003266 EXPECT_TRUE_WAIT(
3267 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3268 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3269 kDefaultTimeout);
3270}
3271
zhihuang435264a2016-06-21 11:28:38 -07003272// Verify that the connections are pinged at the right time.
3273TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
3274 rtc::ScopedFakeClock clock;
3275 int RTT_RATIO = 4;
3276 int SCHEDULING_RANGE = 200;
3277 int RTT_RANGE = 10;
3278
deadbeef14f97f52016-06-22 17:14:15 -07003279 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3280 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07003281 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07003282 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003283 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3284 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003285
3286 ASSERT_TRUE(conn != nullptr);
3287 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3288
3289 // Initializing.
3290
3291 int64_t start = clock.TimeNanos();
3292 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3293 kDefaultTimeout, clock);
3294 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3295 rtc::kNumNanosecsPerMillisec /
3296 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003297 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003298
3299 // Stabilizing.
3300
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003301 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003302 int ping_sent_before = conn->num_pings_sent();
3303 start = clock.TimeNanos();
3304 // The connection becomes strong but not stable because we haven't been able
3305 // to converge the RTT.
Honghai Zhang161a5862016-10-20 11:47:02 -07003306 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3307 clock);
zhihuang435264a2016-06-21 11:28:38 -07003308 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003309 EXPECT_GE(ping_interval_ms,
3310 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3311 EXPECT_LE(
3312 ping_interval_ms,
3313 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003314
3315 // Stabilized.
3316
3317 // The connection becomes stable after receiving more than RTT_RATIO rtt
3318 // samples.
3319 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003320 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003321 }
3322 ping_sent_before = conn->num_pings_sent();
3323 start = clock.TimeNanos();
Honghai Zhang161a5862016-10-20 11:47:02 -07003324 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3325 clock);
zhihuang435264a2016-06-21 11:28:38 -07003326 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003327 EXPECT_GE(ping_interval_ms,
3328 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3329 EXPECT_LE(
3330 ping_interval_ms,
3331 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003332
3333 // Destabilized.
3334
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003335 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003336 // Create a in-flight ping.
3337 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3338 start = clock.TimeNanos();
3339 // In-flight ping timeout and the connection will be unstable.
3340 SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003341 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3342 kMediumTimeout, clock);
zhihuang435264a2016-06-21 11:28:38 -07003343 int64_t duration_ms =
3344 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3345 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3346 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3347 // The connection become unstable due to not receiving ping responses.
3348 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003349 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3350 clock);
zhihuang435264a2016-06-21 11:28:38 -07003351 // The interval is expected to be
honghaiz7252a002016-11-08 20:04:09 -08003352 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
zhihuang435264a2016-06-21 11:28:38 -07003353 start = clock.TimeNanos();
3354 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003355 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3356 clock);
zhihuang435264a2016-06-21 11:28:38 -07003357 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003358 EXPECT_GE(ping_interval_ms,
3359 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3360 EXPECT_LE(
3361 ping_interval_ms,
3362 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003363}
3364
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003365// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003366// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003367TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3368 rtc::ScopedFakeClock clock;
3369
3370 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3371 P2PTransportChannel ch("TestChannel", 1, &pa);
3372 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003373 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003374 ch.MaybeStartGathering();
3375 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3376 kDefaultTimeout);
3377
3378 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003379 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003380 IceMessage request;
3381 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003382 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3383 STUN_ATTR_USERNAME, kIceUfrag[1]));
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003384 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3385 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003386 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003387 Port* port = GetPort(&ch);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003388 ASSERT_NE(nullptr, port);
3389 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3390 &request, kIceUfrag[1], false);
3391 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3392 ASSERT_NE(nullptr, conn);
3393
3394 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003395 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003396 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3397 EXPECT_EQ(0, conn->num_pings_sent());
3398
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003399 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003400 // the first ping is sent as soon as possible, within one simulated clock
3401 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003402 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003403 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3404}
3405
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003406TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003407 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3408 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003409 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003410 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003411 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3412 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003413
deadbeef14f97f52016-06-22 17:14:15 -07003414 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3415 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003416 ASSERT_TRUE(conn1 != nullptr);
3417 ASSERT_TRUE(conn2 != nullptr);
3418
guoweis36f01372016-03-02 18:02:40 -08003419 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3420 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003421 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003422 ASSERT_TRUE(conn1->writable());
3423 conn1->ReceivedPing();
3424
3425 // Ping received, but the connection is already writable, so no
3426 // "triggered check" and conn2 is pinged before conn1 because it has
3427 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003428 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003429}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003430
honghaiz079a7a12016-06-22 16:26:29 -07003431TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003432 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3433 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003434 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003435 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003436 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003437
deadbeef14f97f52016-06-22 17:14:15 -07003438 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003439 ASSERT_TRUE(conn1 != nullptr);
3440
3441 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3442 conn1->Prune(); // A pruned connection may still be pingable.
3443 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3444 conn1->FailAndPrune();
3445 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3446}
3447
Honghai Zhang1590c392016-05-24 13:15:02 -07003448TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003449 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3450 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003451 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003452 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003453 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3454 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003455 ASSERT_TRUE(conn1 != nullptr);
3456 // Pruning the connection reduces the set of active connections and changes
3457 // the channel state.
3458 conn1->Prune();
zhihuangd06adf62017-01-12 15:58:31 -08003459 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3460 kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003461}
3462
honghaiza54a0802015-12-16 18:37:23 -08003463// Test adding remote candidates with different ufrags. If a remote candidate
3464// is added with an old ufrag, it will be discarded. If it is added with a
3465// ufrag that was not seen before, it will be used to create connections
3466// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003467// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003468// ufrag, its pwd and generation will be set properly.
3469TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003470 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3471 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003472 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003473 ch.MaybeStartGathering();
3474 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003475 ch.AddRemoteCandidate(
3476 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3477 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003478 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003479 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003480 EXPECT_EQ(kIceUfrag[2], candidate.username());
3481 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003482 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003483
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003484 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003485 // This should set the ICE pwd in the remote candidate of |conn1|, making
3486 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003487 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003488 EXPECT_EQ(kIceUfrag[2], candidate.username());
3489 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003490 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003491
3492 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003493 ch.AddRemoteCandidate(
3494 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003495 rtc::Thread::Current()->ProcessMessages(500);
3496 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3497
3498 // Add a candidate with the current ufrag, its pwd and generation will be
3499 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003500 ch.AddRemoteCandidate(
3501 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3502 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003503 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003504 kMediumTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07003505 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003506 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3507 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003508
3509 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003510 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003511 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3512 candidate.username() == kIceUfrag[2]);
3513 if (candidate.username() == kIceUfrag[1]) {
3514 EXPECT_EQ(kIcePwd[1], candidate.password());
3515 } else if (candidate.username() == kIceUfrag[2]) {
3516 EXPECT_EQ(kIcePwd[2], candidate.password());
3517 }
3518 }
honghaiza54a0802015-12-16 18:37:23 -08003519}
3520
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003521TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003522 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3523 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003524 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003525 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003526
3527 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003528 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3529 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003530 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003531 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003532
3533 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003534 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003535 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3536 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003537 ASSERT_TRUE(conn2 != nullptr);
3538 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003539 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003540
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003541 // Wait for conn1 to be pruned.
Honghai Zhang161a5862016-10-20 11:47:02 -07003542 EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003543 // Destroy the connection to test SignalUnknownAddress.
3544 conn1->Destroy();
honghaize58d73d2016-10-24 16:38:26 -07003545 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
3546 kMediumTimeout);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003547
3548 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003549 IceMessage request;
3550 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003551 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3552 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003553 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3554 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003555 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003556 EXPECT_NE(prflx_priority, remote_priority);
3557
sprang716978d2016-10-11 06:43:28 -07003558 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003559 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003560 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3561 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003562 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3563 ASSERT_TRUE(conn1 != nullptr);
3564 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3565
3566 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003567 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3568 &request, kIceUfrag[1], false);
3569 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003570 ASSERT_TRUE(conn3 != nullptr);
3571 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3572}
Peter Thatcher54360512015-07-08 11:08:35 -07003573
3574TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
honghaize58d73d2016-10-24 16:38:26 -07003575 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003576 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3577 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003578 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003579 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003580 // small.
Qingsi Wang866e08d2018-03-22 17:54:23 -07003581 EXPECT_LE(1000, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003582 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003583 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Qingsi Wang866e08d2018-03-22 17:54:23 -07003584 EXPECT_EQ(500, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003585 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003586 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003587 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaize58d73d2016-10-24 16:38:26 -07003588 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003589 ASSERT_TRUE(conn1 != nullptr);
3590
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003591 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Peter Thatcher54360512015-07-08 11:08:35 -07003592 conn1->ReceivedPing();
3593 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
honghaize58d73d2016-10-24 16:38:26 -07003594 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
3595 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003596}
honghaiz5a3acd82015-08-20 15:53:17 -07003597
Honghai Zhang572b0942016-06-23 12:26:57 -07003598// The controlled side will select a connection as the "selected connection"
3599// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003600// point the controlled side will select that connection as the
Zhi Huang942bc2e2017-11-13 13:26:07 -08003601// "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
Honghai Zhang572b0942016-06-23 12:26:57 -07003602// selected connection changes and SignalReadyToSend will be fired if the new
3603// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003604TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003605 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3606 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003607 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003608 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003609 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003610 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3611 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003612 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003613 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003614 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003615 int last_packet_id = 0;
3616 const char* data = "ABCDEFGH";
3617 int len = static_cast<int>(strlen(data));
Steve Antone9324572017-11-29 10:18:21 -08003618 EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003619 EXPECT_EQ(-1, last_sent_packet_id());
3620
3621 // A connection needs to be writable before it is selected for transmission.
3622 conn1->ReceivedPingResponse(LOW_RTT, "id");
3623 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003624 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Steve Antone9324572017-11-29 10:18:21 -08003625 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003626
honghaiz5a3acd82015-08-20 15:53:17 -07003627 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003628 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003629 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3630 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003631 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003632 conn2->ReceivedPingResponse(LOW_RTT, "id");
3633 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003634 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003635 EXPECT_TRUE(channel_ready_to_send());
3636 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003637
3638 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003639 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003640 // its priority is lower.
Steve Antone9324572017-11-29 10:18:21 -08003641 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003642 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3643 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003644 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003645 // Because it has a lower priority, the selected connection is still conn2.
3646 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003647 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003648 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003649 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003650 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003651 EXPECT_EQ(conn3, ch.selected_connection());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003652 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003653 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003654 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003655
Honghai Zhang572b0942016-06-23 12:26:57 -07003656 // Even if another higher priority candidate arrives, it will not be set as
3657 // the selected connection because the selected connection is nominated by
3658 // the controlling side.
Steve Antone9324572017-11-29 10:18:21 -08003659 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003660 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3661 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003662 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003663 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003664 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003665 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003666 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003667 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003668 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003669 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003670 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003671 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003672 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003673 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
Honghai Zhang52dce732016-03-31 12:37:31 -07003674 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003675 // SignalReadyToSend is fired again because conn4 is writable.
3676 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003677}
3678
Honghai Zhang572b0942016-06-23 12:26:57 -07003679// The controlled side will select a connection as the "selected connection"
3680// based on requests from an unknown address before the controlling side
3681// nominates a connection, and will nominate a connection from an unknown
3682// address if the request contains the use_candidate attribute. Plus, it will
3683// also sends back a ping response and set the ICE pwd in the remote candidate
3684// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003685TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003686 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3687 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003688 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003689 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003690 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003691 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003692 IceMessage request;
3693 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003694 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3695 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003696 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3697 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003698 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003699 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
deadbeef14f97f52016-06-22 17:14:15 -07003700 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3701 &request, kIceUfrag[1], false);
3702 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003703 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003704 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003705 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003706 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003707 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003708 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003709
3710 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003711 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3712 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003713 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003714 // Because it has a lower priority, the selected connection is still conn1.
3715 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003716 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003717 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003718 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3719 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003720 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003721
Honghai Zhang572b0942016-06-23 12:26:57 -07003722 // Another request with unknown address, it will not be set as the selected
3723 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003724 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003725 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3726 &request, kIceUfrag[1], false);
3727 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003728 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003729 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003730 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003731 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003732 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003733
3734 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003735 // selected as the selected connection.
zsteinf42cc9d2017-03-27 16:17:19 -07003736 request.AddAttribute(
3737 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
deadbeef14f97f52016-06-22 17:14:15 -07003738 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3739 &request, kIceUfrag[1], false);
3740 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003741 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003742 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003743 // conn4 is not the selected connection yet because it is not writable.
3744 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003745 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003746 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003747
3748 // Test that the request from an unknown address contains a ufrag from an old
3749 // generation.
3750 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003751 ch.SetRemoteIceParameters(kIceParams[2]);
3752 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003753 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3754 &request, kIceUfrag[2], false);
3755 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003756 ASSERT_TRUE(conn5 != nullptr);
3757 EXPECT_TRUE(port->sent_binding_response());
3758 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003759}
3760
Honghai Zhang572b0942016-06-23 12:26:57 -07003761// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003762// based on media received until the controlling side nominates a connection,
3763// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003764// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003765TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003766 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3767 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003768 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003769 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003770 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003771 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3772 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003773 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003774 conn1->ReceivedPingResponse(LOW_RTT, "id");
3775 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003776
Honghai Zhang572b0942016-06-23 12:26:57 -07003777 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003778 // switch to conn2 because the controlled side must mirror the media path
3779 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003780 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3781 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003782 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003783 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003784 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003785 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003786 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003787
3788 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003789 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003790 IceMessage request;
3791 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003792 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3793 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003794 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3795 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003796 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
3797 request.AddAttribute(
3798 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
sprang716978d2016-10-11 06:43:28 -07003799 Port* port = GetPort(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003800 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3801 &request, kIceUfrag[1], false);
3802 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003803 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003804 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003805 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003806 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003807
Honghai Zhang572b0942016-06-23 12:26:57 -07003808 // Now another data packet will not switch the selected connection because the
3809 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003810 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003811 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz5a3acd82015-08-20 15:53:17 -07003812 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003813 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3814}
3815
3816TEST_F(P2PTransportChannelPingTest,
3817 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3818 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003819 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003820 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3821 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3822 PrepareChannel(&ch);
3823 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003824 ch.MaybeStartGathering();
3825 // The connections have decreasing priority.
3826 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003827 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003828 ASSERT_TRUE(conn1 != nullptr);
3829 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003830 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003831 ASSERT_TRUE(conn2 != nullptr);
3832
3833 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003834 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003835 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003836
3837 // conn2 receives data; it becomes selected.
3838 // Advance the clock by 1ms so that the last data receiving timestamp of
3839 // conn2 is larger.
3840 SIMULATED_WAIT(false, 1, clock);
3841 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003842 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003843 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003844
3845 // conn1 also receives data; it becomes selected due to priority again.
3846 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003847 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003848 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003849
Honghai Zhange05bcc22016-08-16 18:19:14 -07003850 // conn2 received data more recently; it is selected now because it
3851 // received data more recently.
3852 SIMULATED_WAIT(false, 1, clock);
3853 // Need to become writable again because it was pruned.
3854 conn2->ReceivedPingResponse(LOW_RTT, "id");
3855 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3856 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003857 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003858
Honghai Zhang572b0942016-06-23 12:26:57 -07003859 // Make sure sorting won't reselect candidate pair.
3860 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003861 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003862}
3863
3864TEST_F(P2PTransportChannelPingTest,
3865 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3866 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003867 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003868
3869 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3870 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3871 PrepareChannel(&ch);
3872 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003873 ch.MaybeStartGathering();
3874 // The connections have decreasing priority.
3875 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003876 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003877 ASSERT_TRUE(conn1 != nullptr);
3878 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003879 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003880 ASSERT_TRUE(conn2 != nullptr);
3881
3882 // conn1 received data; it is the selected connection.
3883 // Advance the clock to have a non-zero last-data-receiving time.
3884 SIMULATED_WAIT(false, 1, clock);
3885 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003886 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003887 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003888
3889 // conn2 is nominated; it becomes the selected connection.
3890 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003891 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003892 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003893
Honghai Zhange05bcc22016-08-16 18:19:14 -07003894 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07003895 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003896 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003897 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003898
Honghai Zhang572b0942016-06-23 12:26:57 -07003899 // Make sure sorting won't reselect candidate pair.
3900 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003901 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003902}
3903
3904TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003905 TestControlledAgentSelectsConnectionWithHigherNomination) {
3906 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003907 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003908
3909 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3910 P2PTransportChannel ch("test", 1, &pa);
3911 PrepareChannel(&ch);
3912 ch.SetIceRole(ICEROLE_CONTROLLED);
3913 ch.MaybeStartGathering();
3914 // The connections have decreasing priority.
3915 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003916 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003917 ASSERT_TRUE(conn1 != nullptr);
3918 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003919 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003920 ASSERT_TRUE(conn2 != nullptr);
3921
3922 // conn1 is the selected connection because it has a higher priority,
Zhi Huang942bc2e2017-11-13 13:26:07 -08003923 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
3924 clock);
3925 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003926 reset_selected_candidate_pair_switches();
3927
3928 // conn2 is nominated; it becomes selected.
3929 NominateConnection(conn2);
3930 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003931 EXPECT_EQ(conn2, ch.selected_connection());
3932 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003933
3934 // conn1 is selected because of its priority.
3935 NominateConnection(conn1);
3936 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003937 EXPECT_EQ(conn1, ch.selected_connection());
3938 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003939
3940 // conn2 gets higher remote nomination; it is selected again.
3941 NominateConnection(conn2, 2U);
3942 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003943 EXPECT_EQ(conn2, ch.selected_connection());
3944 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003945
3946 // Make sure sorting won't reselect candidate pair.
3947 SIMULATED_WAIT(false, 100, clock);
3948 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3949}
3950
3951TEST_F(P2PTransportChannelPingTest,
3952 TestControlledAgentIgnoresSmallerNomination) {
3953 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003954 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07003955
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003956 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3957 P2PTransportChannel ch("test", 1, &pa);
3958 PrepareChannel(&ch);
3959 ch.SetIceRole(ICEROLE_CONTROLLED);
3960 ch.MaybeStartGathering();
3961 Connection* conn =
Steve Antone9324572017-11-29 10:18:21 -08003962 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003963 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
3964 EXPECT_EQ(2U, conn->remote_nomination());
3965 // Smaller nomination is ignored.
3966 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
3967 EXPECT_EQ(2U, conn->remote_nomination());
3968}
3969
3970TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07003971 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3972 rtc::ScopedFakeClock clock;
3973
3974 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3975 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3976 PrepareChannel(&ch);
3977 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003978 ch.MaybeStartGathering();
3979 // The connections have decreasing priority.
3980 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003981 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07003982 ASSERT_TRUE(conn1 != nullptr);
3983 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003984 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07003985 ASSERT_TRUE(conn2 != nullptr);
3986
3987 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003988 // There is no selected connection because no connection is writable.
3989 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003990
3991 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003992 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003993 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003994 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003995 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
3996 clock);
3997 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003998
3999 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004000 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07004001 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07004002 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08004003 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4004 clock);
4005 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004006
4007 // Make sure sorting won't reselect candidate pair.
4008 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07004009 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07004010}
honghaiz89374372015-09-24 13:14:47 -07004011
honghaiz36f50e82016-06-01 15:57:03 -07004012// Test that if a new remote candidate has the same address and port with
4013// an old one, it will be used to create a new connection.
4014TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07004015 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4016 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07004017 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07004018 ch.MaybeStartGathering();
4019 const std::string host_address = "1.1.1.1";
4020 const int port_num = 1;
4021
4022 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07004023 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4024 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07004025 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004026 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004027 ASSERT_TRUE(conn1 != nullptr);
4028 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4029
4030 // Simply adding the same candidate again won't create a new connection.
4031 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004032 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004033 EXPECT_EQ(conn1, conn2);
4034
4035 // Update the ufrag of the candidate and add it again.
4036 candidate.set_username(kIceUfrag[2]);
4037 ch.AddRemoteCandidate(candidate);
4038 conn2 = GetConnectionTo(&ch, host_address, port_num);
4039 EXPECT_NE(conn1, conn2);
4040 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4041 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4042
4043 // Verify that a ping with the new ufrag can be received on the new
4044 // connection.
4045 EXPECT_EQ(0, conn2->last_ping_received());
4046 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
Steve Antone9324572017-11-29 10:18:21 -08004047 EXPECT_GT(conn2->last_ping_received(), 0);
honghaiz36f50e82016-06-01 15:57:03 -07004048}
4049
Honghai Zhang572b0942016-06-23 12:26:57 -07004050// When the current selected connection is strong, lower-priority connections
4051// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07004052TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004053 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004054 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004055 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4056 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07004057 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004058 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07004059 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004060 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4061 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07004062 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004063 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004064 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07004065
4066 // When a higher-priority, nominated candidate comes in, the connections with
4067 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07004068 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004069 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07004070 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004071 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4072 NominateConnection(conn2);
Honghai Zhang161a5862016-10-20 11:47:02 -07004073 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004074
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004075 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07004076 // Wait until conn2 becomes not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004077 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004078
deadbeef14f97f52016-06-22 17:14:15 -07004079 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004080 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07004081 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07004082 // The selected connection should still be conn2. Even through conn3 has lower
4083 // priority and is not receiving/writable, it is not pruned because the
4084 // selected connection is not receiving.
honghaize58d73d2016-10-24 16:38:26 -07004085 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004086 EXPECT_FALSE(conn3->pruned());
4087}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004088
Honghai Zhang572b0942016-06-23 12:26:57 -07004089TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4090 rtc::ScopedFakeClock clock;
4091 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4092 P2PTransportChannel ch("test channel", 1, &pa);
4093 PrepareChannel(&ch);
4094 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004095 ch.MaybeStartGathering();
4096 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004097 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004098 ASSERT_TRUE(conn1 != nullptr);
4099 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004100 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004101 ASSERT_TRUE(conn2 != nullptr);
4102 // Even if conn1 is writable, nominated, receiving data, it should not prune
4103 // conn2.
4104 NominateConnection(conn1);
4105 SIMULATED_WAIT(false, 1, clock);
4106 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
4107 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4108 EXPECT_FALSE(conn2->pruned());
4109}
4110
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004111// Test that GetState returns the state correctly.
4112TEST_F(P2PTransportChannelPingTest, TestGetState) {
honghaize58d73d2016-10-24 16:38:26 -07004113 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004114 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004115 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4116 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004117 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004118 ch.MaybeStartGathering();
zhihuangd06adf62017-01-12 15:58:31 -08004119 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
deadbeef14f97f52016-06-22 17:14:15 -07004120 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4121 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004122 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4123 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004124 ASSERT_TRUE(conn1 != nullptr);
4125 ASSERT_TRUE(conn2 != nullptr);
4126 // Now there are two connections, so the transport channel is connecting.
zhihuangd06adf62017-01-12 15:58:31 -08004127 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004128 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004129 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaize58d73d2016-10-24 16:38:26 -07004130 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004131 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004132 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08004133 // Need to wait until the channel state is updated.
zhihuangd06adf62017-01-12 15:58:31 -08004134 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
honghaize58d73d2016-10-24 16:38:26 -07004135 kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004136}
4137
4138// Test that when a low-priority connection is pruned, it is not deleted
4139// right away, and it can become active and be pruned again.
4140TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004141 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004142 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07004143
deadbeef14f97f52016-06-22 17:14:15 -07004144 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4145 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004146 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07004147 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01004148 config.receiving_switching_delay = 800;
honghaiz9ad0db52016-07-14 19:30:28 -07004149 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004150 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004151 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004152 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004153 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004154 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004155 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07004156 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4157 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004158
4159 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07004160 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004161 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07004162 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004163 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004164 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004165 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004166 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004167 // |conn2| should not send a ping yet.
hbos06495bc2017-01-02 08:08:18 -08004168 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
zhihuangd06adf62017-01-12 15:58:31 -08004169 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004170 // Wait for |conn1| becoming not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004171 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004172 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07004173 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004174 ASSERT_TRUE(conn2 != nullptr);
hbos06495bc2017-01-02 08:08:18 -08004175 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
Honghai Zhange05bcc22016-08-16 18:19:14 -07004176 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004177 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004178 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4179 clock);
zhihuangd06adf62017-01-12 15:58:31 -08004180 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004181
4182 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004183 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004184 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4185 clock);
4186 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004187 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004188}
honghaiz77d0d6e2015-10-27 11:34:45 -07004189
4190// Test that if all connections in a channel has timed out on writing, they
4191// will all be deleted. We use Prune to simulate write_time_out.
4192TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
honghaize58d73d2016-10-24 16:38:26 -07004193 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07004194 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4195 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07004196 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07004197 ch.MaybeStartGathering();
4198 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07004199 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
honghaize58d73d2016-10-24 16:38:26 -07004200 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004201 ASSERT_TRUE(conn1 != nullptr);
4202 conn1->ReceivedPing(); // Becomes receiving
4203 conn1->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004204 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004205
4206 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07004207 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004208 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004209 ASSERT_TRUE(conn2 != nullptr);
4210 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07004211 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
honghaize58d73d2016-10-24 16:38:26 -07004212 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004213 ASSERT_TRUE(conn3 != nullptr);
4214 conn3->ReceivedPing(); // Becomes receiving
4215 // Now prune both conn2 and conn3; they will be deleted soon.
4216 conn2->Prune();
4217 conn3->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004218 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004219}
honghaiz9b669572015-11-04 12:07:44 -08004220
Honghai Zhang5a246372016-05-02 17:28:35 -07004221// Tests that after a port allocator session is started, it will be stopped
4222// when a new connection becomes writable and receiving. Also tests that if a
4223// connection belonging to an old session becomes writable, it won't stop
4224// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08004225TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07004226 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4227 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08004228 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004229 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08004230 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004231 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4232 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08004233 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004234 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004235 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4236
Honghai Zhang5a246372016-05-02 17:28:35 -07004237 // Start a new session. Even though conn1, which belongs to an older
4238 // session, becomes unwritable and writable again, it should not stop the
4239 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004240 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08004241 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07004242 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004243 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07004244 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4245
4246 // But if a new connection created from the new session becomes writable,
4247 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07004248 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4249 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08004250 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004251 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004252 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4253}
guoweis36f01372016-03-02 18:02:40 -08004254
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004255// Test that the ICE role is updated even on ports that has been removed.
4256// These ports may still have connections that need a correct role, in case that
4257// the connections on it may still receive stun pings.
4258TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07004259 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4260 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004261 // Starts with ICEROLE_CONTROLLING.
4262 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004263 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07004264 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07004265 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004266 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004267
deadbeef14f97f52016-06-22 17:14:15 -07004268 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004269 ASSERT_TRUE(conn != nullptr);
4270
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004271 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4272 // change the ICE role and expect it to be updated.
4273 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07004274 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07004275 ch.SetIceRole(ICEROLE_CONTROLLED);
4276 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004277}
4278
4279// Test that the ICE role is updated even on ports with inactive networks.
4280// These ports may still have connections that need a correct role, for the
4281// pings sent by those connections until they're replaced by newer-generation
4282// connections.
4283TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07004284 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4285 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004286 // Starts with ICEROLE_CONTROLLING.
4287 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07004288 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004289 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004290
deadbeef14f97f52016-06-22 17:14:15 -07004291 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004292 ASSERT_TRUE(conn != nullptr);
4293
4294 // Do an ICE restart, change the role, and expect the old port to have its
4295 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004296 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07004297 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004298 ch.SetIceRole(ICEROLE_CONTROLLED);
4299 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004300}
4301
4302// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07004303// will be destroyed. The port will only be destroyed after it is marked as
4304// "pruned."
4305TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07004306 rtc::ScopedFakeClock fake_clock;
4307
deadbeef14f97f52016-06-22 17:14:15 -07004308 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4309 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004310 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004311 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07004312 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004313 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004314
deadbeef14f97f52016-06-22 17:14:15 -07004315 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004316 ASSERT_TRUE(conn != nullptr);
4317
4318 // Simulate 2 minutes going by. This should be enough time for the port to
4319 // time out.
4320 for (int second = 0; second < 120; ++second) {
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004321 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeefdfc42442016-06-21 14:19:48 -07004322 }
4323 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004324 // Port will not be removed because it is not pruned yet.
sprang716978d2016-10-11 06:43:28 -07004325 PortInterface* port = GetPort(&ch);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004326 ASSERT_NE(nullptr, port);
4327
4328 // If the session prunes all ports, the port will be destroyed.
4329 ch.allocator_session()->PruneAllPorts();
sprang716978d2016-10-11 06:43:28 -07004330 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004331 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004332}
4333
guoweis36f01372016-03-02 18:02:40 -08004334class P2PTransportChannelMostLikelyToWorkFirstTest
4335 : public P2PTransportChannelPingTest {
4336 public:
4337 P2PTransportChannelMostLikelyToWorkFirstTest()
4338 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4339 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004340 allocator_.reset(
4341 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4342 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004343 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4344 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004345 allocator_->set_step_delay(kMinimumStepDelay);
4346 }
4347
deadbeef14f97f52016-06-22 17:14:15 -07004348 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004349 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004350 int stable_writable_connection_ping_interval) {
deadbeef49f34fd2016-12-06 16:22:06 -08004351 channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
deadbeef14f97f52016-06-22 17:14:15 -07004352 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004353 config.prioritize_most_likely_candidate_pairs =
4354 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004355 config.stable_writable_connection_ping_interval =
4356 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004357 channel_->SetIceConfig(config);
4358 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004359 channel_->MaybeStartGathering();
4360 return *channel_.get();
4361 }
4362
deadbeef14f97f52016-06-22 17:14:15 -07004363 BasicPortAllocator* allocator() { return allocator_.get(); }
4364 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004365
4366 // This verifies the next pingable connection has the expected candidates'
4367 // types and, for relay local candidate, the expected relay protocol and ping
4368 // it.
4369 void VerifyNextPingableConnection(
4370 const std::string& local_candidate_type,
4371 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004372 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4373 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004374 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004375 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004376 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4377 }
4378 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4379 }
4380
guoweis36f01372016-03-02 18:02:40 -08004381 private:
deadbeef14f97f52016-06-22 17:14:15 -07004382 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004383 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004384 TestTurnServer turn_server_;
4385 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004386};
4387
4388// Test that Relay/Relay connections will be pinged first when no other
4389// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004390// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004391TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4392 TestRelayRelayFirstWhenNothingPingedYet) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004393 const int max_strong_interval = 500;
deadbeef14f97f52016-06-22 17:14:15 -07004394 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
Honghai Zhang161a5862016-10-20 11:47:02 -07004395 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004396 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4397 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004398
deadbeef14f97f52016-06-22 17:14:15 -07004399 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4400 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004401
Honghai Zhang161a5862016-10-20 11:47:02 -07004402 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004403
4404 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004405 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4406 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4407 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004408
4409 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004410 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4411 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4412 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004413 conn2->ReceivedPing();
4414 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4415
Honghai Zhang572b0942016-06-23 12:26:57 -07004416 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004417 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4418 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4419 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004420 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004421 ASSERT_TRUE(conn3->writable());
4422 conn3->ReceivedPing();
4423
honghaiz524ecc22016-05-25 12:48:31 -07004424 /*
4425
4426 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4427 the flakiness. The following test becomes flaky because we now ping the
4428 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004429 times. The selected connection may have been pinged before
4430 |max_strong_interval|, so it may not be the next connection to be pinged as
4431 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004432
Honghai Zhang572b0942016-06-23 12:26:57 -07004433 // Verify that conn3 will be the "selected connection" since it is readable
4434 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004435 // pingable connection.
Honghai Zhang161a5862016-10-20 11:47:02 -07004436 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004437 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004438 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004439 ASSERT_TRUE(conn3->writable());
4440 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004441
4442 */
guoweis36f01372016-03-02 18:02:40 -08004443}
4444
4445// Test that Relay/Relay connections will be pinged first when everything has
4446// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4447// in the first round.
4448TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4449 TestRelayRelayFirstWhenEverythingPinged) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004450 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004451 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004452 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4453 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004454
deadbeef14f97f52016-06-22 17:14:15 -07004455 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004456 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004457
4458 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004459 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4460 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004461
4462 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004463 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004464 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004465
4466 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004467 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004468
4469 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004470 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004471
4472 // Now, every connection has been pinged once. The next one should be
4473 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004474 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004475}
4476
4477// Test that when we receive a new remote candidate, they will be tried first
4478// before we re-ping Relay/Relay connections again.
4479TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4480 TestNoStarvationOnNonRelayConnection) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004481 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004482 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004483 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4484 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004485
deadbeef14f97f52016-06-22 17:14:15 -07004486 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004487 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004488
4489 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004490 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004491
4492 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004493 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004494
4495 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004496 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004497 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004498
4499 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004500 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004501
4502 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004503 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004504
4505 // Now, every connection has been pinged once. The next one should be
4506 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004507 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004508}
4509
4510// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4511// followed by the rest.
4512TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4513 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004514 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
4515 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08004516 config.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08004517 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
guoweis36f01372016-03-02 18:02:40 -08004518 allocator()->AddTurnServer(config);
4519
Qingsi Wangdea68892018-03-27 10:55:21 -07004520 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004521 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004522 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4523 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4524 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004525
4526 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004527 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004528 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004529
4530 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004531 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004532
4533 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004534 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4535 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004536
4537 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004538 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004539}
deadbeef14f97f52016-06-22 17:14:15 -07004540
Steve Antone9324572017-11-29 10:18:21 -08004541} // namespace cricket