blob: fc2b65c8b3de640d8d1b603fe7ded39f2c1c1f00 [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,
116 int backup_ping_interval = -1) {
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);
158 allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
159 return allocator;
160}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700161} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700162
163namespace cricket {
164
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165// This test simulates 2 P2P endpoints that want to establish connectivity
166// with each other over various network topologies and conditions, which can be
167// specified in each individial test.
168// A virtual network (via VirtualSocketServer) along with virtual firewalls and
169// NATs (via Firewall/NATSocketServer) are used to simulate the various network
170// conditions. We can configure the IP addresses of the endpoints,
171// block various types of connectivity, or add arbitrary levels of NAT.
172// We also run a STUN server and a relay server on the virtual network to allow
173// our typical P2P mechanisms to do their thing.
174// For each case, we expect the P2P stack to eventually settle on a specific
175// form of connectivity to the other side. The test checks that the P2P
176// negotiation successfully establishes connectivity within a certain time,
177// and that the result is what we expect.
178// Note that this class is a base class for use by other tests, who will provide
179// specialized test behavior.
180class P2PTransportChannelTestBase : public testing::Test,
181 public rtc::MessageHandler,
182 public sigslot::has_slots<> {
183 public:
184 P2PTransportChannelTestBase()
deadbeef98e186c2017-05-16 18:00:06 -0700185 : vss_(new rtc::VirtualSocketServer()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000186 nss_(new rtc::NATSocketServer(vss_.get())),
187 ss_(new rtc::FirewallSocketServer(nss_.get())),
nisse7eaa4ea2017-05-08 05:25:41 -0700188 main_(ss_.get()),
189 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
190 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeeff137e972017-03-23 15:45:49 -0700191 socks_server1_(ss_.get(),
192 kSocksProxyAddrs[0],
193 ss_.get(),
194 kSocksProxyAddrs[0]),
195 socks_server2_(ss_.get(),
196 kSocksProxyAddrs[1],
197 ss_.get(),
198 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000199 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700200 ep1_.role_ = ICEROLE_CONTROLLING;
201 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202
203 ServerAddresses stun_servers;
204 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700205 ep1_.allocator_.reset(
206 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
207 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700208 ep1_.metrics_observer_ =
209 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
210 ep1_.allocator_->SetMetricsObserver(ep1_.metrics_observer_);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700211 ep2_.allocator_.reset(
212 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
213 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700214 ep2_.metrics_observer_ =
215 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
216 ep2_.allocator_->SetMetricsObserver(ep2_.metrics_observer_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217 }
218
219 protected:
220 enum Config {
221 OPEN, // Open to the Internet
222 NAT_FULL_CONE, // NAT, no filtering
223 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
224 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
225 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
226 NAT_DOUBLE_CONE, // Double NAT, both cone
227 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
228 BLOCK_UDP, // Firewall, UDP in/out blocked
229 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
deadbeeff137e972017-03-23 15:45:49 -0700230 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
231 PROXY_HTTPS, // All traffic through HTTPS proxy
232 PROXY_SOCKS, // All traffic through SOCKS proxy
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000233 NUM_CONFIGS
234 };
235
236 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700237 Result(const std::string& controlling_type,
238 const std::string& controlling_protocol,
239 const std::string& controlled_type,
240 const std::string& controlled_protocol,
241 int wait)
242 : controlling_type(controlling_type),
243 controlling_protocol(controlling_protocol),
244 controlled_type(controlled_type),
245 controlled_protocol(controlled_protocol),
246 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700247
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700248 // The expected candidate type and protocol of the controlling ICE agent.
249 std::string controlling_type;
250 std::string controlling_protocol;
251 // The expected candidate type and protocol of the controlled ICE agent.
252 std::string controlled_type;
253 std::string controlled_protocol;
254 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000255 int connect_wait;
256 };
257
258 struct ChannelData {
259 bool CheckData(const char* data, int len) {
260 bool ret = false;
261 if (!ch_packets_.empty()) {
262 std::string packet = ch_packets_.front();
263 ret = (packet == std::string(data, len));
264 ch_packets_.pop_front();
265 }
266 return ret;
267 }
268
Steve Antone9324572017-11-29 10:18:21 -0800269 std::string name_; // TODO(?) - Currently not used.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000270 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700271 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000272 };
273
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700274 struct CandidatesData : public rtc::MessageData {
zhihuangd06adf62017-01-12 15:58:31 -0800275 CandidatesData(IceTransportInternal* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700276 : channel(ch), candidates(1, c) {}
zhihuangd06adf62017-01-12 15:58:31 -0800277 CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700278 : channel(ch), candidates(cc) {}
zhihuangd06adf62017-01-12 15:58:31 -0800279 IceTransportInternal* channel;
deadbeef14f97f52016-06-22 17:14:15 -0700280 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000281 };
282
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000283 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000284 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700285 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000286 tiebreaker_(0),
287 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700288 save_candidates_(false) {}
deadbeef5bd5ca32017-02-10 11:31:50 -0800289 bool HasTransport(const rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700290 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000291 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800292 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700293 if (!HasTransport(transport))
294 return NULL;
295 if (cd1_.ch_.get() == transport)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000296 return &cd1_;
297 else
298 return &cd2_;
299 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000300
deadbeef14f97f52016-06-22 17:14:15 -0700301 void SetIceRole(IceRole role) { role_ = role; }
302 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200303 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
304 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000305 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
306 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200307 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000308 allocator_->set_step_delay(delay);
309 }
310 void SetAllowTcpListen(bool allow_tcp_listen) {
311 allocator_->set_allow_tcp_listen(allow_tcp_listen);
312 }
313
314 rtc::FakeNetworkManager network_manager_;
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700315 // |metrics_observer_| should outlive |allocator_| as the former may be
316 // used by the latter.
317 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer_;
deadbeef14f97f52016-06-22 17:14:15 -0700318 std::unique_ptr<BasicPortAllocator> allocator_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000319 ChannelData cd1_;
320 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700321 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200322 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000323 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000324 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700325 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700326 bool ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000327 };
328
deadbeef5bd5ca32017-02-10 11:31:50 -0800329 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700330 if (ep1_.HasTransport(transport))
331 return ep1_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000332 else
johand89ab142016-10-25 10:50:32 -0700333 return ep2_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000334 }
335
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700336 IceParameters IceParamsWithRenomination(const IceParameters& ice,
337 bool renomination) {
338 IceParameters new_ice = ice;
339 new_ice.renomination = renomination;
340 return new_ice;
341 }
342
johan02bd5122016-09-20 00:23:27 -0700343 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700344 const IceConfig& ep2_config,
345 bool renomination = false) {
346 IceParameters ice_ep1_cd1_ch =
347 IceParamsWithRenomination(kIceParams[0], renomination);
348 IceParameters ice_ep2_cd1_ch =
349 IceParamsWithRenomination(kIceParams[1], renomination);
350 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
351 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
352 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
353 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700354 ep1_.cd1_.ch_->SetMetricsObserver(ep1_.metrics_observer_);
355 ep2_.cd1_.ch_->SetMetricsObserver(ep2_.metrics_observer_);
deadbeefb60a8192016-08-24 15:15:00 -0700356 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
357 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700358 ep1_.cd1_.ch_->MaybeStartGathering();
359 ep2_.cd1_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000360 }
deadbeefb60a8192016-08-24 15:15:00 -0700361
johan02bd5122016-09-20 00:23:27 -0700362 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700363 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700364 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700365 }
366
deadbeef14f97f52016-06-22 17:14:15 -0700367 P2PTransportChannel* CreateChannel(int endpoint,
368 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700369 const IceParameters& local_ice,
370 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700371 P2PTransportChannel* channel = new P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800372 "test content name", component, GetAllocator(endpoint));
deadbeef14f97f52016-06-22 17:14:15 -0700373 channel->SignalReadyToSend.connect(
374 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700375 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700376 this, &P2PTransportChannelTestBase::OnCandidateGathered);
377 channel->SignalCandidatesRemoved.connect(
378 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000379 channel->SignalReadPacket.connect(
380 this, &P2PTransportChannelTestBase::OnReadPacket);
381 channel->SignalRoleConflict.connect(
382 this, &P2PTransportChannelTestBase::OnRoleConflict);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800383 channel->SignalNetworkRouteChanged.connect(
384 this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700385 channel->SetIceParameters(local_ice);
386 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
387 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000388 }
389 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
390 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000391 return channel;
392 }
393 void DestroyChannels() {
394 ep1_.cd1_.ch_.reset();
395 ep2_.cd1_.ch_.reset();
396 ep1_.cd2_.ch_.reset();
397 ep2_.cd2_.ch_.reset();
398 }
deadbeef14f97f52016-06-22 17:14:15 -0700399 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
400 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
401 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
402 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000403
Taylor Brandstetteref184702016-06-23 17:35:47 -0700404 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700405 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700406
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000407 // Common results.
408 static const Result kLocalUdpToLocalUdp;
409 static const Result kLocalUdpToStunUdp;
410 static const Result kLocalUdpToPrflxUdp;
411 static const Result kPrflxUdpToLocalUdp;
412 static const Result kStunUdpToLocalUdp;
413 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700414 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000415 static const Result kPrflxUdpToStunUdp;
416 static const Result kLocalUdpToRelayUdp;
417 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700418 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000419 static const Result kLocalTcpToLocalTcp;
420 static const Result kLocalTcpToPrflxTcp;
421 static const Result kPrflxTcpToLocalTcp;
422
423 rtc::NATSocketServer* nat() { return nss_.get(); }
424 rtc::FirewallSocketServer* fw() { return ss_.get(); }
425
426 Endpoint* GetEndpoint(int endpoint) {
427 if (endpoint == 0) {
428 return &ep1_;
429 } else if (endpoint == 1) {
430 return &ep2_;
431 } else {
432 return NULL;
433 }
434 }
honghaiz7252a002016-11-08 20:04:09 -0800435 BasicPortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000436 return GetEndpoint(endpoint)->allocator_.get();
437 }
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700438 webrtc::FakeMetricsObserver* GetMetricsObserver(int endpoint) {
439 return GetEndpoint(endpoint)->metrics_observer_;
440 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000441 void AddAddress(int endpoint, const SocketAddress& addr) {
442 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
443 }
honghaize1a0c942016-02-16 14:54:56 -0800444 void AddAddress(int endpoint,
445 const SocketAddress& addr,
446 const std::string& ifname,
447 rtc::AdapterType adapter_type) {
448 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
449 adapter_type);
450 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000451 void RemoveAddress(int endpoint, const SocketAddress& addr) {
452 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700453 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000454 }
deadbeeff137e972017-03-23 15:45:49 -0700455 void SetProxy(int endpoint, rtc::ProxyType type) {
456 rtc::ProxyInfo info;
457 info.type = type;
458 info.address = (type == rtc::PROXY_HTTPS) ?
459 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
460 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
461 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000462 void SetAllocatorFlags(int endpoint, int flags) {
463 GetAllocator(endpoint)->set_flags(flags);
464 }
deadbeef14f97f52016-06-22 17:14:15 -0700465 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000466 GetEndpoint(endpoint)->SetIceRole(role);
467 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200468 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000469 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
470 }
471 bool GetRoleConflict(int endpoint) {
472 return GetEndpoint(endpoint)->role_conflict();
473 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200474 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000475 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
476 }
477 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
478 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
479 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700480
481 // Return true if the approprite parts of the expected Result, based
482 // on the local and remote candidate of ep1_ch1, match. This can be
483 // used in an EXPECT_TRUE_WAIT.
484 bool CheckCandidate1(const Result& expected) {
485 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700486 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700487 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700488 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
489 return (local_protocol == expected.controlling_protocol &&
490 remote_protocol == expected.controlled_protocol &&
491 local_type == expected.controlling_type &&
492 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700493 }
494
495 // EXPECT_EQ on the approprite parts of the expected Result, based
496 // on the local and remote candidate of ep1_ch1. This is like
497 // CheckCandidate1, except that it will provide more detail about
498 // what didn't match.
499 void ExpectCandidate1(const Result& expected) {
500 if (CheckCandidate1(expected)) {
501 return;
502 }
503
504 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700505 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700506 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700507 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
508 EXPECT_EQ(expected.controlling_type, local_type);
509 EXPECT_EQ(expected.controlled_type, remote_type);
510 EXPECT_EQ(expected.controlling_protocol, local_protocol);
511 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700512 }
513
514 // Return true if the approprite parts of the expected Result, based
515 // on the local and remote candidate of ep2_ch1, match. This can be
516 // used in an EXPECT_TRUE_WAIT.
517 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700518 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
519 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
520 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
521 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
522 return (local_protocol == expected.controlled_protocol &&
523 remote_protocol == expected.controlling_protocol &&
524 local_type == expected.controlled_type &&
525 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700526 }
527
528 // EXPECT_EQ on the approprite parts of the expected Result, based
529 // on the local and remote candidate of ep2_ch1. This is like
530 // CheckCandidate2, except that it will provide more detail about
531 // what didn't match.
532 void ExpectCandidate2(const Result& expected) {
533 if (CheckCandidate2(expected)) {
534 return;
535 }
536
537 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700538 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700539 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700540 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
541 EXPECT_EQ(expected.controlled_type, local_type);
542 EXPECT_EQ(expected.controlling_type, remote_type);
543 EXPECT_EQ(expected.controlled_protocol, local_protocol);
544 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700545 }
546
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000547 void Test(const Result& expected) {
honghaize58d73d2016-10-24 16:38:26 -0700548 rtc::ScopedFakeClock clock;
nisse1bffc1d2016-05-02 08:18:55 -0700549 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700550 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000551
552 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700553 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -0700554 EXPECT_TRUE_SIMULATED_WAIT(
555 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
556 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
557 ep2_ch1()->writable(),
558 expected.connect_wait + kShortTimeout, clock);
nisse1bffc1d2016-05-02 08:18:55 -0700559 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000560 if (connect_time < expected.connect_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100561 RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000562 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100563 RTC_LOG(LS_INFO) << "Connect time: "
564 << "TIMEOUT (" << expected.connect_wait << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000565 }
566
Honghai Zhang572b0942016-06-23 12:26:57 -0700567 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000568 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700569 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700570 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700571 int64_t converge_time;
Honghai Zhang572b0942016-06-23 12:26:57 -0700572 // Verifying local and remote channel selected connection information.
573 // This is done only for the RFC 5245 as controlled agent will use
574 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
575 // EP1 result matrix.
honghaize58d73d2016-10-24 16:38:26 -0700576 EXPECT_TRUE_SIMULATED_WAIT(
577 CheckCandidate1(expected) && CheckCandidate2(expected),
578 kMediumTimeout, clock);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700579 // Also do EXPECT_EQ on each part so that failures are more verbose.
580 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700581 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000582
nisse1bffc1d2016-05-02 08:18:55 -0700583 converge_time = rtc::TimeMillis() - converge_start;
honghaize58d73d2016-10-24 16:38:26 -0700584 int64_t converge_wait = 2000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000585 if (converge_time < converge_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100586 RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000587 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100588 RTC_LOG(LS_INFO) << "Converge time: "
589 << "TIMEOUT (" << converge_wait << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000590 }
591 }
592 // Try sending some data to other end.
Steve Antone9324572017-11-29 10:18:21 -0800593 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000594
595 // Destroy the channels, and wait for them to be fully cleaned up.
596 DestroyChannels();
597 }
598
Steve Antone9324572017-11-29 10:18:21 -0800599 void TestSendRecv(rtc::FakeClock* clock) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000600 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700601 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000602 int len = static_cast<int>(strlen(data));
603 // local_channel1 <==> remote_channel1
honghaize58d73d2016-10-24 16:38:26 -0700604 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800605 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700606 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800607 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700608 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800609 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700610 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800611 kMediumTimeout, *clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000612 }
613 }
614
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700615 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700616 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000617 // restart the ice gathering. Finally it waits for the transport to select a
618 // new connection using the newly generated ice candidates.
619 // Before calling this function the end points must be configured.
620 void TestHandleIceUfragPasswordChanged() {
honghaize58d73d2016-10-24 16:38:26 -0700621 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700622 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
623 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
honghaize58d73d2016-10-24 16:38:26 -0700624 EXPECT_TRUE_SIMULATED_WAIT(
625 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
626 ep2_ch1()->receiving() && ep2_ch1()->writable(),
627 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000628
deadbeef14f97f52016-06-22 17:14:15 -0700629 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
630 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
631 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
632 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000633
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700634 ep1_ch1()->SetIceParameters(kIceParams[2]);
635 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700636 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700637 ep2_ch1()->SetIceParameters(kIceParams[3]);
638
639 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700640 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000641
honghaize58d73d2016-10-24 16:38:26 -0700642 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
643 old_local_candidate1->generation(),
644 kMediumTimeout, clock);
645 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
646 old_local_candidate2->generation(),
647 kMediumTimeout, clock);
648 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
649 old_remote_candidate1->generation(),
650 kMediumTimeout, clock);
651 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
652 old_remote_candidate2->generation(),
653 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000654 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
655 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
656 }
657
658 void TestSignalRoleConflict() {
honghaize58d73d2016-10-24 16:38:26 -0700659 rtc::ScopedFakeClock clock;
660 // Default EP1 is in controlling state.
661 SetIceTiebreaker(0, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000662
deadbeef14f97f52016-06-22 17:14:15 -0700663 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700664 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000665
666 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700667 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000668 // Since both the channels initiated with controlling state and channel2
669 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
honghaize58d73d2016-10-24 16:38:26 -0700670 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000671 EXPECT_FALSE(GetRoleConflict(1));
672
honghaize58d73d2016-10-24 16:38:26 -0700673 EXPECT_TRUE_SIMULATED_WAIT(
674 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
675 ep2_ch1()->receiving() && ep2_ch1()->writable(),
676 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000677
Honghai Zhang572b0942016-06-23 12:26:57 -0700678 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
679 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000680
Steve Antone9324572017-11-29 10:18:21 -0800681 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000682 }
683
deadbeef5bd5ca32017-02-10 11:31:50 -0800684 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700685 GetEndpoint(transport)->ready_to_send_ = true;
deadbeef14f97f52016-06-22 17:14:15 -0700686 }
687
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000688 // We pass the candidates directly to the other side.
zhihuangd06adf62017-01-12 15:58:31 -0800689 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
deadbeef14f97f52016-06-22 17:14:15 -0700690 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000691 return;
692
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000693 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700694 GetEndpoint(ch)->saved_candidates_.push_back(
695 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000696 } else {
nisse7eaa4ea2017-05-08 05:25:41 -0700697 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
698 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000699 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000700 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800701
702 void OnNetworkRouteChanged(rtc::Optional<rtc::NetworkRoute> network_route) {
703 // If the |network_route| is unset, don't count. This is used in the case
704 // when the network on remote side is down, the signal will be fired with an
705 // unset network route and it shouldn't trigger a connection switch.
706 if (network_route) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700707 ++selected_candidate_pair_switches_;
708 }
honghaiz9ad0db52016-07-14 19:30:28 -0700709 }
710
711 int reset_selected_candidate_pair_switches() {
712 int switches = selected_candidate_pair_switches_;
713 selected_candidate_pair_switches_ = 0;
714 return switches;
715 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000716
717 void PauseCandidates(int endpoint) {
718 GetEndpoint(endpoint)->save_candidates_ = true;
719 }
720
zhihuangd06adf62017-01-12 15:58:31 -0800721 void OnCandidatesRemoved(IceTransportInternal* ch,
deadbeef14f97f52016-06-22 17:14:15 -0700722 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700723 // Candidate removals are not paused.
724 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
nisse7eaa4ea2017-05-08 05:25:41 -0700725 main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700726 }
727
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800728 // Tcp candidate verification has to be done when they are generated.
729 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
730 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700731 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700732 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700733 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700734 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
735 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
736 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
737 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700738 } else {
739 FAIL() << "Unknown tcptype: " << candidate.tcptype();
740 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800741 }
742 }
743 }
744
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000745 void ResumeCandidates(int endpoint) {
746 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700747 for (auto& candidate : ed->saved_candidates_) {
nisse7eaa4ea2017-05-08 05:25:41 -0700748 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000749 }
750 ed->saved_candidates_.clear();
751 ed->save_candidates_ = false;
752 }
753
754 void OnMessage(rtc::Message* msg) {
755 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700756 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700757 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700758 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700759 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
760 if (!rch) {
761 return;
762 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700763 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700764 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700765 c.set_username("");
766 c.set_password("");
767 }
Mirko Bonadei675513b2017-11-09 11:09:25 +0100768 RTC_LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
769 << rch->component() << "): " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700770 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000771 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700772 break;
773 }
774 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700775 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700776 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700777 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
778 if (!rch) {
779 return;
780 }
781 for (Candidate& c : data->candidates) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100782 RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700783 rch->RemoveRemoteCandidate(c);
784 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000785 break;
786 }
787 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000788 }
johand89ab142016-10-25 10:50:32 -0700789
deadbeef5bd5ca32017-02-10 11:31:50 -0800790 void OnReadPacket(rtc::PacketTransportInternal* transport,
deadbeef14f97f52016-06-22 17:14:15 -0700791 const char* data,
792 size_t len,
793 const rtc::PacketTime& packet_time,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000794 int flags) {
johand89ab142016-10-25 10:50:32 -0700795 std::list<std::string>& packets = GetPacketList(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000796 packets.push_front(std::string(data, len));
797 }
johand89ab142016-10-25 10:50:32 -0700798
zhihuangd06adf62017-01-12 15:58:31 -0800799 void OnRoleConflict(IceTransportInternal* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000800 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700801 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
802 ? ICEROLE_CONTROLLED
803 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000804 channel->SetIceRole(new_role);
805 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700806
zhihuangd06adf62017-01-12 15:58:31 -0800807 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000808 rtc::PacketOptions options;
809 return channel->SendPacket(data, len, options, 0);
810 }
zhihuangd06adf62017-01-12 15:58:31 -0800811 bool CheckDataOnChannel(IceTransportInternal* channel,
deadbeef14f97f52016-06-22 17:14:15 -0700812 const char* data,
813 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000814 return GetChannelData(channel)->CheckData(data, len);
815 }
deadbeef14f97f52016-06-22 17:14:15 -0700816 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700817 return (ch && ch->selected_connection())
818 ? &ch->selected_connection()->local_candidate()
819 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000820 }
deadbeef14f97f52016-06-22 17:14:15 -0700821 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700822 return (ch && ch->selected_connection())
823 ? &ch->selected_connection()->remote_candidate()
824 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000825 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800826 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700827 if (ep1_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000828 return &ep1_;
johand89ab142016-10-25 10:50:32 -0700829 } else if (ep2_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000830 return &ep2_;
831 } else {
832 return NULL;
833 }
834 }
zhihuangd06adf62017-01-12 15:58:31 -0800835 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000836 if (ch == ep1_ch1())
837 return ep2_ch1();
838 else if (ch == ep1_ch2())
839 return ep2_ch2();
840 else if (ch == ep2_ch1())
841 return ep1_ch1();
842 else if (ch == ep2_ch2())
843 return ep1_ch2();
844 else
845 return NULL;
846 }
johand89ab142016-10-25 10:50:32 -0700847 std::list<std::string>& GetPacketList(
deadbeef5bd5ca32017-02-10 11:31:50 -0800848 rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700849 return GetChannelData(transport)->ch_packets_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000850 }
851
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700852 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700853
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700854 // How does the test pass ICE parameters to the P2PTransportChannel?
855 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700856 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700857 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
858 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000859 }
860
861 void set_force_relay(bool relay) {
862 force_relay_ = relay;
863 }
864
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700865 void ConnectSignalNominated(Connection* conn) {
866 conn->SignalNominated.connect(this,
867 &P2PTransportChannelTestBase::OnNominated);
868 }
869
870 void OnNominated(Connection* conn) { nominated_ = true; }
871 bool nominated() { return nominated_; }
872
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000873 private:
kwiberg3ec46792016-04-27 07:22:53 -0700874 std::unique_ptr<rtc::VirtualSocketServer> vss_;
875 std::unique_ptr<rtc::NATSocketServer> nss_;
876 std::unique_ptr<rtc::FirewallSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700877 rtc::AutoSocketServerThread main_;
deadbeef14f97f52016-06-22 17:14:15 -0700878 std::unique_ptr<TestStunServer> stun_server_;
879 TestTurnServer turn_server_;
deadbeeff137e972017-03-23 15:45:49 -0700880 rtc::SocksProxyServer socks_server1_;
881 rtc::SocksProxyServer socks_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000882 Endpoint ep1_;
883 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700884 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000885 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700886 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700887
888 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000889};
890
891// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700892const P2PTransportChannelTestBase::Result
893 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
894 "udp",
895 "local",
896 "udp",
897 1000);
898const P2PTransportChannelTestBase::Result
899 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
900 "udp",
901 "stun",
902 "udp",
903 1000);
904const P2PTransportChannelTestBase::Result
905 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
906 "udp",
907 "prflx",
908 "udp",
909 1000);
910const P2PTransportChannelTestBase::Result
911 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
912 "udp",
913 "local",
914 "udp",
915 1000);
916const P2PTransportChannelTestBase::Result
917 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
918 "udp",
919 "local",
920 "udp",
921 1000);
922const P2PTransportChannelTestBase::Result
923 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
924 "udp",
925 "stun",
926 "udp",
927 1000);
928const P2PTransportChannelTestBase::Result
929 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
930 "udp",
931 "prflx",
932 "udp",
933 1000);
934const P2PTransportChannelTestBase::Result
935 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
936 "udp",
937 "stun",
938 "udp",
939 1000);
940const P2PTransportChannelTestBase::Result
941 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
942 "udp",
943 "relay",
944 "udp",
945 2000);
946const P2PTransportChannelTestBase::Result
947 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
948 "udp",
949 "relay",
950 "udp",
951 2000);
952const P2PTransportChannelTestBase::Result
953 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
954 "udp",
955 "prflx",
956 "udp",
957 2000);
958const P2PTransportChannelTestBase::Result
959 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
960 "tcp",
961 "local",
962 "tcp",
963 3000);
964const P2PTransportChannelTestBase::Result
965 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
966 "tcp",
967 "prflx",
968 "tcp",
969 3000);
970const P2PTransportChannelTestBase::Result
971 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
972 "tcp",
973 "local",
974 "tcp",
975 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000976
977// Test the matrix of all the connectivity types we expect to see in the wild.
978// Just test every combination of the configs in the Config enum.
979class P2PTransportChannelTest : public P2PTransportChannelTestBase {
980 protected:
981 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700982 void ConfigureEndpoints(Config config1,
983 Config config2,
984 int allocator_flags1,
985 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000986 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000987 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700988 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000989 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000990 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700991 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000992
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700993 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000994 }
995 void ConfigureEndpoint(int endpoint, Config config) {
996 switch (config) {
997 case OPEN:
998 AddAddress(endpoint, kPublicAddrs[endpoint]);
999 break;
1000 case NAT_FULL_CONE:
1001 case NAT_ADDR_RESTRICTED:
1002 case NAT_PORT_RESTRICTED:
1003 case NAT_SYMMETRIC:
1004 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1005 // Add a single NAT of the desired type
1006 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1007 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
1008 AddClient(kPrivateAddrs[endpoint]);
1009 break;
1010 case NAT_DOUBLE_CONE:
1011 case NAT_SYMMETRIC_THEN_CONE:
1012 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1013 // Add a two cascaded NATs of the desired types
1014 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1015 (config == NAT_DOUBLE_CONE) ?
1016 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
1017 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1018 rtc::NAT_OPEN_CONE)->
1019 AddClient(kCascadedPrivateAddrs[endpoint]);
1020 break;
1021 case BLOCK_UDP:
1022 case BLOCK_UDP_AND_INCOMING_TCP:
deadbeeff137e972017-03-23 15:45:49 -07001023 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1024 case PROXY_HTTPS:
1025 case PROXY_SOCKS:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001026 AddAddress(endpoint, kPublicAddrs[endpoint]);
1027 // Block all UDP
1028 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
1029 kPublicAddrs[endpoint]);
1030 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1031 // Block TCP inbound to the endpoint
1032 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1033 kPublicAddrs[endpoint]);
deadbeeff137e972017-03-23 15:45:49 -07001034 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1035 // Block all TCP to/from the endpoint except 80/443 out
1036 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1037 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1038 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1039 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1040 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1041 kPublicAddrs[endpoint]);
1042 } else if (config == PROXY_HTTPS) {
1043 // Block all TCP to/from the endpoint except to the proxy server
1044 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1045 kHttpsProxyAddrs[endpoint]);
1046 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1047 kPublicAddrs[endpoint]);
1048 SetProxy(endpoint, rtc::PROXY_HTTPS);
1049 } else if (config == PROXY_SOCKS) {
1050 // Block all TCP to/from the endpoint except to the proxy server
1051 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1052 kSocksProxyAddrs[endpoint]);
1053 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1054 kPublicAddrs[endpoint]);
1055 SetProxy(endpoint, rtc::PROXY_SOCKS5);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001056 }
1057 break;
1058 default:
deadbeef1ee21252017-06-13 15:49:45 -07001059 RTC_NOTREACHED();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001060 break;
1061 }
1062 }
1063};
1064
1065// Shorthands for use in the test matrix.
1066#define LULU &kLocalUdpToLocalUdp
1067#define LUSU &kLocalUdpToStunUdp
1068#define LUPU &kLocalUdpToPrflxUdp
1069#define PULU &kPrflxUdpToLocalUdp
1070#define SULU &kStunUdpToLocalUdp
1071#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001072#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001073#define PUSU &kPrflxUdpToStunUdp
1074#define LURU &kLocalUdpToRelayUdp
1075#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001076#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001077#define LTLT &kLocalTcpToLocalTcp
1078#define LTPT &kLocalTcpToPrflxTcp
1079#define PTLT &kPrflxTcpToLocalTcp
Steve Antone9324572017-11-29 10:18:21 -08001080// TODO(?): Enable these once TestRelayServer can accept external TCP.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001081#define LTRT NULL
1082#define LSRS NULL
1083
1084// Test matrix. Originator behavior defined by rows, receiever by columns.
1085
Steve Antone9324572017-11-29 10:18:21 -08001086// TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
1087// TODO(?): Fix NULLs caused by no HTTP proxy support.
1088// TODO(?): Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001089const P2PTransportChannelTest::Result*
1090 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
deadbeeff137e972017-03-23 15:45:49 -07001091// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1092/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL, LTPT},
1093/*CO*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1094/*AD*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1095/*PO*/ {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, LTRT},
1096/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1097/*2C*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1098/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1099/*!U*/ {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, LTRT},
1100/*!T*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1101/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1102/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1103/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001104};
1105
1106// The actual tests that exercise all the various configurations.
1107// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001108#define P2P_TEST_DECLARATION(x, y, z) \
1109 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1110 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1111 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001112 if (kMatrix[x][y] != NULL) \
1113 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001114 else \
Mirko Bonadei675513b2017-11-09 11:09:25 +01001115 RTC_LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001116 }
1117
Steve Antone9324572017-11-29 10:18:21 -08001118#define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001119
deadbeeff137e972017-03-23 15:45:49 -07001120#define P2P_TEST_SET(x) \
1121 P2P_TEST(x, OPEN) \
1122 P2P_TEST(x, NAT_FULL_CONE) \
1123 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1124 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1125 P2P_TEST(x, NAT_SYMMETRIC) \
1126 P2P_TEST(x, NAT_DOUBLE_CONE) \
1127 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1128 P2P_TEST(x, BLOCK_UDP) \
1129 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1130 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1131 P2P_TEST(x, PROXY_HTTPS) \
1132 P2P_TEST(x, PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001133
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001134P2P_TEST_SET(OPEN)
1135P2P_TEST_SET(NAT_FULL_CONE)
1136P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1137P2P_TEST_SET(NAT_PORT_RESTRICTED)
1138P2P_TEST_SET(NAT_SYMMETRIC)
1139P2P_TEST_SET(NAT_DOUBLE_CONE)
1140P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1141P2P_TEST_SET(BLOCK_UDP)
1142P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
deadbeeff137e972017-03-23 15:45:49 -07001143P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1144P2P_TEST_SET(PROXY_HTTPS)
1145P2P_TEST_SET(PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001146
1147// Test that we restart candidate allocation when local ufrag&pwd changed.
1148// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001149TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001150 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001151 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001152 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001153 TestHandleIceUfragPasswordChanged();
1154 DestroyChannels();
1155}
1156
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001157// Same as above test, but with a symmetric NAT.
1158// We should end up with relay<->prflx candidate pairs, with generation "1".
1159TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1160 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1161 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001162 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001163 TestHandleIceUfragPasswordChanged();
1164 DestroyChannels();
1165}
1166
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001167// Test the operation of GetStats.
1168TEST_F(P2PTransportChannelTest, GetStats) {
honghaize58d73d2016-10-24 16:38:26 -07001169 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001170 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001171 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001172 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -07001173 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1174 ep2_ch1()->receiving() &&
1175 ep2_ch1()->writable(),
1176 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001177 TestSendRecv(&clock);
deadbeef14f97f52016-06-22 17:14:15 -07001178 ConnectionInfos infos;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001179 ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
Steve Antone9324572017-11-29 10:18:21 -08001180 ASSERT_GE(infos.size(), 1u);
deadbeef14f97f52016-06-22 17:14:15 -07001181 ConnectionInfo* best_conn_info = nullptr;
1182 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001183 if (info.best_connection) {
1184 best_conn_info = &info;
1185 break;
1186 }
1187 }
1188 ASSERT_TRUE(best_conn_info != nullptr);
1189 EXPECT_TRUE(best_conn_info->new_connection);
1190 EXPECT_TRUE(best_conn_info->receiving);
1191 EXPECT_TRUE(best_conn_info->writable);
1192 EXPECT_FALSE(best_conn_info->timeout);
1193 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1194 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1195 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1196 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001197 DestroyChannels();
1198}
1199
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001200// Tests that UMAs are recorded when ICE restarts while the channel
1201// is disconnected.
1202TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1203 rtc::ScopedFakeClock clock;
1204 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1205
1206 CreateChannels();
1207 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1208 ep2_ch1()->receiving() &&
1209 ep2_ch1()->writable(),
1210 kDefaultTimeout, clock);
1211
1212 // Drop all packets so that both channels become not writable.
1213 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
skvlad51072462017-02-02 11:50:14 -08001214 const int kWriteTimeoutDelay = 8000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001215 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1216 kWriteTimeoutDelay, clock);
1217
1218 ep1_ch1()->SetIceParameters(kIceParams[2]);
1219 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1220 ep1_ch1()->MaybeStartGathering();
1221 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1222 webrtc::kEnumCounterIceRestart,
1223 static_cast<int>(IceRestartState::DISCONNECTED)));
1224
1225 ep2_ch1()->SetIceParameters(kIceParams[3]);
1226 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1227 ep2_ch1()->MaybeStartGathering();
1228 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1229 webrtc::kEnumCounterIceRestart,
1230 static_cast<int>(IceRestartState::DISCONNECTED)));
1231
1232 DestroyChannels();
1233}
1234
1235// Tests that UMAs are recorded when ICE restarts while the channel
1236// is connected.
1237TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1238 rtc::ScopedFakeClock clock;
1239 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1240
1241 CreateChannels();
1242 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1243 ep2_ch1()->receiving() &&
1244 ep2_ch1()->writable(),
1245 kDefaultTimeout, clock);
1246
1247 ep1_ch1()->SetIceParameters(kIceParams[2]);
1248 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1249 ep1_ch1()->MaybeStartGathering();
1250 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1251 webrtc::kEnumCounterIceRestart,
1252 static_cast<int>(IceRestartState::CONNECTED)));
1253
1254 ep2_ch1()->SetIceParameters(kIceParams[3]);
1255 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1256 ep2_ch1()->MaybeStartGathering();
1257 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1258 webrtc::kEnumCounterIceRestart,
1259 static_cast<int>(IceRestartState::CONNECTED)));
1260
1261 DestroyChannels();
1262}
1263
1264// Tests that UMAs are recorded when ICE restarts while the channel
1265// is connecting.
1266TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1267 rtc::ScopedFakeClock clock;
1268 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1269
1270 // Create the channels without waiting for them to become connected.
1271 CreateChannels();
1272
1273 ep1_ch1()->SetIceParameters(kIceParams[2]);
1274 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1275 ep1_ch1()->MaybeStartGathering();
1276 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1277 webrtc::kEnumCounterIceRestart,
1278 static_cast<int>(IceRestartState::CONNECTING)));
1279
1280 ep2_ch1()->SetIceParameters(kIceParams[3]);
1281 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1282 ep2_ch1()->MaybeStartGathering();
1283 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1284 webrtc::kEnumCounterIceRestart,
1285 static_cast<int>(IceRestartState::CONNECTING)));
1286
1287 DestroyChannels();
1288}
1289
1290// Tests that a UMA on ICE regathering is recorded when there is a network
1291// change if and only if continual gathering is enabled.
1292TEST_F(P2PTransportChannelTest,
1293 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1294 rtc::ScopedFakeClock clock;
1295 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1296
1297 // ep1 gathers continually but ep2 does not.
1298 IceConfig continual_gathering_config =
1299 CreateIceConfig(1000, GATHER_CONTINUALLY);
1300 IceConfig default_config;
1301 CreateChannels(continual_gathering_config, default_config);
1302
1303 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1304 ep2_ch1()->receiving() &&
1305 ep2_ch1()->writable(),
1306 kDefaultTimeout, clock);
1307
1308 // Adding address in ep1 will trigger continual gathering.
1309 AddAddress(0, kAlternateAddrs[0]);
1310 EXPECT_EQ_SIMULATED_WAIT(
1311 1, GetMetricsObserver(0)->GetEnumCounter(
1312 webrtc::kEnumCounterIceRegathering,
1313 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)),
1314 kDefaultTimeout, clock);
1315
1316 ep2_ch1()->SetIceParameters(kIceParams[3]);
1317 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1318 ep2_ch1()->MaybeStartGathering();
1319
1320 AddAddress(1, kAlternateAddrs[1]);
1321 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1322 // ep2 has not enabled continual gathering.
1323 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1324 webrtc::kEnumCounterIceRegathering,
1325 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)));
1326
1327 DestroyChannels();
1328}
1329
1330// Tests that a UMA on ICE regathering is recorded when there is a network
1331// failure if and only if continual gathering is enabled.
1332TEST_F(P2PTransportChannelTest,
1333 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1334 rtc::ScopedFakeClock clock;
1335 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1336
1337 // ep1 gathers continually but ep2 does not.
1338 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001339 config1.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001340 IceConfig config2;
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001341 config2.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001342 CreateChannels(config1, config2);
1343
1344 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1345 ep2_ch1()->receiving() &&
1346 ep2_ch1()->writable(),
1347 kDefaultTimeout, clock);
1348
1349 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1350 // Timeout value such that all connections are deleted.
1351 const int kNetworkFailureTimeout = 35000;
1352 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
1353 EXPECT_LE(1, GetMetricsObserver(0)->GetEnumCounter(
1354 webrtc::kEnumCounterIceRegathering,
1355 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1356 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1357 webrtc::kEnumCounterIceRegathering,
1358 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1359
1360 DestroyChannels();
1361}
1362
Steve Anton300bf8e2017-07-14 10:13:10 -07001363// Tests that ICE regathering occurs regularly when
1364// regather_all_networks_interval_range configuration value is set.
1365TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
1366 rtc::ScopedFakeClock clock;
1367 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1368
1369 // ep1 gathers continually but ep2 does not.
1370 const int kRegatherInterval = 2000;
1371 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1372 config1.regather_all_networks_interval_range.emplace(
1373 kRegatherInterval, kRegatherInterval);
1374 IceConfig config2;
Steve Anton300bf8e2017-07-14 10:13:10 -07001375 CreateChannels(config1, config2);
1376
1377 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1378 ep2_ch1()->receiving() &&
1379 ep2_ch1()->writable(),
1380 kDefaultTimeout, clock);
1381
1382 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1383 // Timeout value such that all connections are deleted.
1384 const int kNetworkGatherDuration = 11000;
1385 SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
1386 // Expect regathering to happen 5 times in 11s with 2s interval.
1387 EXPECT_LE(5, GetMetricsObserver(0)->GetEnumCounter(
1388 webrtc::kEnumCounterIceRegathering,
1389 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1390 // Expect no regathering if continual gathering not configured.
1391 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1392 webrtc::kEnumCounterIceRegathering,
1393 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1394
1395 DestroyChannels();
1396}
1397
1398// Test that ICE periodic regathering can change the selected connection on the
1399// specified interval and that the peers can communicate over the new
1400// connection. The test is parameterized to test that it works when regathering
1401// is done by the ICE controlling peer and when done by the controlled peer.
1402class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
1403 protected:
1404 void TestWithRoles(IceRole p1_role, IceRole p2_role) {
1405 rtc::ScopedFakeClock clock;
1406 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1407 kDefaultPortAllocatorFlags);
1408 set_force_relay(true);
1409
1410 const int kRegatherInterval = 2000;
1411 const int kNumRegathers = 2;
1412
1413 // Set up peer 1 to auto regather every 2s.
1414 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1415 config1.regather_all_networks_interval_range.emplace(
1416 kRegatherInterval, kRegatherInterval);
1417 IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1418
1419 // Set peer roles.
1420 SetIceRole(0, p1_role);
1421 SetIceRole(1, p2_role);
1422
1423 CreateChannels(config1, config2);
1424
1425 // Wait for initial connection to be made.
1426 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() &&
1427 ep1_ch1()->writable() &&
1428 ep2_ch1()->receiving() &&
1429 ep2_ch1()->writable(),
1430 kMediumTimeout, clock);
1431
1432 const Connection* initial_selected = ep1_ch1()->selected_connection();
1433
1434 // Wait long enough for 2 regathering cycles to happen plus some extra so
1435 // the new connection has time to settle.
1436 const int kWaitRegather =
1437 kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
1438 SIMULATED_WAIT(false, kWaitRegather, clock);
1439 EXPECT_EQ(kNumRegathers, GetMetricsObserver(0)->GetEnumCounter(
1440 webrtc::kEnumCounterIceRegathering,
1441 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1442
1443 const Connection* new_selected = ep1_ch1()->selected_connection();
1444
1445 // Want the new selected connection to be different.
1446 ASSERT_NE(initial_selected, new_selected);
1447
1448 // Make sure we can communicate over the new connection too.
Steve Antone9324572017-11-29 10:18:21 -08001449 TestSendRecv(&clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001450 }
1451};
1452
1453TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
1454 TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
1455}
1456
1457TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
1458 TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
1459}
1460
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001461// Test that we properly create a connection on a STUN ping from unknown address
1462// when the signaling is slow.
1463TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001464 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001465 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001466 // Emulate no remote parameters coming in.
1467 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001468 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001469 // Only have remote parameters come in for ep2, not ep1.
1470 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001471
1472 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1473 // candidate.
1474 PauseCandidates(1);
1475
Honghai Zhange05bcc22016-08-16 18:19:14 -07001476 // Wait until the callee becomes writable to make sure that a ping request is
1477 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001478 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001479 // Add two sets of remote ICE credentials, so that the ones used by the
1480 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001481 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1482 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001483 // The caller should have the selected connection connected to the peer
1484 // reflexive candidate.
1485 const Connection* selected_connection = nullptr;
1486 ASSERT_TRUE_WAIT(
1487 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001488 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001489 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1490 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1491 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1492 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001493
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001494 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001495 // Verify ep1's selected connection is updated to use the 'local' candidate.
1496 EXPECT_EQ_WAIT("local",
1497 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001498 kMediumTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001499 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001500 DestroyChannels();
1501}
1502
1503// Test that we properly create a connection on a STUN ping from unknown address
1504// when the signaling is slow and the end points are behind NAT.
1505TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001506 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001507 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001508 // Emulate no remote parameters coming in.
1509 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001510 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001511 // Only have remote parameters come in for ep2, not ep1.
1512 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001513 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1514 // candidate.
1515 PauseCandidates(1);
1516
Honghai Zhange05bcc22016-08-16 18:19:14 -07001517 // Wait until the callee becomes writable to make sure that a ping request is
1518 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001519 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001520 // Add two sets of remote ICE credentials, so that the ones used by the
1521 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001522 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1523 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001524
1525 // The caller's selected connection should be connected to the peer reflexive
1526 // candidate.
1527 const Connection* selected_connection = nullptr;
1528 ASSERT_TRUE_WAIT(
1529 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001530 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001531 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1532 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1533 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1534 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001535
1536 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001537
Honghai Zhange05bcc22016-08-16 18:19:14 -07001538 EXPECT_EQ_WAIT("prflx",
1539 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001540 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001541 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001542 DestroyChannels();
1543}
1544
deadbeef0af180b2016-06-21 13:15:32 -07001545// Test that we properly create a connection on a STUN ping from unknown address
1546// when the signaling is slow, even if the new candidate is created due to the
1547// remote peer doing an ICE restart, pairing this candidate across generations.
1548//
1549// Previously this wasn't working due to a bug where the peer reflexive
1550// candidate was only updated for the newest generation candidate pairs, and
1551// not older-generation candidate pairs created by pairing candidates across
1552// generations. This resulted in the old-generation prflx candidate being
1553// prioritized above new-generation candidate pairs.
1554TEST_F(P2PTransportChannelTest,
1555 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1556 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1557 kDefaultPortAllocatorFlags);
1558 // Only gather relay candidates, so that when the prflx candidate arrives
1559 // it's prioritized above the current candidate pair.
deadbeef14f97f52016-06-22 17:14:15 -07001560 GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
1561 GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001562 // Setting this allows us to control when SetRemoteIceParameters is called.
1563 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001564 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001565 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001566 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1567 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001568 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1569 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1570 kDefaultTimeout);
1571
1572 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001573 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001574 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001575 ep2_ch1()->SetIceParameters(kIceParams[3]);
1576
1577 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001578 ep2_ch1()->MaybeStartGathering();
1579
Honghai Zhang572b0942016-06-23 12:26:57 -07001580 // The caller should have the selected connection connected to the peer
1581 // reflexive candidate.
deadbeef0af180b2016-06-21 13:15:32 -07001582 EXPECT_EQ_WAIT("prflx",
Honghai Zhang572b0942016-06-23 12:26:57 -07001583 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001584 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001585 const Connection* prflx_selected_connection =
1586 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001587
1588 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001589 ep1_ch1()->SetIceParameters(kIceParams[2]);
1590
1591 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001592 ep1_ch1()->MaybeStartGathering();
1593
1594 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1595 // their information to update the peer reflexive candidate.
1596 ResumeCandidates(1);
1597
1598 EXPECT_EQ_WAIT("relay",
Honghai Zhang572b0942016-06-23 12:26:57 -07001599 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001600 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001601 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001602 DestroyChannels();
1603}
1604
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001605// Test that if remote candidates don't have ufrag and pwd, we still work.
1606TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001607 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001608 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001609 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001610 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001611 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001612 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001613 // Wait until the callee's connections are created.
Honghai Zhang161a5862016-10-20 11:47:02 -07001614 EXPECT_TRUE_SIMULATED_WAIT(
1615 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1616 kMediumTimeout, clock);
1617 // Wait to make sure the selected connection is not changed.
1618 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1619 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001620 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001621 DestroyChannels();
1622}
1623
1624// Test that a host behind NAT cannot be reached when incoming_only
1625// is set to true.
1626TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
honghaize58d73d2016-10-24 16:38:26 -07001627 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001628 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001629 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001630
1631 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001632 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001633 ep1_ch1()->set_incoming_only(true);
1634
1635 // Pump for 1 second and verify that the channels are not connected.
honghaize58d73d2016-10-24 16:38:26 -07001636 SIMULATED_WAIT(false, kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001637
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001638 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001639 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001640 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001641 EXPECT_FALSE(ep2_ch1()->writable());
1642
1643 DestroyChannels();
1644}
1645
1646// Test that a peer behind NAT can connect to a peer that has
1647// incoming_only flag set.
1648TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
honghaize58d73d2016-10-24 16:38:26 -07001649 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001650 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001651 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001652
1653 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001654 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001655 ep1_ch1()->set_incoming_only(true);
1656
honghaize58d73d2016-10-24 16:38:26 -07001657 EXPECT_TRUE_SIMULATED_WAIT(
1658 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1659 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1660 ep2_ch1()->writable(),
1661 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001662
1663 DestroyChannels();
1664}
1665
deadbeef1ee21252017-06-13 15:49:45 -07001666// Test that two peers can connect when one can only make outgoing TCP
1667// connections. This has been observed in some scenarios involving
1668// VPNs/firewalls.
1669TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
1670 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1671 // application needs this use case to work, since the application must accept
1672 // the tradeoff that more candidates need to be allocated.
1673 //
1674 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1675 // things to ensure extra candidates don't waste resources?
1676 ConfigureEndpoints(
1677 OPEN, OPEN,
1678 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1679 kDefaultPortAllocatorFlags);
1680 // In order to simulate nothing working but outgoing TCP connections, prevent
1681 // the endpoint from binding to its interface's address as well as the
1682 // "any" addresses. It can then only make a connection by using "Connect()".
1683 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1684 kPublicAddrs[0].ipaddr()});
1685 CreateChannels();
1686 // Expect a "prflx" candidate on the side that can only make outgoing
1687 // connections, endpoint 0.
1688 Test(kPrflxTcpToLocalTcp);
1689 DestroyChannels();
1690}
1691
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001692TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
honghaize58d73d2016-10-24 16:38:26 -07001693 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001694 AddAddress(0, kPublicAddrs[0]);
1695 AddAddress(1, kPublicAddrs[1]);
1696
1697 SetAllocationStepDelay(0, kMinimumStepDelay);
1698 SetAllocationStepDelay(1, kMinimumStepDelay);
1699
deadbeef14f97f52016-06-22 17:14:15 -07001700 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1701 PORTALLOCATOR_DISABLE_STUN |
1702 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001703 // Disable all protocols except TCP.
1704 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1705 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1706
1707 SetAllowTcpListen(0, true); // actpass.
1708 SetAllowTcpListen(1, false); // active.
1709
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001710 // We want SetRemoteIceParameters to be called as it normally would.
1711 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001712 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001713 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001714
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001715 // Pause candidate so we could verify the candidate properties.
1716 PauseCandidates(0);
1717 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001718 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001719
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001720 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001721 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1722 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001723
1724 // Resume candidates.
1725 ResumeCandidates(0);
1726 ResumeCandidates(1);
1727
honghaize58d73d2016-10-24 16:38:26 -07001728 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1729 ep2_ch1()->receiving() &&
1730 ep2_ch1()->writable(),
1731 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001732 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1733 ep2_ch1()->selected_connection() &&
1734 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1735 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001736
Steve Antone9324572017-11-29 10:18:21 -08001737 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001738 DestroyChannels();
1739}
1740
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001741TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001742 AddAddress(0, kPublicAddrs[0]);
1743 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001744 TestSignalRoleConflict();
1745}
1746
1747// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1748// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001749TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
honghaize58d73d2016-10-24 16:38:26 -07001750 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001751 AddAddress(0, kPublicAddrs[0]);
1752 AddAddress(1, kPublicAddrs[1]);
1753
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001754 // Give the first connection the higher tiebreaker so its role won't
1755 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001756 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001757 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001758 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001759 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001760
johan02bd5122016-09-20 00:23:27 -07001761 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001762
honghaize58d73d2016-10-24 16:38:26 -07001763 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001764
deadbeef14f97f52016-06-22 17:14:15 -07001765 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001766 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001767 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001768 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001769 }
1770
deadbeef14f97f52016-06-22 17:14:15 -07001771 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001772 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001773
deadbeef14f97f52016-06-22 17:14:15 -07001774 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001775 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001776 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001777 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001778 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001779 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001780 }
1781
honghaize58d73d2016-10-24 16:38:26 -07001782 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1783 ep2_ch1()->receiving() &&
1784 ep2_ch1()->writable(),
1785 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001786
Honghai Zhang572b0942016-06-23 12:26:57 -07001787 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1788 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001789
Steve Antone9324572017-11-29 10:18:21 -08001790 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001791 DestroyChannels();
1792}
1793
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001794// Verify that we can set DSCP value and retrieve properly from P2PTC.
1795TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1796 AddAddress(0, kPublicAddrs[0]);
1797 AddAddress(1, kPublicAddrs[1]);
1798
johan02bd5122016-09-20 00:23:27 -07001799 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001800 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1801 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1802 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1803 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1804 GetEndpoint(0)->cd1_.ch_->SetOption(
1805 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1806 GetEndpoint(1)->cd1_.ch_->SetOption(
1807 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1808 EXPECT_EQ(rtc::DSCP_CS6,
1809 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1810 EXPECT_EQ(rtc::DSCP_CS6,
1811 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1812 GetEndpoint(0)->cd1_.ch_->SetOption(
1813 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1814 GetEndpoint(1)->cd1_.ch_->SetOption(
1815 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1816 EXPECT_EQ(rtc::DSCP_AF41,
1817 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1818 EXPECT_EQ(rtc::DSCP_AF41,
1819 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1820}
1821
1822// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001823TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
honghaize58d73d2016-10-24 16:38:26 -07001824 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001825 AddAddress(0, kIPv6PublicAddrs[0]);
1826 AddAddress(0, kPublicAddrs[0]);
1827 AddAddress(1, kIPv6PublicAddrs[1]);
1828 AddAddress(1, kPublicAddrs[1]);
1829
1830 SetAllocationStepDelay(0, kMinimumStepDelay);
1831 SetAllocationStepDelay(1, kMinimumStepDelay);
1832
1833 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08001834 SetAllocatorFlags(
1835 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1836 SetAllocatorFlags(
1837 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001838
johan02bd5122016-09-20 00:23:27 -07001839 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001840
honghaize58d73d2016-10-24 16:38:26 -07001841 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1842 ep2_ch1()->receiving() &&
1843 ep2_ch1()->writable(),
1844 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001845 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001846 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001847 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1848 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1849
Steve Antone9324572017-11-29 10:18:21 -08001850 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001851 DestroyChannels();
1852}
1853
1854// Testing forceful TURN connections.
1855TEST_F(P2PTransportChannelTest, TestForceTurn) {
honghaize58d73d2016-10-24 16:38:26 -07001856 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001857 ConfigureEndpoints(
1858 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001859 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1860 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001861 set_force_relay(true);
1862
1863 SetAllocationStepDelay(0, kMinimumStepDelay);
1864 SetAllocationStepDelay(1, kMinimumStepDelay);
1865
johan02bd5122016-09-20 00:23:27 -07001866 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001867
honghaize58d73d2016-10-24 16:38:26 -07001868 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1869 ep2_ch1()->receiving() &&
1870 ep2_ch1()->writable(),
1871 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001872
Honghai Zhang572b0942016-06-23 12:26:57 -07001873 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1874 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001875
1876 EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
1877 EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
1878 EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
1879 EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
1880
Steve Antone9324572017-11-29 10:18:21 -08001881 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001882 DestroyChannels();
1883}
1884
honghaiz98db68f2015-09-29 07:58:17 -07001885// Test that if continual gathering is set to true, ICE gathering state will
1886// not change to "Complete", and vice versa.
1887TEST_F(P2PTransportChannelTest, TestContinualGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001888 rtc::ScopedFakeClock clock;
honghaiz98db68f2015-09-29 07:58:17 -07001889 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1890 kDefaultPortAllocatorFlags);
1891 SetAllocationStepDelay(0, kDefaultStepDelay);
1892 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07001893 IceConfig continual_gathering_config =
1894 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001895 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07001896 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07001897 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07001898
Honghai Zhang161a5862016-10-20 11:47:02 -07001899 EXPECT_TRUE_SIMULATED_WAIT(
1900 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1901 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1902 ep2_ch1()->writable(),
1903 kMediumTimeout, clock);
1904 SIMULATED_WAIT(
1905 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
1906 kShortTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07001907 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001908 ep1_ch1()->gathering_state());
1909 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001910 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001911 ep2_ch1()->gathering_state());
1912
1913 DestroyChannels();
1914}
1915
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001916// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1917// PortAllocatorSession that has not yet finished gathering candidates.
1918TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001919 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001920 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1921 kDefaultPortAllocatorFlags);
1922 // First create a pooled session for each endpoint.
1923 auto& allocator_1 = GetEndpoint(0)->allocator_;
1924 auto& allocator_2 = GetEndpoint(1)->allocator_;
1925 int pool_size = 1;
1926 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001927 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001928 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001929 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001930 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001931 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001932 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001933 allocator_2->GetPooledSession();
1934 ASSERT_NE(nullptr, pooled_session_1);
1935 ASSERT_NE(nullptr, pooled_session_2);
1936 // Sanity check that pooled sessions haven't gathered anything yet.
1937 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1938 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1939 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1940 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1941 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001942 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001943 EXPECT_TRUE_SIMULATED_WAIT(
1944 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1945 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1946 ep2_ch1()->writable(),
1947 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001948 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001949 // Make sure the P2PTransportChannels are actually using ports from the
1950 // pooled sessions.
1951 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1952 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1953 EXPECT_NE(pooled_ports_1.end(),
1954 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001955 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001956 EXPECT_NE(pooled_ports_2.end(),
1957 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001958 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001959}
1960
1961// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1962// PortAllocatorSession that already finished gathering candidates.
1963TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001964 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001965 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1966 kDefaultPortAllocatorFlags);
1967 // First create a pooled session for each endpoint.
1968 auto& allocator_1 = GetEndpoint(0)->allocator_;
1969 auto& allocator_2 = GetEndpoint(1)->allocator_;
1970 int pool_size = 1;
1971 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001972 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001973 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001974 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001975 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001976 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001977 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001978 allocator_2->GetPooledSession();
1979 ASSERT_NE(nullptr, pooled_session_1);
1980 ASSERT_NE(nullptr, pooled_session_2);
1981 // Wait for the pooled sessions to finish gathering before the
1982 // P2PTransportChannels try to use them.
Honghai Zhang161a5862016-10-20 11:47:02 -07001983 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
1984 pooled_session_2->CandidatesAllocationDone(),
1985 kDefaultTimeout, clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001986 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001987 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001988 EXPECT_TRUE_SIMULATED_WAIT(
1989 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1990 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1991 ep2_ch1()->writable(),
1992 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001993 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001994 // Make sure the P2PTransportChannels are actually using ports from the
1995 // pooled sessions.
1996 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1997 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1998 EXPECT_NE(pooled_ports_1.end(),
1999 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002000 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002001 EXPECT_NE(pooled_ports_2.end(),
2002 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002003 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002004}
2005
deadbeef14f97f52016-06-22 17:14:15 -07002006// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07002007// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07002008// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07002009// TODO(deadbeef): Move this and other "presumed writable" tests into a test
2010// class that operates on a single P2PTransportChannel, once an appropriate one
2011// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07002012TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
2013 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2014 kDefaultPortAllocatorFlags);
2015 // Only configure one channel so we can control when the remote candidate
2016 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002017 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2018 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07002019 IceConfig config;
2020 config.presume_writable_when_fully_relayed = true;
2021 ep1_ch1()->SetIceConfig(config);
2022 ep1_ch1()->MaybeStartGathering();
2023 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2024 ep1_ch1()->gathering_state(), kDefaultTimeout);
2025 // Add two remote candidates; a host candidate (with higher priority)
2026 // and TURN candidate.
2027 ep1_ch1()->AddRemoteCandidate(
2028 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2029 ep1_ch1()->AddRemoteCandidate(
2030 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2031 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2032 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07002033 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002034 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2035 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2036 // Also expect that the channel instantly indicates that it's writable since
2037 // it has a TURN-TURN pair.
2038 EXPECT_TRUE(ep1_ch1()->writable());
2039 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002040 // Also make sure we can immediately send packets.
2041 const char* data = "test";
2042 int len = static_cast<int>(strlen(data));
2043 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07002044}
2045
Taylor Brandstetteref184702016-06-23 17:35:47 -07002046// Test that a TURN/peer reflexive candidate pair is also presumed writable.
2047TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
2048 rtc::ScopedFakeClock fake_clock;
2049
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002050 // We need to add artificial network delay to verify that the connection
2051 // is presumed writable before it's actually writable. Without this delay
2052 // it would become writable instantly.
2053 virtual_socket_server()->set_delay_mean(50);
2054 virtual_socket_server()->UpdateDelayDistribution();
2055
Taylor Brandstetteref184702016-06-23 17:35:47 -07002056 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2057 kDefaultPortAllocatorFlags);
2058 // We want the remote TURN candidate to show up as prflx. To do this we need
2059 // to configure the server to accept packets from an address we haven't
2060 // explicitly installed permission for.
2061 test_turn_server()->set_enable_permission_checks(false);
2062 IceConfig config;
2063 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002064 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2065 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2066 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2067 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07002068 ep1_ch1()->SetIceConfig(config);
2069 ep2_ch1()->SetIceConfig(config);
2070 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2071 // candidate as peer reflexive.
2072 PauseCandidates(1);
2073 ep1_ch1()->MaybeStartGathering();
2074 ep2_ch1()->MaybeStartGathering();
2075
2076 // Wait for the TURN<->prflx connection.
2077 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002078 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002079 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2080 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2081 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2082 // Make sure that at this point the connection is only presumed writable,
2083 // not fully writable.
2084 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2085
2086 // Now wait for it to actually become writable.
Honghai Zhang161a5862016-10-20 11:47:02 -07002087 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2088 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002089
2090 // Explitly destroy channels, before fake clock is destroyed.
2091 DestroyChannels();
2092}
2093
deadbeef14f97f52016-06-22 17:14:15 -07002094// Test that a presumed-writable TURN<->TURN connection is preferred above an
2095// unreliable connection (one that has failed to be pinged for some time).
2096TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
2097 rtc::ScopedFakeClock fake_clock;
2098
2099 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2100 kDefaultPortAllocatorFlags);
2101 IceConfig config;
2102 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002103 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2104 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2105 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2106 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07002107 ep1_ch1()->SetIceConfig(config);
2108 ep2_ch1()->SetIceConfig(config);
2109 ep1_ch1()->MaybeStartGathering();
2110 ep2_ch1()->MaybeStartGathering();
2111 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07002112 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2113 ep1_ch1()->selected_connection()->writable() &&
2114 ep2_ch1()->receiving() &&
2115 ep2_ch1()->writable() &&
2116 ep2_ch1()->selected_connection()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002117 kShortTimeout, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002118 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07002119 // Destroy the second channel and wait for the current connection on the
2120 // first channel to become "unreliable", making it no longer writable.
2121 GetEndpoint(1)->cd1_.ch_.reset();
Honghai Zhang161a5862016-10-20 11:47:02 -07002122 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2123 fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002124 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002125 // Add a remote TURN candidate. The first channel should still have a TURN
2126 // port available to make a TURN<->TURN pair that's presumed writable.
2127 ep1_ch1()->AddRemoteCandidate(
2128 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2129 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2130 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2131 EXPECT_TRUE(ep1_ch1()->writable());
2132 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07002133 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002134 // Explitly destroy channels, before fake clock is destroyed.
2135 DestroyChannels();
2136}
2137
deadbeefdd7fb432016-09-30 15:16:48 -07002138// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2139// writable" connection. Previously this did not work.
2140TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
2141 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2142 kDefaultPortAllocatorFlags);
2143 // Only test one endpoint, so we can ensure the connection doesn't receive a
2144 // binding response and advance beyond being "presumed" writable.
2145 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2146 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2147 IceConfig config;
2148 config.presume_writable_when_fully_relayed = true;
2149 ep1_ch1()->SetIceConfig(config);
2150 ep1_ch1()->MaybeStartGathering();
2151 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2152 ep1_ch1()->gathering_state(), kDefaultTimeout);
2153 ep1_ch1()->AddRemoteCandidate(
2154 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2155 // Sanity checking the type of the connection.
2156 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
2157 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2158 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2159
2160 // Tell the socket server to block packets (returning EWOULDBLOCK).
2161 virtual_socket_server()->SetSendingBlocked(true);
2162 const char* data = "test";
2163 int len = static_cast<int>(strlen(data));
2164 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2165
2166 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2167 // should.
2168 GetEndpoint(0)->ready_to_send_ = false;
2169 virtual_socket_server()->SetSendingBlocked(false);
2170 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2171 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2172}
2173
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002174// Test what happens when we have 2 users behind the same NAT. This can lead
2175// to interesting behavior because the STUN server will only give out the
2176// address of the outermost NAT.
2177class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2178 protected:
2179 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
kwibergee89e782017-08-09 17:22:01 -07002180 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2181 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002182 rtc::NATSocketServer::Translator* outer_nat =
2183 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
2184 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
2185 ConfigureEndpoint(outer_nat, 0, config1);
2186 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002187 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002188 }
2189 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
2190 int endpoint, Config config) {
nissec8ee8822017-01-18 07:20:55 -08002191 RTC_CHECK(config <= NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002192 if (config == OPEN) {
2193 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2194 nat->AddClient(kPrivateAddrs[endpoint]);
2195 } else {
2196 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2197 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
2198 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
2199 kCascadedPrivateAddrs[endpoint]);
2200 }
2201 }
2202};
2203
2204TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2205 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002206 Test(
2207 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002208}
2209
2210// Test what happens when we have multiple available pathways.
2211// In the future we will try different RTTs and configs for the different
2212// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2213class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002214 public:
honghaiz7252a002016-11-08 20:04:09 -08002215 const Connection* GetConnectionWithRemoteAddress(
2216 P2PTransportChannel* channel,
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002217 const SocketAddress& address) {
honghaiz7252a002016-11-08 20:04:09 -08002218 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002219 if (conn->remote_candidate().address().EqualIPs(address)) {
2220 return conn;
2221 }
2222 }
2223 return nullptr;
2224 }
2225
honghaiz7252a002016-11-08 20:04:09 -08002226 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2227 const SocketAddress& address) {
2228 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002229 if (conn->local_candidate().address().EqualIPs(address)) {
2230 return conn;
2231 }
2232 }
2233 return nullptr;
2234 }
2235
honghaiz7252a002016-11-08 20:04:09 -08002236 Connection* GetConnection(P2PTransportChannel* channel,
2237 const SocketAddress& local,
2238 const SocketAddress& remote) {
2239 for (Connection* conn : channel->connections()) {
2240 if (conn->local_candidate().address().EqualIPs(local) &&
2241 conn->remote_candidate().address().EqualIPs(remote)) {
2242 return conn;
2243 }
2244 }
2245 return nullptr;
2246 }
2247
2248 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2249 const Connection* selected_connection = channel->selected_connection();
2250 for (Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002251 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002252 conn->Destroy();
2253 }
2254 }
2255 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002256};
2257
2258// Test that we can establish connectivity when both peers are multihomed.
zhihuanga3095d02016-11-10 13:59:46 -08002259TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002260 AddAddress(0, kPublicAddrs[0]);
2261 AddAddress(0, kAlternateAddrs[0]);
2262 AddAddress(1, kPublicAddrs[1]);
2263 AddAddress(1, kAlternateAddrs[1]);
2264 Test(kLocalUdpToLocalUdp);
2265}
2266
Honghai Zhang52dce732016-03-31 12:37:31 -07002267// Test that we can quickly switch links if an interface goes down.
2268// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002269TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002270 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002271 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002272 // Simulate failing over from Wi-Fi to cell interface.
2273 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2274 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002275
2276 // Use only local ports for simplicity.
2277 SetAllocatorFlags(0, kOnlyLocalPorts);
2278 SetAllocatorFlags(1, kOnlyLocalPorts);
2279
deadbeefb60a8192016-08-24 15:15:00 -07002280 // Make the receiving timeout shorter for testing.
2281 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002282 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002283 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002284
honghaiz9ad0db52016-07-14 19:30:28 -07002285 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2286 ep2_ch1()->receiving() &&
2287 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002288 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002289 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2290 ep2_ch1()->selected_connection() &&
2291 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2292 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002293
2294 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002295 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002296 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002297 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002298 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2299 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002300 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002301 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002302 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002303 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002304
honghaiz9ad0db52016-07-14 19:30:28 -07002305 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002306 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002307 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2308 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002309 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002310 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2311 EXPECT_TRUE(
2312 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2313 EXPECT_TRUE(
2314 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2315
2316 DestroyChannels();
2317}
2318
Honghai Zhang52dce732016-03-31 12:37:31 -07002319// Test that we can quickly switch links if an interface goes down.
2320// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002321TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002322 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002323 // Simulate failing over from Wi-Fi to cell interface.
2324 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2325 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiza58ea782015-09-24 08:13:36 -07002326 AddAddress(1, kPublicAddrs[1]);
2327
2328 // Use only local ports for simplicity.
2329 SetAllocatorFlags(0, kOnlyLocalPorts);
2330 SetAllocatorFlags(1, kOnlyLocalPorts);
2331
deadbeefb60a8192016-08-24 15:15:00 -07002332 // Make the receiving timeout shorter for testing.
2333 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002334 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002335 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002336 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2337 ep2_ch1()->receiving() &&
2338 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002339 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002340 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2341 ep2_ch1()->selected_connection() &&
2342 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2343 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002344
2345 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002346 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002347 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002348 // The selected connections will switch, so keep references to them.
2349 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2350 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002351 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002352 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002353 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002354 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002355
honghaiz9ad0db52016-07-14 19:30:28 -07002356 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002357 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002358 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2359 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002360 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002361 EXPECT_TRUE(
2362 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
2363 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2364 EXPECT_TRUE(
2365 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002366
2367 DestroyChannels();
2368}
2369
honghaiz7252a002016-11-08 20:04:09 -08002370// Tests that we can quickly switch links if an interface goes down when
2371// there are many connections.
2372TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2373 rtc::ScopedFakeClock clock;
2374 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
2375 RelayServerConfig turn_server(RELAY_TURN);
2376 turn_server.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08002377 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
honghaiz7252a002016-11-08 20:04:09 -08002378 GetAllocator(0)->AddTurnServer(turn_server);
2379 GetAllocator(1)->AddTurnServer(turn_server);
2380 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08002381 SetAllocatorFlags(
2382 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2383 SetAllocatorFlags(
2384 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002385 SetAllocationStepDelay(0, kMinimumStepDelay);
2386 SetAllocationStepDelay(1, kMinimumStepDelay);
2387
2388 auto& wifi = kPublicAddrs;
2389 auto& cellular = kAlternateAddrs;
2390 auto& wifiIpv6 = kIPv6PublicAddrs;
2391 auto& cellularIpv6 = kIPv6AlternateAddrs;
2392 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2393 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2394 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2395 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2396 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2397 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2398 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2399 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2400
2401 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2402 // will be created in time.
2403 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2404 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2405 virtual_socket_server()->set_delay_mean(500);
2406 virtual_socket_server()->UpdateDelayDistribution();
2407
2408 // Make the receiving timeout shorter for testing.
2409 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2410 // Create channels and let them go writable, as usual.
2411 CreateChannels(config, config, true /* ice_renomination */);
2412 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2413 ep2_ch1()->receiving() &&
2414 ep2_ch1()->writable(),
2415 kMediumTimeout, clock);
2416 EXPECT_TRUE_SIMULATED_WAIT(
2417 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
2418 LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
2419 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
2420 kMediumTimeout, clock);
2421
2422 // Blackhole any traffic to or from the wifi on endpoint 1.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002423 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz7252a002016-11-08 20:04:09 -08002424 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2425 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2426
2427 // The selected connections may switch, so keep references to them.
2428 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2429 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2430 EXPECT_TRUE_SIMULATED_WAIT(
2431 !selected_connection1->receiving() && !selected_connection2->receiving(),
2432 kMediumTimeout, clock);
2433
2434 // Per-network best connections will be pinged at relatively higher rate when
2435 // the selected connection becomes not receiving.
2436 Connection* per_network_best_connection1 =
2437 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2438 ASSERT_NE(nullptr, per_network_best_connection1);
2439 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2440 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2441 EXPECT_TRUE_SIMULATED_WAIT(
2442 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2443 kMediumTimeout, clock);
2444 int64_t ping_interval1 =
2445 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2446 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2447 constexpr int SCHEDULING_DELAY = 200;
2448 EXPECT_LT(
2449 ping_interval1,
2450 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2451
2452 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2453 // it timed out on writing.
2454 EXPECT_TRUE_SIMULATED_WAIT(
2455 ep1_ch1()->selected_connection()->receiving() &&
2456 ep2_ch1()->selected_connection()->receiving() &&
2457 RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
2458 LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
2459 kMediumTimeout, clock);
2460
2461 DestroyChannels();
2462}
2463
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002464// Test that when the controlling side switches the selected connection,
2465// the nomination of the selected connection on the controlled side will
2466// increase.
2467TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2468 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002469 // Simulate failing over from Wi-Fi to cell interface.
2470 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2471 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002472 AddAddress(1, kPublicAddrs[1]);
2473
2474 // Use only local ports for simplicity.
2475 SetAllocatorFlags(0, kOnlyLocalPorts);
2476 SetAllocatorFlags(1, kOnlyLocalPorts);
2477
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002478 // We want it to set the remote ICE parameters when creating channels.
2479 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002480 // Make the receiving timeout shorter for testing.
2481 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002482 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002483 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002484 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2485 ep2_ch1()->receiving() &&
2486 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002487 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002488 EXPECT_TRUE_SIMULATED_WAIT(
2489 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2490 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2491 kDefaultTimeout, clock);
2492 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2493 Connection* selected_connection2 =
2494 const_cast<Connection*>(ep2_ch1()->selected_connection());
2495 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2496 // |selected_connection2| should not be nominated any more since the previous
2497 // nomination has been acknowledged.
2498 ConnectSignalNominated(selected_connection2);
Honghai Zhang161a5862016-10-20 11:47:02 -07002499 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002500 EXPECT_FALSE(nominated());
2501
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002502 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002503 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002504 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2505
2506 // The selected connection on the controlling side should switch.
2507 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002508 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2509 clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002510 // The connection on the controlled side should be nominated again
2511 // and have an increased nomination.
2512 EXPECT_TRUE_SIMULATED_WAIT(
2513 ep2_ch1()->selected_connection()->remote_nomination() >
2514 remote_nomination2,
2515 kDefaultTimeout, clock);
2516
2517 DestroyChannels();
2518}
2519
honghaiz9ad0db52016-07-14 19:30:28 -07002520// Test that if an interface fails temporarily and then recovers quickly,
2521// the selected connection will not switch.
2522// The case that it will switch over to the backup connection if the selected
2523// connection does not recover after enough time is covered in
2524// TestFailoverControlledSide and TestFailoverControllingSide.
2525TEST_F(P2PTransportChannelMultihomedTest,
2526 TestConnectionSwitchDampeningControlledSide) {
2527 rtc::ScopedFakeClock clock;
2528 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002529 // Simulate failing over from Wi-Fi to cell interface.
2530 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2531 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002532
2533 // Use only local ports for simplicity.
2534 SetAllocatorFlags(0, kOnlyLocalPorts);
2535 SetAllocatorFlags(1, kOnlyLocalPorts);
2536
2537 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002538 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002539
2540 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2541 ep2_ch1()->receiving() &&
2542 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002543 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002544 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2545 ep2_ch1()->selected_connection() &&
2546 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2547 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2548
2549 // Make the receiving timeout shorter for testing.
2550 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2551 ep1_ch1()->SetIceConfig(config);
2552 ep2_ch1()->SetIceConfig(config);
2553 reset_selected_candidate_pair_switches();
2554
2555 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002556 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002557 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2558
2559 // The selected connections may switch, so keep references to them.
2560 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2561 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2562 // We should detect loss of receiving within 1 second or so.
2563 EXPECT_TRUE_SIMULATED_WAIT(
2564 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002565 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002566 // After a short while, the link recovers itself.
2567 SIMULATED_WAIT(false, 10, clock);
2568 fw()->ClearRules();
2569
2570 // We should remain on the public address on both sides and no connection
2571 // switches should have happened.
2572 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2573 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002574 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002575 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2576 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2577 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2578
2579 DestroyChannels();
2580}
2581
2582// Test that if an interface fails temporarily and then recovers quickly,
2583// the selected connection will not switch.
2584TEST_F(P2PTransportChannelMultihomedTest,
2585 TestConnectionSwitchDampeningControllingSide) {
2586 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002587 // Simulate failing over from Wi-Fi to cell interface.
2588 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2589 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002590 AddAddress(1, kPublicAddrs[1]);
2591
2592 // Use only local ports for simplicity.
2593 SetAllocatorFlags(0, kOnlyLocalPorts);
2594 SetAllocatorFlags(1, kOnlyLocalPorts);
2595
2596 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002597 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002598 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2599 ep2_ch1()->receiving() &&
2600 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002601 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002602 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2603 ep2_ch1()->selected_connection() &&
2604 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2605 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2606
2607 // Make the receiving timeout shorter for testing.
2608 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2609 ep1_ch1()->SetIceConfig(config);
2610 ep2_ch1()->SetIceConfig(config);
2611 reset_selected_candidate_pair_switches();
2612
2613 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002614 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002615 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2616 // The selected connections may switch, so keep references to them.
2617 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2618 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2619 // We should detect loss of receiving within 1 second or so.
2620 EXPECT_TRUE_SIMULATED_WAIT(
2621 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002622 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002623 // The link recovers after a short while.
2624 SIMULATED_WAIT(false, 10, clock);
2625 fw()->ClearRules();
2626
2627 // We should not switch to the alternate addr on both sides because of the
2628 // dampening.
2629 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2630 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002631 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002632 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2633 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2634 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2635 DestroyChannels();
2636}
2637
Honghai Zhangfd16da22016-08-17 16:12:46 -07002638// Tests that if the remote side's network failed, it won't cause the local
2639// side to switch connections and networks.
2640TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2641 rtc::ScopedFakeClock clock;
2642 // The interface names are chosen so that |cellular| would have higher
2643 // candidate priority and higher cost.
2644 auto& wifi = kPublicAddrs;
2645 auto& cellular = kAlternateAddrs;
2646 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2647 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2648 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2649
2650 // Use only local ports for simplicity.
2651 SetAllocatorFlags(0, kOnlyLocalPorts);
2652 SetAllocatorFlags(1, kOnlyLocalPorts);
2653 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002654 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002655 // Make the receiving timeout shorter for testing.
2656 // Set the backup connection ping interval to 25s.
2657 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2658 // Ping the best connection more frequently since we don't have traffic.
2659 config.stable_writable_connection_ping_interval = 900;
2660 ep1_ch1()->SetIceConfig(config);
2661 ep2_ch1()->SetIceConfig(config);
2662 // Need to wait to make sure the connections on both networks are writable.
2663 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2664 ep2_ch1()->receiving() &&
2665 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002666 kMediumTimeout, clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002667 EXPECT_TRUE_SIMULATED_WAIT(
2668 ep1_ch1()->selected_connection() &&
2669 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2670 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2671 kDefaultTimeout, clock);
2672 Connection* backup_conn =
2673 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2674 ASSERT_NE(nullptr, backup_conn);
2675 // After a short while, the backup connection will be writable but not
2676 // receiving because backup connection is pinged at a slower rate.
2677 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002678 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
2679 clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002680 reset_selected_candidate_pair_switches();
2681 // Blackhole any traffic to or from the remote WiFi networks.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002682 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhangfd16da22016-08-17 16:12:46 -07002683 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2684
2685 int num_switches = 0;
2686 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2687 20000, clock);
2688 EXPECT_EQ(0, num_switches);
2689 DestroyChannels();
2690}
2691
honghaize1a0c942016-02-16 14:54:56 -08002692// Tests that a Wifi-Wifi connection has the highest precedence.
2693TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2694 // The interface names are chosen so that |cellular| would have higher
2695 // candidate priority if it is not for the network type.
2696 auto& wifi = kAlternateAddrs;
2697 auto& cellular = kPublicAddrs;
2698 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2699 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2700 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2701 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2702
2703 // Use only local ports for simplicity.
2704 SetAllocatorFlags(0, kOnlyLocalPorts);
2705 SetAllocatorFlags(1, kOnlyLocalPorts);
2706
2707 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002708 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002709
2710 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2711 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2712 1000, 1000);
2713 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002714 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002715 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2716 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2717 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002718 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002719 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2720 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2721 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002722 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002723}
2724
2725// Tests that a Wifi-Cellular connection has higher precedence than
2726// a Cellular-Cellular connection.
2727TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2728 // The interface names are chosen so that |cellular| would have higher
2729 // candidate priority if it is not for the network type.
2730 auto& wifi = kAlternateAddrs;
2731 auto& cellular = kPublicAddrs;
2732 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2733 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2734 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2735
2736 // Use only local ports for simplicity.
2737 SetAllocatorFlags(0, kOnlyLocalPorts);
2738 SetAllocatorFlags(1, kOnlyLocalPorts);
2739
2740 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002741 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002742
2743 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2744 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2745 1000, 1000);
2746 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002747 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002748 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2749 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002750 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002751 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2752 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002753 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002754}
2755
Honghai Zhang381b4212015-12-04 12:24:03 -08002756// Test that the backup connection is pinged at a rate no faster than
2757// what was configured.
2758TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2759 AddAddress(0, kPublicAddrs[0]);
2760 // Adding alternate address will make sure |kPublicAddrs| has the higher
2761 // priority than others. This is due to FakeNetwork::AddInterface method.
2762 AddAddress(1, kAlternateAddrs[1]);
2763 AddAddress(1, kPublicAddrs[1]);
2764
2765 // Use only local ports for simplicity.
2766 SetAllocatorFlags(0, kOnlyLocalPorts);
2767 SetAllocatorFlags(1, kOnlyLocalPorts);
2768
2769 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002770 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002771 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2772 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2773 1000, 1000);
2774 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002775 ep2_ch1()->SetIceConfig(
2776 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002777 // After the state becomes COMPLETED, the backup connection will be pinged
2778 // once every |backup_ping_interval| milliseconds.
zhihuangd06adf62017-01-12 15:58:31 -08002779 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
2780 1000);
deadbeef14f97f52016-06-22 17:14:15 -07002781 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002782 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002783 Connection* backup_conn = connections[1];
Honghai Zhang161a5862016-10-20 11:47:02 -07002784 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
honghaiz34b11eb2016-03-16 08:55:44 -07002785 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002786 EXPECT_TRUE_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002787 last_ping_response_ms < backup_conn->last_ping_response_received(),
2788 kDefaultTimeout);
Honghai Zhang381b4212015-12-04 12:24:03 -08002789 int time_elapsed =
2790 backup_conn->last_ping_response_received() - last_ping_response_ms;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002791 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
Honghai Zhang381b4212015-12-04 12:24:03 -08002792 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002793
2794 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002795}
2796
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002797TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002798 rtc::ScopedFakeClock clock;
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002799 AddAddress(0, kAlternateAddrs[0]);
2800 AddAddress(0, kPublicAddrs[0]);
2801 AddAddress(1, kPublicAddrs[1]);
2802 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002803 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002804
2805 // Both transport channels will reach STATE_COMPLETED quickly.
zhihuangd06adf62017-01-12 15:58:31 -08002806 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002807 ep1_ch1()->GetState(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08002808 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002809 ep2_ch1()->GetState(), kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002810}
2811
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002812// Tests that when a network interface becomes inactive, if Continual Gathering
2813// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002814// will be removed from the port list of the channel, and the respective
2815// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002816TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002817 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002818 AddAddress(0, kPublicAddrs[0]);
2819 AddAddress(1, kPublicAddrs[1]);
2820 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07002821 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
2822 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07002823 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08002824
2825 SetAllocatorFlags(0, kOnlyLocalPorts);
2826 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002827 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2828 ep2_ch1()->receiving() &&
2829 ep2_ch1()->writable(),
2830 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002831 // More than one port has been created.
2832 EXPECT_LE(1U, ep1_ch1()->ports().size());
2833 // Endpoint 1 enabled continual gathering; the port will be removed
2834 // when the interface is removed.
2835 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002836 EXPECT_TRUE(ep1_ch1()->ports().empty());
2837 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002838 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2839 clock);
honghaize3c6c822016-02-17 13:00:28 -08002840
2841 size_t num_ports = ep2_ch1()->ports().size();
2842 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002843 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002844 // Endpoint 2 did not enable continual gathering; the local port will still be
2845 // removed when the interface is removed but the remote candidates on the
2846 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002847 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002848
2849 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2850 clock);
2851 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002852 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002853
2854 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002855}
2856
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002857// Tests that continual gathering will create new connections when a new
2858// interface is added.
2859TEST_F(P2PTransportChannelMultihomedTest,
2860 TestContinualGatheringOnNewInterface) {
2861 auto& wifi = kAlternateAddrs;
2862 auto& cellular = kPublicAddrs;
2863 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2864 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002865 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002866 IceConfig continual_gathering_config =
2867 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07002868 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002869 SetAllocatorFlags(0, kOnlyLocalPorts);
2870 SetAllocatorFlags(1, kOnlyLocalPorts);
2871 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2872 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2873 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002874
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002875 // Add a new wifi interface on end point 2. We should expect a new connection
2876 // to be created and the new one will be the best connection.
2877 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002878 const Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002879 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002880 conn->remote_candidate().address().EqualIPs(wifi[1]),
2881 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002882 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002883 conn->local_candidate().address().EqualIPs(wifi[1]),
2884 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002885
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002886 // Add a new cellular interface on end point 1, we should expect a new
2887 // backup connection created using this new interface.
2888 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002889 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002890 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002891 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2892 nullptr &&
2893 conn != ep1_ch1()->selected_connection() && conn->writable(),
2894 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002895 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002896 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002897 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
2898 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002899 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002900 kDefaultTimeout);
2901
2902 DestroyChannels();
2903}
2904
2905// Tests that we can switch links via continual gathering.
2906TEST_F(P2PTransportChannelMultihomedTest,
2907 TestSwitchLinksViaContinualGathering) {
2908 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002909 AddAddress(0, kPublicAddrs[0]);
2910 AddAddress(1, kPublicAddrs[1]);
2911 // Use only local ports for simplicity.
2912 SetAllocatorFlags(0, kOnlyLocalPorts);
2913 SetAllocatorFlags(1, kOnlyLocalPorts);
2914
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002915 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002916 IceConfig continual_gathering_config =
2917 CreateIceConfig(1000, GATHER_CONTINUALLY);
2918 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002919 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002920 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2921 ep2_ch1()->receiving() &&
2922 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002923 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002924 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07002925 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002926 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2927 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2928
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002929 // Add the new address first and then remove the other one.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002930 RTC_LOG(LS_INFO) << "Draining...";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002931 AddAddress(1, kAlternateAddrs[1]);
2932 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002933 // We should switch to use the alternate address after an exchange of pings.
2934 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002935 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002936 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2937 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002938 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002939
2940 // Remove one address first and then add another address.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002941 RTC_LOG(LS_INFO) << "Draining again...";
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002942 RemoveAddress(1, kAlternateAddrs[1]);
2943 AddAddress(1, kAlternateAddrs[0]);
2944 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002945 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002946 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2947 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002948 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002949
2950 DestroyChannels();
2951}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002952
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002953/*
2954TODO(honghaiz) Once continual gathering fully supports
2955GATHER_CONTINUALLY_AND_RECOVER, put this test back.
2956
2957// Tests that if the backup connections are lost and then the interface with the
2958// selected connection is gone, continual gathering will restore the
2959// connectivity.
2960TEST_F(P2PTransportChannelMultihomedTest,
2961 TestBackupConnectionLostThenInterfaceGone) {
2962 rtc::ScopedFakeClock clock;
2963 auto& wifi = kAlternateAddrs;
2964 auto& cellular = kPublicAddrs;
2965 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2966 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2967 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2968 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2969 // Use only local ports for simplicity.
2970 SetAllocatorFlags(0, kOnlyLocalPorts);
2971 SetAllocatorFlags(1, kOnlyLocalPorts);
2972
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002973 // Set continual gathering policy.
2974 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER);
deadbeefb60a8192016-08-24 15:15:00 -07002975 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002976 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002977 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2978 ep2_ch1()->receiving() && ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002979 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002980 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2981 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002982 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2983 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2984
2985 // First destroy all backup connection.
2986 DestroyAllButBestConnection(ep1_ch1());
2987
2988 SIMULATED_WAIT(false, 10, clock);
2989 // Then the interface of the best connection goes away.
2990 RemoveAddress(0, wifi[0]);
2991 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002992 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002993 LocalCandidate(ep1_ch1())->address().EqualIPs(cellular[0]) &&
2994 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002995 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002996
2997 DestroyChannels();
2998}
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002999*/
3000
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003001// Tests that the backup connection will be restored after it is destroyed.
3002TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3003 rtc::ScopedFakeClock clock;
3004 auto& wifi = kAlternateAddrs;
3005 auto& cellular = kPublicAddrs;
3006 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3007 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3008 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3009 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3010 // Use only local ports for simplicity.
3011 SetAllocatorFlags(0, kOnlyLocalPorts);
3012 SetAllocatorFlags(1, kOnlyLocalPorts);
3013
3014 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003015 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01003016 config.regather_on_failed_networks_interval = 2000;
johan02bd5122016-09-20 00:23:27 -07003017 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003018 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3019 ep2_ch1()->receiving() &&
3020 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003021 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003022 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3023 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003024 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
3025 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
3026
3027 // Destroy all backup connections.
3028 DestroyAllButBestConnection(ep1_ch1());
3029 // Ensure the backup connection is removed first.
3030 EXPECT_TRUE_SIMULATED_WAIT(
3031 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3032 kDefaultTimeout, clock);
honghaiz7252a002016-11-08 20:04:09 -08003033 const Connection* conn;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003034 EXPECT_TRUE_SIMULATED_WAIT(
3035 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3036 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003037 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003038 kDefaultTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003039
3040 DestroyChannels();
3041}
3042
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003043// A collection of tests which tests a single P2PTransportChannel by sending
3044// pings.
3045class P2PTransportChannelPingTest : public testing::Test,
3046 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003047 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003048 P2PTransportChannelPingTest()
deadbeef98e186c2017-05-16 18:00:06 -07003049 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003050
3051 protected:
deadbeef14f97f52016-06-22 17:14:15 -07003052 void PrepareChannel(P2PTransportChannel* ch) {
3053 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003054 ch->SetIceParameters(kIceParams[0]);
3055 ch->SetRemoteIceParameters(kIceParams[1]);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003056 ch->SignalNetworkRouteChanged.connect(
3057 this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07003058 ch->SignalReadyToSend.connect(this,
3059 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07003060 ch->SignalStateChanged.connect(
3061 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003062 }
3063
deadbeef14f97f52016-06-22 17:14:15 -07003064 Connection* WaitForConnectionTo(P2PTransportChannel* ch,
3065 const std::string& ip,
Honghai Zhange05bcc22016-08-16 18:19:14 -07003066 int port_num,
3067 rtc::FakeClock* clock = nullptr) {
3068 if (clock == nullptr) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003069 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3070 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003071 } else {
3072 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003073 kMediumTimeout, *clock);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003074 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003075 return GetConnectionTo(ch, ip, port_num);
3076 }
3077
sprang716978d2016-10-11 06:43:28 -07003078 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003079 if (ch->ports().empty()) {
3080 return nullptr;
3081 }
deadbeef14f97f52016-06-22 17:14:15 -07003082 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003083 }
3084
Honghai Zhanga74363c2016-07-28 18:06:15 -07003085 Port* GetPrunedPort(P2PTransportChannel* ch) {
3086 if (ch->pruned_ports().empty()) {
3087 return nullptr;
3088 }
3089 return static_cast<Port*>(ch->pruned_ports()[0]);
3090 }
3091
deadbeef14f97f52016-06-22 17:14:15 -07003092 Connection* GetConnectionTo(P2PTransportChannel* ch,
3093 const std::string& ip,
3094 int port_num) {
sprang716978d2016-10-11 06:43:28 -07003095 Port* port = GetPort(ch);
3096 if (!port) {
3097 return nullptr;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003098 }
sprang716978d2016-10-11 06:43:28 -07003099 return port->GetConnection(rtc::SocketAddress(ip, port_num));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003100 }
3101
deadbeef14f97f52016-06-22 17:14:15 -07003102 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3103 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08003104 if (conn) {
3105 ch->MarkConnectionPinged(conn);
3106 }
3107 return conn;
3108 }
3109
Steve Antone9324572017-11-29 10:18:21 -08003110 int SendData(IceTransportInternal* channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07003111 const char* data,
3112 size_t len,
3113 int packet_id) {
3114 rtc::PacketOptions options;
3115 options.packet_id = packet_id;
Steve Antone9324572017-11-29 10:18:21 -08003116 return channel->SendPacket(data, len, options, 0);
Honghai Zhang52dce732016-03-31 12:37:31 -07003117 }
3118
Steve Antone9324572017-11-29 10:18:21 -08003119 Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
3120 rtc::ScopedFakeClock* clock,
Honghai Zhang572b0942016-06-23 12:26:57 -07003121 const std::string& ip_addr,
3122 int port,
3123 int priority,
3124 bool writable) {
Steve Antone9324572017-11-29 10:18:21 -08003125 channel->AddRemoteCandidate(
Honghai Zhang572b0942016-06-23 12:26:57 -07003126 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3127 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antone9324572017-11-29 10:18:21 -08003128 GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
3129 *clock);
3130 Connection* conn = GetConnectionTo(channel, ip_addr, port);
Honghai Zhang572b0942016-06-23 12:26:57 -07003131
3132 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003133 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07003134 }
3135 return conn;
3136 }
3137
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003138 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3139 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07003140 conn->SignalNominated(conn);
3141 }
3142
Zhi Huang942bc2e2017-11-13 13:26:07 -08003143 void OnNetworkRouteChanged(rtc::Optional<rtc::NetworkRoute> network_route) {
3144 last_network_route_ = network_route;
3145 if (last_network_route_) {
3146 last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
3147 }
Honghai Zhang572b0942016-06-23 12:26:57 -07003148 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07003149 }
3150
deadbeef14f97f52016-06-22 17:14:15 -07003151 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07003152 const std::string& remote_ufrag,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003153 int priority,
3154 uint32_t nomination = 0) {
deadbeef14f97f52016-06-22 17:14:15 -07003155 IceMessage msg;
3156 msg.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003157 msg.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
deadbeef14f97f52016-06-22 17:14:15 -07003158 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07003159 conn->local_candidate().username() + ":" + remote_ufrag));
zsteinf42cc9d2017-03-27 16:17:19 -07003160 msg.AddAttribute(
3161 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003162 if (nomination != 0) {
zsteinf42cc9d2017-03-27 16:17:19 -07003163 msg.AddAttribute(rtc::MakeUnique<StunUInt32Attribute>(
3164 STUN_ATTR_NOMINATION, nomination));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003165 }
deadbeef14f97f52016-06-22 17:14:15 -07003166 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07003167 msg.AddMessageIntegrity(conn->local_candidate().password());
3168 msg.AddFingerprint();
3169 rtc::ByteBufferWriter buf;
3170 msg.Write(&buf);
3171 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
3172 }
3173
deadbeef5bd5ca32017-02-10 11:31:50 -08003174 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07003175 channel_ready_to_send_ = true;
3176 }
zhihuangd06adf62017-01-12 15:58:31 -08003177 void OnChannelStateChanged(IceTransportInternal* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07003178 channel_state_ = channel->GetState();
3179 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003180
Honghai Zhang52dce732016-03-31 12:37:31 -07003181 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003182 bool channel_ready_to_send() { return channel_ready_to_send_; }
3183 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
zhihuangd06adf62017-01-12 15:58:31 -08003184 IceTransportState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07003185 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07003186 int switches = selected_candidate_pair_switches_;
3187 selected_candidate_pair_switches_ = 0;
3188 return switches;
3189 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003190
Zhi Huang942bc2e2017-11-13 13:26:07 -08003191 // Return true if the |pair| matches the last network route.
3192 bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
3193 if (!pair) {
3194 return !last_network_route_.has_value();
3195 } else {
3196 return pair->local_candidate().network_id() ==
3197 last_network_route_->local_network_id &&
3198 pair->remote_candidate().network_id() ==
3199 last_network_route_->remote_network_id;
3200 }
3201 }
3202
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003203 private:
kwiberg3ec46792016-04-27 07:22:53 -07003204 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -07003205 rtc::AutoSocketServerThread thread_;
Honghai Zhang572b0942016-06-23 12:26:57 -07003206 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07003207 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07003208 bool channel_ready_to_send_ = false;
zhihuangd06adf62017-01-12 15:58:31 -08003209 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
Zhi Huang942bc2e2017-11-13 13:26:07 -08003210 rtc::Optional<rtc::NetworkRoute> last_network_route_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003211};
3212
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003213TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07003214 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3215 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003216 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003217 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003218 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3219 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003220
deadbeef14f97f52016-06-22 17:14:15 -07003221 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3222 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003223 ASSERT_TRUE(conn1 != nullptr);
3224 ASSERT_TRUE(conn2 != nullptr);
3225
3226 // Before a triggered check, the first connection to ping is the
3227 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08003228 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003229
3230 // Receiving a ping causes a triggered check which should make conn1
3231 // be pinged first instead of conn2, even though conn2 has a higher
3232 // priority.
3233 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08003234 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003235}
3236
honghaiz524ecc22016-05-25 12:48:31 -07003237TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07003238 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3239 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07003240 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07003241 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003242 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3243 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07003244
deadbeef14f97f52016-06-22 17:14:15 -07003245 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3246 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07003247 ASSERT_TRUE(conn1 != nullptr);
3248 ASSERT_TRUE(conn2 != nullptr);
3249
3250 // Low-priority connection becomes writable so that the other connection
3251 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003252 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07003253 EXPECT_TRUE_WAIT(
3254 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3255 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3256 kDefaultTimeout);
3257}
3258
zhihuang435264a2016-06-21 11:28:38 -07003259// Verify that the connections are pinged at the right time.
3260TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
3261 rtc::ScopedFakeClock clock;
3262 int RTT_RATIO = 4;
3263 int SCHEDULING_RANGE = 200;
3264 int RTT_RANGE = 10;
3265
deadbeef14f97f52016-06-22 17:14:15 -07003266 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3267 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07003268 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07003269 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003270 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3271 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003272
3273 ASSERT_TRUE(conn != nullptr);
3274 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3275
3276 // Initializing.
3277
3278 int64_t start = clock.TimeNanos();
3279 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3280 kDefaultTimeout, clock);
3281 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3282 rtc::kNumNanosecsPerMillisec /
3283 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003284 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003285
3286 // Stabilizing.
3287
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003288 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003289 int ping_sent_before = conn->num_pings_sent();
3290 start = clock.TimeNanos();
3291 // The connection becomes strong but not stable because we haven't been able
3292 // to converge the RTT.
Honghai Zhang161a5862016-10-20 11:47:02 -07003293 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3294 clock);
zhihuang435264a2016-06-21 11:28:38 -07003295 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003296 EXPECT_GE(ping_interval_ms,
3297 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3298 EXPECT_LE(
3299 ping_interval_ms,
3300 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003301
3302 // Stabilized.
3303
3304 // The connection becomes stable after receiving more than RTT_RATIO rtt
3305 // samples.
3306 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003307 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003308 }
3309 ping_sent_before = conn->num_pings_sent();
3310 start = clock.TimeNanos();
Honghai Zhang161a5862016-10-20 11:47:02 -07003311 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3312 clock);
zhihuang435264a2016-06-21 11:28:38 -07003313 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003314 EXPECT_GE(ping_interval_ms,
3315 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3316 EXPECT_LE(
3317 ping_interval_ms,
3318 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003319
3320 // Destabilized.
3321
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003322 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003323 // Create a in-flight ping.
3324 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3325 start = clock.TimeNanos();
3326 // In-flight ping timeout and the connection will be unstable.
3327 SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003328 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3329 kMediumTimeout, clock);
zhihuang435264a2016-06-21 11:28:38 -07003330 int64_t duration_ms =
3331 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3332 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3333 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3334 // The connection become unstable due to not receiving ping responses.
3335 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003336 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3337 clock);
zhihuang435264a2016-06-21 11:28:38 -07003338 // The interval is expected to be
honghaiz7252a002016-11-08 20:04:09 -08003339 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
zhihuang435264a2016-06-21 11:28:38 -07003340 start = clock.TimeNanos();
3341 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003342 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3343 clock);
zhihuang435264a2016-06-21 11:28:38 -07003344 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003345 EXPECT_GE(ping_interval_ms,
3346 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3347 EXPECT_LE(
3348 ping_interval_ms,
3349 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003350}
3351
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003352// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003353// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003354TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3355 rtc::ScopedFakeClock clock;
3356
3357 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3358 P2PTransportChannel ch("TestChannel", 1, &pa);
3359 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003360 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003361 ch.MaybeStartGathering();
3362 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3363 kDefaultTimeout);
3364
3365 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003366 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003367 IceMessage request;
3368 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003369 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3370 STUN_ATTR_USERNAME, kIceUfrag[1]));
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003371 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3372 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003373 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003374 Port* port = GetPort(&ch);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003375 ASSERT_NE(nullptr, port);
3376 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3377 &request, kIceUfrag[1], false);
3378 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3379 ASSERT_NE(nullptr, conn);
3380
3381 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003382 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003383 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3384 EXPECT_EQ(0, conn->num_pings_sent());
3385
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003386 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003387 // the first ping is sent as soon as possible, within one simulated clock
3388 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003389 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003390 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3391}
3392
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003393TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003394 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3395 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003396 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003397 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003398 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3399 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003400
deadbeef14f97f52016-06-22 17:14:15 -07003401 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3402 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003403 ASSERT_TRUE(conn1 != nullptr);
3404 ASSERT_TRUE(conn2 != nullptr);
3405
guoweis36f01372016-03-02 18:02:40 -08003406 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3407 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003408 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003409 ASSERT_TRUE(conn1->writable());
3410 conn1->ReceivedPing();
3411
3412 // Ping received, but the connection is already writable, so no
3413 // "triggered check" and conn2 is pinged before conn1 because it has
3414 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003415 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003416}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003417
honghaiz079a7a12016-06-22 16:26:29 -07003418TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003419 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3420 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003421 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003422 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003423 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003424
deadbeef14f97f52016-06-22 17:14:15 -07003425 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003426 ASSERT_TRUE(conn1 != nullptr);
3427
3428 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3429 conn1->Prune(); // A pruned connection may still be pingable.
3430 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3431 conn1->FailAndPrune();
3432 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3433}
3434
Honghai Zhang1590c392016-05-24 13:15:02 -07003435TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003436 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3437 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003438 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003439 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003440 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3441 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003442 ASSERT_TRUE(conn1 != nullptr);
3443 // Pruning the connection reduces the set of active connections and changes
3444 // the channel state.
3445 conn1->Prune();
zhihuangd06adf62017-01-12 15:58:31 -08003446 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3447 kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003448}
3449
honghaiza54a0802015-12-16 18:37:23 -08003450// Test adding remote candidates with different ufrags. If a remote candidate
3451// is added with an old ufrag, it will be discarded. If it is added with a
3452// ufrag that was not seen before, it will be used to create connections
3453// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003454// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003455// ufrag, its pwd and generation will be set properly.
3456TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003457 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3458 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003459 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003460 ch.MaybeStartGathering();
3461 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003462 ch.AddRemoteCandidate(
3463 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3464 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003465 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003466 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003467 EXPECT_EQ(kIceUfrag[2], candidate.username());
3468 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003469 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003470
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003471 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003472 // This should set the ICE pwd in the remote candidate of |conn1|, making
3473 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003474 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003475 EXPECT_EQ(kIceUfrag[2], candidate.username());
3476 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003477 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003478
3479 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003480 ch.AddRemoteCandidate(
3481 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003482 rtc::Thread::Current()->ProcessMessages(500);
3483 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3484
3485 // Add a candidate with the current ufrag, its pwd and generation will be
3486 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003487 ch.AddRemoteCandidate(
3488 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3489 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003490 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003491 kMediumTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07003492 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003493 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3494 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003495
3496 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003497 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003498 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3499 candidate.username() == kIceUfrag[2]);
3500 if (candidate.username() == kIceUfrag[1]) {
3501 EXPECT_EQ(kIcePwd[1], candidate.password());
3502 } else if (candidate.username() == kIceUfrag[2]) {
3503 EXPECT_EQ(kIcePwd[2], candidate.password());
3504 }
3505 }
honghaiza54a0802015-12-16 18:37:23 -08003506}
3507
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003508TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003509 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3510 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003511 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003512 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003513
3514 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003515 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3516 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003517 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003518 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003519
3520 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003521 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003522 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3523 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003524 ASSERT_TRUE(conn2 != nullptr);
3525 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003526 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003527
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003528 // Wait for conn1 to be pruned.
Honghai Zhang161a5862016-10-20 11:47:02 -07003529 EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003530 // Destroy the connection to test SignalUnknownAddress.
3531 conn1->Destroy();
honghaize58d73d2016-10-24 16:38:26 -07003532 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
3533 kMediumTimeout);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003534
3535 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003536 IceMessage request;
3537 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003538 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3539 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003540 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3541 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003542 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003543 EXPECT_NE(prflx_priority, remote_priority);
3544
sprang716978d2016-10-11 06:43:28 -07003545 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003546 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003547 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3548 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003549 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3550 ASSERT_TRUE(conn1 != nullptr);
3551 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3552
3553 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003554 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3555 &request, kIceUfrag[1], false);
3556 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003557 ASSERT_TRUE(conn3 != nullptr);
3558 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3559}
Peter Thatcher54360512015-07-08 11:08:35 -07003560
3561TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
honghaize58d73d2016-10-24 16:38:26 -07003562 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003563 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3564 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003565 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003566 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003567 // small.
3568 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003569 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003570 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Peter Thatcher54360512015-07-08 11:08:35 -07003571 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003572 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003573 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003574 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaize58d73d2016-10-24 16:38:26 -07003575 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003576 ASSERT_TRUE(conn1 != nullptr);
3577
honghaize58d73d2016-10-24 16:38:26 -07003578 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Peter Thatcher54360512015-07-08 11:08:35 -07003579 conn1->ReceivedPing();
3580 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
honghaize58d73d2016-10-24 16:38:26 -07003581 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
3582 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003583}
honghaiz5a3acd82015-08-20 15:53:17 -07003584
Honghai Zhang572b0942016-06-23 12:26:57 -07003585// The controlled side will select a connection as the "selected connection"
3586// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003587// point the controlled side will select that connection as the
Zhi Huang942bc2e2017-11-13 13:26:07 -08003588// "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
Honghai Zhang572b0942016-06-23 12:26:57 -07003589// selected connection changes and SignalReadyToSend will be fired if the new
3590// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003591TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003592 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3593 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003594 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003595 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003596 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003597 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3598 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003599 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003600 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003601 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003602 int last_packet_id = 0;
3603 const char* data = "ABCDEFGH";
3604 int len = static_cast<int>(strlen(data));
Steve Antone9324572017-11-29 10:18:21 -08003605 EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003606 EXPECT_EQ(-1, last_sent_packet_id());
3607
3608 // A connection needs to be writable before it is selected for transmission.
3609 conn1->ReceivedPingResponse(LOW_RTT, "id");
3610 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003611 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Steve Antone9324572017-11-29 10:18:21 -08003612 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003613
honghaiz5a3acd82015-08-20 15:53:17 -07003614 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003615 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003616 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3617 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003618 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003619 conn2->ReceivedPingResponse(LOW_RTT, "id");
3620 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003621 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003622 EXPECT_TRUE(channel_ready_to_send());
3623 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003624
3625 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003626 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003627 // its priority is lower.
Steve Antone9324572017-11-29 10:18:21 -08003628 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003629 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3630 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003631 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003632 // Because it has a lower priority, the selected connection is still conn2.
3633 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003634 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003635 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003636 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003637 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003638 EXPECT_EQ(conn3, ch.selected_connection());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003639 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003640 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003641 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003642
Honghai Zhang572b0942016-06-23 12:26:57 -07003643 // Even if another higher priority candidate arrives, it will not be set as
3644 // the selected connection because the selected connection is nominated by
3645 // the controlling side.
Steve Antone9324572017-11-29 10:18:21 -08003646 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003647 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3648 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003649 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003650 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003651 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003652 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003653 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003654 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003655 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003656 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003657 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003658 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003659 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003660 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
Honghai Zhang52dce732016-03-31 12:37:31 -07003661 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003662 // SignalReadyToSend is fired again because conn4 is writable.
3663 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003664}
3665
Honghai Zhang572b0942016-06-23 12:26:57 -07003666// The controlled side will select a connection as the "selected connection"
3667// based on requests from an unknown address before the controlling side
3668// nominates a connection, and will nominate a connection from an unknown
3669// address if the request contains the use_candidate attribute. Plus, it will
3670// also sends back a ping response and set the ICE pwd in the remote candidate
3671// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003672TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003673 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3674 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003675 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003676 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003677 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003678 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003679 IceMessage request;
3680 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003681 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3682 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003683 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3684 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003685 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003686 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
deadbeef14f97f52016-06-22 17:14:15 -07003687 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3688 &request, kIceUfrag[1], false);
3689 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003690 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003691 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003692 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003693 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003694 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003695 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003696
3697 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003698 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3699 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003700 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003701 // Because it has a lower priority, the selected connection is still conn1.
3702 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003703 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003704 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003705 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3706 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003707 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003708
Honghai Zhang572b0942016-06-23 12:26:57 -07003709 // Another request with unknown address, it will not be set as the selected
3710 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003711 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003712 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3713 &request, kIceUfrag[1], false);
3714 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003715 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003716 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003717 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003718 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003719 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003720
3721 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003722 // selected as the selected connection.
zsteinf42cc9d2017-03-27 16:17:19 -07003723 request.AddAttribute(
3724 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
deadbeef14f97f52016-06-22 17:14:15 -07003725 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3726 &request, kIceUfrag[1], false);
3727 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003728 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003729 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003730 // conn4 is not the selected connection yet because it is not writable.
3731 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003732 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003733 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003734
3735 // Test that the request from an unknown address contains a ufrag from an old
3736 // generation.
3737 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003738 ch.SetRemoteIceParameters(kIceParams[2]);
3739 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003740 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3741 &request, kIceUfrag[2], false);
3742 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003743 ASSERT_TRUE(conn5 != nullptr);
3744 EXPECT_TRUE(port->sent_binding_response());
3745 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003746}
3747
Honghai Zhang572b0942016-06-23 12:26:57 -07003748// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003749// based on media received until the controlling side nominates a connection,
3750// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003751// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003752TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003753 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3754 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003755 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003756 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003757 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003758 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3759 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003760 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003761 conn1->ReceivedPingResponse(LOW_RTT, "id");
3762 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003763
Honghai Zhang572b0942016-06-23 12:26:57 -07003764 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003765 // switch to conn2 because the controlled side must mirror the media path
3766 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003767 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3768 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003769 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003770 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003771 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003772 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003773 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003774
3775 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003776 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003777 IceMessage request;
3778 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003779 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3780 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003781 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3782 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003783 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
3784 request.AddAttribute(
3785 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
sprang716978d2016-10-11 06:43:28 -07003786 Port* port = GetPort(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003787 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3788 &request, kIceUfrag[1], false);
3789 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003790 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003791 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003792 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003793 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003794
Honghai Zhang572b0942016-06-23 12:26:57 -07003795 // Now another data packet will not switch the selected connection because the
3796 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003797 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003798 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz5a3acd82015-08-20 15:53:17 -07003799 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003800 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3801}
3802
3803TEST_F(P2PTransportChannelPingTest,
3804 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3805 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003806 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003807 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3808 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3809 PrepareChannel(&ch);
3810 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003811 ch.MaybeStartGathering();
3812 // The connections have decreasing priority.
3813 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003814 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003815 ASSERT_TRUE(conn1 != nullptr);
3816 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003817 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003818 ASSERT_TRUE(conn2 != nullptr);
3819
3820 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003821 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003822 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003823
3824 // conn2 receives data; it becomes selected.
3825 // Advance the clock by 1ms so that the last data receiving timestamp of
3826 // conn2 is larger.
3827 SIMULATED_WAIT(false, 1, clock);
3828 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003829 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003830 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003831
3832 // conn1 also receives data; it becomes selected due to priority again.
3833 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
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(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003836
Honghai Zhange05bcc22016-08-16 18:19:14 -07003837 // conn2 received data more recently; it is selected now because it
3838 // received data more recently.
3839 SIMULATED_WAIT(false, 1, clock);
3840 // Need to become writable again because it was pruned.
3841 conn2->ReceivedPingResponse(LOW_RTT, "id");
3842 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3843 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003844 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003845
Honghai Zhang572b0942016-06-23 12:26:57 -07003846 // Make sure sorting won't reselect candidate pair.
3847 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003848 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003849}
3850
3851TEST_F(P2PTransportChannelPingTest,
3852 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3853 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003854 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003855
3856 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3857 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3858 PrepareChannel(&ch);
3859 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003860 ch.MaybeStartGathering();
3861 // The connections have decreasing priority.
3862 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003863 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003864 ASSERT_TRUE(conn1 != nullptr);
3865 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003866 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003867 ASSERT_TRUE(conn2 != nullptr);
3868
3869 // conn1 received data; it is the selected connection.
3870 // Advance the clock to have a non-zero last-data-receiving time.
3871 SIMULATED_WAIT(false, 1, clock);
3872 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003873 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003874 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003875
3876 // conn2 is nominated; it becomes the selected connection.
3877 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003878 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003879 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003880
Honghai Zhange05bcc22016-08-16 18:19:14 -07003881 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07003882 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003883 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003884 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003885
Honghai Zhang572b0942016-06-23 12:26:57 -07003886 // Make sure sorting won't reselect candidate pair.
3887 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003888 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003889}
3890
3891TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003892 TestControlledAgentSelectsConnectionWithHigherNomination) {
3893 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003894 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003895
3896 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3897 P2PTransportChannel ch("test", 1, &pa);
3898 PrepareChannel(&ch);
3899 ch.SetIceRole(ICEROLE_CONTROLLED);
3900 ch.MaybeStartGathering();
3901 // The connections have decreasing priority.
3902 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003903 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003904 ASSERT_TRUE(conn1 != nullptr);
3905 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003906 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003907 ASSERT_TRUE(conn2 != nullptr);
3908
3909 // conn1 is the selected connection because it has a higher priority,
Zhi Huang942bc2e2017-11-13 13:26:07 -08003910 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
3911 clock);
3912 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003913 reset_selected_candidate_pair_switches();
3914
3915 // conn2 is nominated; it becomes selected.
3916 NominateConnection(conn2);
3917 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003918 EXPECT_EQ(conn2, ch.selected_connection());
3919 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003920
3921 // conn1 is selected because of its priority.
3922 NominateConnection(conn1);
3923 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003924 EXPECT_EQ(conn1, ch.selected_connection());
3925 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003926
3927 // conn2 gets higher remote nomination; it is selected again.
3928 NominateConnection(conn2, 2U);
3929 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003930 EXPECT_EQ(conn2, ch.selected_connection());
3931 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003932
3933 // Make sure sorting won't reselect candidate pair.
3934 SIMULATED_WAIT(false, 100, clock);
3935 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3936}
3937
3938TEST_F(P2PTransportChannelPingTest,
3939 TestControlledAgentIgnoresSmallerNomination) {
3940 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003941 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
3942
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003943 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3944 P2PTransportChannel ch("test", 1, &pa);
3945 PrepareChannel(&ch);
3946 ch.SetIceRole(ICEROLE_CONTROLLED);
3947 ch.MaybeStartGathering();
3948 Connection* conn =
Steve Antone9324572017-11-29 10:18:21 -08003949 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003950 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
3951 EXPECT_EQ(2U, conn->remote_nomination());
3952 // Smaller nomination is ignored.
3953 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
3954 EXPECT_EQ(2U, conn->remote_nomination());
3955}
3956
3957TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07003958 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3959 rtc::ScopedFakeClock clock;
3960
3961 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3962 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3963 PrepareChannel(&ch);
3964 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003965 ch.MaybeStartGathering();
3966 // The connections have decreasing priority.
3967 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003968 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07003969 ASSERT_TRUE(conn1 != nullptr);
3970 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003971 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07003972 ASSERT_TRUE(conn2 != nullptr);
3973
3974 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003975 // There is no selected connection because no connection is writable.
3976 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003977
3978 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003979 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003980 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003981 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003982 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
3983 clock);
3984 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003985
3986 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003987 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003988 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003989 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003990 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
3991 clock);
3992 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003993
3994 // Make sure sorting won't reselect candidate pair.
3995 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003996 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07003997}
honghaiz89374372015-09-24 13:14:47 -07003998
honghaiz36f50e82016-06-01 15:57:03 -07003999// Test that if a new remote candidate has the same address and port with
4000// an old one, it will be used to create a new connection.
4001TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07004002 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4003 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07004004 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07004005 ch.MaybeStartGathering();
4006 const std::string host_address = "1.1.1.1";
4007 const int port_num = 1;
4008
4009 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07004010 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4011 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07004012 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004013 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004014 ASSERT_TRUE(conn1 != nullptr);
4015 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4016
4017 // Simply adding the same candidate again won't create a new connection.
4018 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004019 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004020 EXPECT_EQ(conn1, conn2);
4021
4022 // Update the ufrag of the candidate and add it again.
4023 candidate.set_username(kIceUfrag[2]);
4024 ch.AddRemoteCandidate(candidate);
4025 conn2 = GetConnectionTo(&ch, host_address, port_num);
4026 EXPECT_NE(conn1, conn2);
4027 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4028 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4029
4030 // Verify that a ping with the new ufrag can be received on the new
4031 // connection.
4032 EXPECT_EQ(0, conn2->last_ping_received());
4033 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
Steve Antone9324572017-11-29 10:18:21 -08004034 EXPECT_GT(conn2->last_ping_received(), 0);
honghaiz36f50e82016-06-01 15:57:03 -07004035}
4036
Honghai Zhang572b0942016-06-23 12:26:57 -07004037// When the current selected connection is strong, lower-priority connections
4038// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07004039TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004040 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07004041 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004042 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4043 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07004044 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004045 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07004046 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004047 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4048 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07004049 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004050 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004051 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07004052
4053 // When a higher-priority, nominated candidate comes in, the connections with
4054 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07004055 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004056 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07004057 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004058 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4059 NominateConnection(conn2);
Honghai Zhang161a5862016-10-20 11:47:02 -07004060 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004061
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004062 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07004063 // Wait until conn2 becomes not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004064 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004065
deadbeef14f97f52016-06-22 17:14:15 -07004066 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004067 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07004068 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07004069 // The selected connection should still be conn2. Even through conn3 has lower
4070 // priority and is not receiving/writable, it is not pruned because the
4071 // selected connection is not receiving.
honghaize58d73d2016-10-24 16:38:26 -07004072 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004073 EXPECT_FALSE(conn3->pruned());
4074}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004075
Honghai Zhang572b0942016-06-23 12:26:57 -07004076TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4077 rtc::ScopedFakeClock clock;
4078 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4079 P2PTransportChannel ch("test channel", 1, &pa);
4080 PrepareChannel(&ch);
4081 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004082 ch.MaybeStartGathering();
4083 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004084 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004085 ASSERT_TRUE(conn1 != nullptr);
4086 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004087 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004088 ASSERT_TRUE(conn2 != nullptr);
4089 // Even if conn1 is writable, nominated, receiving data, it should not prune
4090 // conn2.
4091 NominateConnection(conn1);
4092 SIMULATED_WAIT(false, 1, clock);
4093 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
4094 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4095 EXPECT_FALSE(conn2->pruned());
4096}
4097
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004098// Test that GetState returns the state correctly.
4099TEST_F(P2PTransportChannelPingTest, TestGetState) {
honghaize58d73d2016-10-24 16:38:26 -07004100 rtc::ScopedFakeClock clock;
4101 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004102 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4103 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004104 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004105 ch.MaybeStartGathering();
zhihuangd06adf62017-01-12 15:58:31 -08004106 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
deadbeef14f97f52016-06-22 17:14:15 -07004107 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4108 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004109 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4110 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004111 ASSERT_TRUE(conn1 != nullptr);
4112 ASSERT_TRUE(conn2 != nullptr);
4113 // Now there are two connections, so the transport channel is connecting.
zhihuangd06adf62017-01-12 15:58:31 -08004114 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004115 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004116 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaize58d73d2016-10-24 16:38:26 -07004117 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004118 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004119 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08004120 // Need to wait until the channel state is updated.
zhihuangd06adf62017-01-12 15:58:31 -08004121 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
honghaize58d73d2016-10-24 16:38:26 -07004122 kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004123}
4124
4125// Test that when a low-priority connection is pruned, it is not deleted
4126// right away, and it can become active and be pruned again.
4127TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004128 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07004129 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
4130
deadbeef14f97f52016-06-22 17:14:15 -07004131 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4132 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004133 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07004134 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01004135 config.receiving_switching_delay = 800;
honghaiz9ad0db52016-07-14 19:30:28 -07004136 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004137 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004138 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004139 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004140 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004141 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004142 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07004143 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4144 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004145
4146 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07004147 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004148 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07004149 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004150 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004151 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004152 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004153 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004154 // |conn2| should not send a ping yet.
hbos06495bc2017-01-02 08:08:18 -08004155 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
zhihuangd06adf62017-01-12 15:58:31 -08004156 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004157 // Wait for |conn1| becoming not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004158 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004159 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07004160 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004161 ASSERT_TRUE(conn2 != nullptr);
hbos06495bc2017-01-02 08:08:18 -08004162 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
Honghai Zhange05bcc22016-08-16 18:19:14 -07004163 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004164 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004165 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4166 clock);
zhihuangd06adf62017-01-12 15:58:31 -08004167 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004168
4169 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004170 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004171 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4172 clock);
4173 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004174 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004175}
honghaiz77d0d6e2015-10-27 11:34:45 -07004176
4177// Test that if all connections in a channel has timed out on writing, they
4178// will all be deleted. We use Prune to simulate write_time_out.
4179TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
honghaize58d73d2016-10-24 16:38:26 -07004180 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07004181 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4182 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07004183 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07004184 ch.MaybeStartGathering();
4185 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07004186 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
honghaize58d73d2016-10-24 16:38:26 -07004187 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004188 ASSERT_TRUE(conn1 != nullptr);
4189 conn1->ReceivedPing(); // Becomes receiving
4190 conn1->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004191 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004192
4193 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07004194 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004195 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004196 ASSERT_TRUE(conn2 != nullptr);
4197 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07004198 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
honghaize58d73d2016-10-24 16:38:26 -07004199 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004200 ASSERT_TRUE(conn3 != nullptr);
4201 conn3->ReceivedPing(); // Becomes receiving
4202 // Now prune both conn2 and conn3; they will be deleted soon.
4203 conn2->Prune();
4204 conn3->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004205 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004206}
honghaiz9b669572015-11-04 12:07:44 -08004207
Honghai Zhang5a246372016-05-02 17:28:35 -07004208// Tests that after a port allocator session is started, it will be stopped
4209// when a new connection becomes writable and receiving. Also tests that if a
4210// connection belonging to an old session becomes writable, it won't stop
4211// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08004212TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07004213 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4214 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08004215 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004216 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08004217 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004218 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4219 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08004220 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004221 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004222 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4223
Honghai Zhang5a246372016-05-02 17:28:35 -07004224 // Start a new session. Even though conn1, which belongs to an older
4225 // session, becomes unwritable and writable again, it should not stop the
4226 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004227 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08004228 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07004229 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004230 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07004231 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4232
4233 // But if a new connection created from the new session becomes writable,
4234 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07004235 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4236 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08004237 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004238 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004239 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4240}
guoweis36f01372016-03-02 18:02:40 -08004241
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004242// Test that the ICE role is updated even on ports that has been removed.
4243// These ports may still have connections that need a correct role, in case that
4244// the connections on it may still receive stun pings.
4245TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07004246 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4247 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004248 // Starts with ICEROLE_CONTROLLING.
4249 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004250 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07004251 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07004252 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004253 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004254
deadbeef14f97f52016-06-22 17:14:15 -07004255 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004256 ASSERT_TRUE(conn != nullptr);
4257
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004258 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4259 // change the ICE role and expect it to be updated.
4260 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07004261 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07004262 ch.SetIceRole(ICEROLE_CONTROLLED);
4263 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004264}
4265
4266// Test that the ICE role is updated even on ports with inactive networks.
4267// These ports may still have connections that need a correct role, for the
4268// pings sent by those connections until they're replaced by newer-generation
4269// connections.
4270TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07004271 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4272 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004273 // Starts with ICEROLE_CONTROLLING.
4274 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07004275 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004276 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004277
deadbeef14f97f52016-06-22 17:14:15 -07004278 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004279 ASSERT_TRUE(conn != nullptr);
4280
4281 // Do an ICE restart, change the role, and expect the old port to have its
4282 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004283 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07004284 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004285 ch.SetIceRole(ICEROLE_CONTROLLED);
4286 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004287}
4288
4289// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07004290// will be destroyed. The port will only be destroyed after it is marked as
4291// "pruned."
4292TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07004293 rtc::ScopedFakeClock fake_clock;
4294
deadbeef14f97f52016-06-22 17:14:15 -07004295 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4296 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004297 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004298 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07004299 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004300 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004301
deadbeef14f97f52016-06-22 17:14:15 -07004302 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004303 ASSERT_TRUE(conn != nullptr);
4304
4305 // Simulate 2 minutes going by. This should be enough time for the port to
4306 // time out.
4307 for (int second = 0; second < 120; ++second) {
4308 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
4309 }
4310 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004311 // Port will not be removed because it is not pruned yet.
sprang716978d2016-10-11 06:43:28 -07004312 PortInterface* port = GetPort(&ch);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004313 ASSERT_NE(nullptr, port);
4314
4315 // If the session prunes all ports, the port will be destroyed.
4316 ch.allocator_session()->PruneAllPorts();
sprang716978d2016-10-11 06:43:28 -07004317 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004318 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004319}
4320
guoweis36f01372016-03-02 18:02:40 -08004321class P2PTransportChannelMostLikelyToWorkFirstTest
4322 : public P2PTransportChannelPingTest {
4323 public:
4324 P2PTransportChannelMostLikelyToWorkFirstTest()
4325 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4326 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004327 allocator_.reset(
4328 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4329 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004330 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4331 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004332 allocator_->set_step_delay(kMinimumStepDelay);
4333 }
4334
deadbeef14f97f52016-06-22 17:14:15 -07004335 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004336 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004337 int stable_writable_connection_ping_interval) {
deadbeef49f34fd2016-12-06 16:22:06 -08004338 channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
deadbeef14f97f52016-06-22 17:14:15 -07004339 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004340 config.prioritize_most_likely_candidate_pairs =
4341 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004342 config.stable_writable_connection_ping_interval =
4343 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004344 channel_->SetIceConfig(config);
4345 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004346 channel_->MaybeStartGathering();
4347 return *channel_.get();
4348 }
4349
deadbeef14f97f52016-06-22 17:14:15 -07004350 BasicPortAllocator* allocator() { return allocator_.get(); }
4351 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004352
4353 // This verifies the next pingable connection has the expected candidates'
4354 // types and, for relay local candidate, the expected relay protocol and ping
4355 // it.
4356 void VerifyNextPingableConnection(
4357 const std::string& local_candidate_type,
4358 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004359 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4360 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004361 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004362 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004363 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4364 }
4365 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4366 }
4367
guoweis36f01372016-03-02 18:02:40 -08004368 private:
deadbeef14f97f52016-06-22 17:14:15 -07004369 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004370 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004371 TestTurnServer turn_server_;
4372 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004373};
4374
4375// Test that Relay/Relay connections will be pinged first when no other
4376// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004377// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004378TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4379 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08004380 const int max_strong_interval = 100;
deadbeef14f97f52016-06-22 17:14:15 -07004381 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
Honghai Zhang161a5862016-10-20 11:47:02 -07004382 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004383 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4384 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004385
deadbeef14f97f52016-06-22 17:14:15 -07004386 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4387 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004388
Honghai Zhang161a5862016-10-20 11:47:02 -07004389 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004390
4391 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004392 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4393 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4394 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004395
4396 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004397 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4398 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4399 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004400 conn2->ReceivedPing();
4401 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4402
Honghai Zhang572b0942016-06-23 12:26:57 -07004403 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004404 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4405 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4406 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004407 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004408 ASSERT_TRUE(conn3->writable());
4409 conn3->ReceivedPing();
4410
honghaiz524ecc22016-05-25 12:48:31 -07004411 /*
4412
4413 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4414 the flakiness. The following test becomes flaky because we now ping the
4415 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004416 times. The selected connection may have been pinged before
4417 |max_strong_interval|, so it may not be the next connection to be pinged as
4418 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004419
Honghai Zhang572b0942016-06-23 12:26:57 -07004420 // Verify that conn3 will be the "selected connection" since it is readable
4421 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004422 // pingable connection.
Honghai Zhang161a5862016-10-20 11:47:02 -07004423 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004424 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004425 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004426 ASSERT_TRUE(conn3->writable());
4427 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004428
4429 */
guoweis36f01372016-03-02 18:02:40 -08004430}
4431
4432// Test that Relay/Relay connections will be pinged first when everything has
4433// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4434// in the first round.
4435TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4436 TestRelayRelayFirstWhenEverythingPinged) {
deadbeef14f97f52016-06-22 17:14:15 -07004437 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004438 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004439 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4440 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004441
deadbeef14f97f52016-06-22 17:14:15 -07004442 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004443 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004444
4445 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004446 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4447 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004448
4449 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004450 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004451 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004452
4453 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004454 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004455
4456 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004457 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004458
4459 // Now, every connection has been pinged once. The next one should be
4460 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004461 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004462}
4463
4464// Test that when we receive a new remote candidate, they will be tried first
4465// before we re-ping Relay/Relay connections again.
4466TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4467 TestNoStarvationOnNonRelayConnection) {
deadbeef14f97f52016-06-22 17:14:15 -07004468 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004469 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004470 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4471 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004472
deadbeef14f97f52016-06-22 17:14:15 -07004473 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004474 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004475
4476 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004477 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004478
4479 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004480 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004481
4482 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004483 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004484 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004485
4486 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004487 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004488
4489 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004490 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004491
4492 // Now, every connection has been pinged once. The next one should be
4493 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004494 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004495}
4496
4497// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4498// followed by the rest.
4499TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4500 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004501 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
4502 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08004503 config.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08004504 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
guoweis36f01372016-03-02 18:02:40 -08004505 allocator()->AddTurnServer(config);
4506
deadbeef14f97f52016-06-22 17:14:15 -07004507 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004508 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004509 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4510 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4511 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004512
4513 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004514 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004515 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004516
4517 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004518 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004519
4520 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004521 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4522 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004523
4524 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004525 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004526}
deadbeef14f97f52016-06-22 17:14:15 -07004527
Steve Antone9324572017-11-29 10:18:21 -08004528} // namespace cricket