blob: 62fddb2b581bbe57ae56380c2afa9f1b1bf36af3 [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>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
13
Honghai Zhangd93f50c2016-10-05 11:47:22 -070014#include "webrtc/api/fakemetricsobserver.h"
ossu7bb87ee2017-01-23 04:56:25 -080015#include "webrtc/p2p/base/fakeportallocator.h"
zsteinf42cc9d2017-03-27 16:17:19 -070016#include "webrtc/p2p/base/icetransportinternal.h"
ossu7bb87ee2017-01-23 04:56:25 -080017#include "webrtc/p2p/base/p2ptransportchannel.h"
deadbeef5bd5ca32017-02-10 11:31:50 -080018#include "webrtc/p2p/base/packettransportinternal.h"
ossu7bb87ee2017-01-23 04:56:25 -080019#include "webrtc/p2p/base/testrelayserver.h"
20#include "webrtc/p2p/base/teststunserver.h"
21#include "webrtc/p2p/base/testturnserver.h"
22#include "webrtc/p2p/client/basicportallocator.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020023#include "webrtc/rtc_base/checks.h"
24#include "webrtc/rtc_base/dscp.h"
25#include "webrtc/rtc_base/fakeclock.h"
26#include "webrtc/rtc_base/fakenetwork.h"
27#include "webrtc/rtc_base/firewallsocketserver.h"
28#include "webrtc/rtc_base/gunit.h"
29#include "webrtc/rtc_base/helpers.h"
30#include "webrtc/rtc_base/logging.h"
31#include "webrtc/rtc_base/natserver.h"
32#include "webrtc/rtc_base/natsocketfactory.h"
33#include "webrtc/rtc_base/proxyserver.h"
34#include "webrtc/rtc_base/ptr_util.h"
35#include "webrtc/rtc_base/socketaddress.h"
36#include "webrtc/rtc_base/ssladapter.h"
37#include "webrtc/rtc_base/thread.h"
38#include "webrtc/rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039
deadbeef14f97f52016-06-22 17:14:15 -070040namespace {
41
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042using rtc::SocketAddress;
43
deadbeef14f97f52016-06-22 17:14:15 -070044// Default timeout for tests in this file.
45// Should be large enough for slow buildbots to run the tests reliably.
46static const int kDefaultTimeout = 10000;
Honghai Zhang161a5862016-10-20 11:47:02 -070047static const int kMediumTimeout = 3000;
48static const int kShortTimeout = 1000;
deadbeef14f97f52016-06-22 17:14:15 -070049
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
51 cricket::PORTALLOCATOR_DISABLE_RELAY |
52 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070053static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054// Addresses on the public internet.
55static const SocketAddress kPublicAddrs[2] =
56 { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
57// IPv6 Addresses on the public internet.
58static const SocketAddress kIPv6PublicAddrs[2] = {
59 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
honghaiz7252a002016-11-08 20:04:09 -080060 SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000061// For configuring multihomed clients.
Honghai Zhangfd16da22016-08-17 16:12:46 -070062static const SocketAddress kAlternateAddrs[2] = {
63 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
honghaiz7252a002016-11-08 20:04:09 -080064static const SocketAddress kIPv6AlternateAddrs[2] = {
65 SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
66 SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
deadbeeff137e972017-03-23 15:45:49 -070067// Addresses for HTTP proxy servers.
68static const SocketAddress kHttpsProxyAddrs[2] =
69 { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
70// Addresses for SOCKS proxy servers.
71static const SocketAddress kSocksProxyAddrs[2] =
72 { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073// Internal addresses for NAT boxes.
74static const SocketAddress kNatAddrs[2] =
75 { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
76// Private addresses inside the NAT private networks.
77static const SocketAddress kPrivateAddrs[2] =
78 { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
79// For cascaded NATs, the internal addresses of the inner NAT boxes.
80static const SocketAddress kCascadedNatAddrs[2] =
81 { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
82// For cascaded NATs, private addresses inside the inner private networks.
83static const SocketAddress kCascadedPrivateAddrs[2] =
84 { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
85// The address of the public STUN server.
86static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000087// The addresses for the public turn server.
Honghai Zhangb73d2692016-09-29 22:46:09 -070088static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000089 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -080090static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
91 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000092static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
93static const cricket::RelayCredentials kRelayCredentials("test", "test");
94
95// Based on ICE_UFRAG_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070096const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097// Based on ICE_PWD_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070098const char* kIcePwd[4] = {
99 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
100 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
101const cricket::IceParameters kIceParams[4] = {
102 {kIceUfrag[0], kIcePwd[0], false},
103 {kIceUfrag[1], kIcePwd[1], false},
104 {kIceUfrag[2], kIcePwd[2], false},
105 {kIceUfrag[3], kIcePwd[3], false}};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000106
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700107const uint64_t kLowTiebreaker = 11111;
108const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700110enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000111
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700112cricket::IceConfig CreateIceConfig(
113 int receiving_timeout,
114 cricket::ContinualGatheringPolicy continual_gathering_policy,
115 int backup_ping_interval = -1) {
honghaiz1f429e32015-09-28 07:57:34 -0700116 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800117 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700118 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800119 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700120 return config;
121}
122
deadbeef14f97f52016-06-22 17:14:15 -0700123cricket::Candidate CreateUdpCandidate(const std::string& type,
124 const std::string& ip,
125 int port,
126 int priority,
127 const std::string& ufrag = "") {
128 cricket::Candidate c;
129 c.set_address(rtc::SocketAddress(ip, port));
130 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
131 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
132 c.set_priority(priority);
133 c.set_username(ufrag);
134 c.set_type(type);
135 return c;
136}
137
Honghai Zhangb73d2692016-09-29 22:46:09 -0700138cricket::BasicPortAllocator* CreateBasicPortAllocator(
139 rtc::NetworkManager* network_manager,
140 const cricket::ServerAddresses& stun_servers,
141 const rtc::SocketAddress& turn_server_udp,
142 const rtc::SocketAddress& turn_server_tcp) {
143 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
144 turn_server.credentials = kRelayCredentials;
145 if (!turn_server_udp.IsNil()) {
146 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800147 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700148 }
149 if (!turn_server_tcp.IsNil()) {
150 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800151 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700152 }
153 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
154
155 cricket::BasicPortAllocator* allocator =
156 new cricket::BasicPortAllocator(network_manager);
157 allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
158 return allocator;
159}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700160} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700161
162namespace cricket {
163
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164// This test simulates 2 P2P endpoints that want to establish connectivity
165// with each other over various network topologies and conditions, which can be
166// specified in each individial test.
167// A virtual network (via VirtualSocketServer) along with virtual firewalls and
168// NATs (via Firewall/NATSocketServer) are used to simulate the various network
169// conditions. We can configure the IP addresses of the endpoints,
170// block various types of connectivity, or add arbitrary levels of NAT.
171// We also run a STUN server and a relay server on the virtual network to allow
172// our typical P2P mechanisms to do their thing.
173// For each case, we expect the P2P stack to eventually settle on a specific
174// form of connectivity to the other side. The test checks that the P2P
175// negotiation successfully establishes connectivity within a certain time,
176// and that the result is what we expect.
177// Note that this class is a base class for use by other tests, who will provide
178// specialized test behavior.
179class P2PTransportChannelTestBase : public testing::Test,
180 public rtc::MessageHandler,
181 public sigslot::has_slots<> {
182 public:
183 P2PTransportChannelTestBase()
deadbeef98e186c2017-05-16 18:00:06 -0700184 : vss_(new rtc::VirtualSocketServer()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000185 nss_(new rtc::NATSocketServer(vss_.get())),
186 ss_(new rtc::FirewallSocketServer(nss_.get())),
nisse7eaa4ea2017-05-08 05:25:41 -0700187 main_(ss_.get()),
188 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
189 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeeff137e972017-03-23 15:45:49 -0700190 socks_server1_(ss_.get(),
191 kSocksProxyAddrs[0],
192 ss_.get(),
193 kSocksProxyAddrs[0]),
194 socks_server2_(ss_.get(),
195 kSocksProxyAddrs[1],
196 ss_.get(),
197 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000198 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700199 ep1_.role_ = ICEROLE_CONTROLLING;
200 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000201
202 ServerAddresses stun_servers;
203 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700204 ep1_.allocator_.reset(
205 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
206 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700207 ep1_.metrics_observer_ =
208 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
209 ep1_.allocator_->SetMetricsObserver(ep1_.metrics_observer_);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700210 ep2_.allocator_.reset(
211 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
212 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700213 ep2_.metrics_observer_ =
214 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
215 ep2_.allocator_->SetMetricsObserver(ep2_.metrics_observer_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000216 }
217
218 protected:
219 enum Config {
220 OPEN, // Open to the Internet
221 NAT_FULL_CONE, // NAT, no filtering
222 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
223 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
224 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
225 NAT_DOUBLE_CONE, // Double NAT, both cone
226 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
227 BLOCK_UDP, // Firewall, UDP in/out blocked
228 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
deadbeeff137e972017-03-23 15:45:49 -0700229 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
230 PROXY_HTTPS, // All traffic through HTTPS proxy
231 PROXY_SOCKS, // All traffic through SOCKS proxy
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000232 NUM_CONFIGS
233 };
234
235 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700236 Result(const std::string& controlling_type,
237 const std::string& controlling_protocol,
238 const std::string& controlled_type,
239 const std::string& controlled_protocol,
240 int wait)
241 : controlling_type(controlling_type),
242 controlling_protocol(controlling_protocol),
243 controlled_type(controlled_type),
244 controlled_protocol(controlled_protocol),
245 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700246
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700247 // The expected candidate type and protocol of the controlling ICE agent.
248 std::string controlling_type;
249 std::string controlling_protocol;
250 // The expected candidate type and protocol of the controlled ICE agent.
251 std::string controlled_type;
252 std::string controlled_protocol;
253 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000254 int connect_wait;
255 };
256
257 struct ChannelData {
258 bool CheckData(const char* data, int len) {
259 bool ret = false;
260 if (!ch_packets_.empty()) {
261 std::string packet = ch_packets_.front();
262 ret = (packet == std::string(data, len));
263 ch_packets_.pop_front();
264 }
265 return ret;
266 }
267
268 std::string name_; // TODO - Currently not used.
269 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700270 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000271 };
272
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700273 struct CandidatesData : public rtc::MessageData {
zhihuangd06adf62017-01-12 15:58:31 -0800274 CandidatesData(IceTransportInternal* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700275 : channel(ch), candidates(1, c) {}
zhihuangd06adf62017-01-12 15:58:31 -0800276 CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700277 : channel(ch), candidates(cc) {}
zhihuangd06adf62017-01-12 15:58:31 -0800278 IceTransportInternal* channel;
deadbeef14f97f52016-06-22 17:14:15 -0700279 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000280 };
281
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000282 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000283 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700284 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000285 tiebreaker_(0),
286 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700287 save_candidates_(false) {}
deadbeef5bd5ca32017-02-10 11:31:50 -0800288 bool HasTransport(const rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700289 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000290 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800291 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700292 if (!HasTransport(transport))
293 return NULL;
294 if (cd1_.ch_.get() == transport)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000295 return &cd1_;
296 else
297 return &cd2_;
298 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000299
deadbeef14f97f52016-06-22 17:14:15 -0700300 void SetIceRole(IceRole role) { role_ = role; }
301 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200302 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
303 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000304 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
305 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200306 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000307 allocator_->set_step_delay(delay);
308 }
309 void SetAllowTcpListen(bool allow_tcp_listen) {
310 allocator_->set_allow_tcp_listen(allow_tcp_listen);
311 }
312
313 rtc::FakeNetworkManager network_manager_;
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700314 // |metrics_observer_| should outlive |allocator_| as the former may be
315 // used by the latter.
316 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer_;
deadbeef14f97f52016-06-22 17:14:15 -0700317 std::unique_ptr<BasicPortAllocator> allocator_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000318 ChannelData cd1_;
319 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700320 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200321 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000322 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000323 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700324 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700325 bool ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000326 };
327
deadbeef5bd5ca32017-02-10 11:31:50 -0800328 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700329 if (ep1_.HasTransport(transport))
330 return ep1_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000331 else
johand89ab142016-10-25 10:50:32 -0700332 return ep2_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000333 }
334
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700335 IceParameters IceParamsWithRenomination(const IceParameters& ice,
336 bool renomination) {
337 IceParameters new_ice = ice;
338 new_ice.renomination = renomination;
339 return new_ice;
340 }
341
johan02bd5122016-09-20 00:23:27 -0700342 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700343 const IceConfig& ep2_config,
344 bool renomination = false) {
345 IceParameters ice_ep1_cd1_ch =
346 IceParamsWithRenomination(kIceParams[0], renomination);
347 IceParameters ice_ep2_cd1_ch =
348 IceParamsWithRenomination(kIceParams[1], renomination);
349 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
350 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
351 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
352 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700353 ep1_.cd1_.ch_->SetMetricsObserver(ep1_.metrics_observer_);
354 ep2_.cd1_.ch_->SetMetricsObserver(ep2_.metrics_observer_);
deadbeefb60a8192016-08-24 15:15:00 -0700355 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
356 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700357 ep1_.cd1_.ch_->MaybeStartGathering();
358 ep2_.cd1_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000359 }
deadbeefb60a8192016-08-24 15:15:00 -0700360
johan02bd5122016-09-20 00:23:27 -0700361 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700362 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700363 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700364 }
365
deadbeef14f97f52016-06-22 17:14:15 -0700366 P2PTransportChannel* CreateChannel(int endpoint,
367 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700368 const IceParameters& local_ice,
369 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700370 P2PTransportChannel* channel = new P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800371 "test content name", component, GetAllocator(endpoint));
deadbeef14f97f52016-06-22 17:14:15 -0700372 channel->SignalReadyToSend.connect(
373 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700374 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700375 this, &P2PTransportChannelTestBase::OnCandidateGathered);
376 channel->SignalCandidatesRemoved.connect(
377 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000378 channel->SignalReadPacket.connect(
379 this, &P2PTransportChannelTestBase::OnReadPacket);
380 channel->SignalRoleConflict.connect(
381 this, &P2PTransportChannelTestBase::OnRoleConflict);
honghaiz9ad0db52016-07-14 19:30:28 -0700382 channel->SignalSelectedCandidatePairChanged.connect(
383 this, &P2PTransportChannelTestBase::OnSelectedCandidatePairChanged);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700384 channel->SetIceParameters(local_ice);
385 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
386 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000387 }
388 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
389 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000390 return channel;
391 }
392 void DestroyChannels() {
393 ep1_.cd1_.ch_.reset();
394 ep2_.cd1_.ch_.reset();
395 ep1_.cd2_.ch_.reset();
396 ep2_.cd2_.ch_.reset();
397 }
deadbeef14f97f52016-06-22 17:14:15 -0700398 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
399 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
400 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
401 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000402
Taylor Brandstetteref184702016-06-23 17:35:47 -0700403 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700404 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700405
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000406 // Common results.
407 static const Result kLocalUdpToLocalUdp;
408 static const Result kLocalUdpToStunUdp;
409 static const Result kLocalUdpToPrflxUdp;
410 static const Result kPrflxUdpToLocalUdp;
411 static const Result kStunUdpToLocalUdp;
412 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700413 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000414 static const Result kPrflxUdpToStunUdp;
415 static const Result kLocalUdpToRelayUdp;
416 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700417 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000418 static const Result kLocalTcpToLocalTcp;
419 static const Result kLocalTcpToPrflxTcp;
420 static const Result kPrflxTcpToLocalTcp;
421
422 rtc::NATSocketServer* nat() { return nss_.get(); }
423 rtc::FirewallSocketServer* fw() { return ss_.get(); }
424
425 Endpoint* GetEndpoint(int endpoint) {
426 if (endpoint == 0) {
427 return &ep1_;
428 } else if (endpoint == 1) {
429 return &ep2_;
430 } else {
431 return NULL;
432 }
433 }
honghaiz7252a002016-11-08 20:04:09 -0800434 BasicPortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000435 return GetEndpoint(endpoint)->allocator_.get();
436 }
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700437 webrtc::FakeMetricsObserver* GetMetricsObserver(int endpoint) {
438 return GetEndpoint(endpoint)->metrics_observer_;
439 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000440 void AddAddress(int endpoint, const SocketAddress& addr) {
441 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
442 }
honghaize1a0c942016-02-16 14:54:56 -0800443 void AddAddress(int endpoint,
444 const SocketAddress& addr,
445 const std::string& ifname,
446 rtc::AdapterType adapter_type) {
447 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
448 adapter_type);
449 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000450 void RemoveAddress(int endpoint, const SocketAddress& addr) {
451 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700452 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000453 }
deadbeeff137e972017-03-23 15:45:49 -0700454 void SetProxy(int endpoint, rtc::ProxyType type) {
455 rtc::ProxyInfo info;
456 info.type = type;
457 info.address = (type == rtc::PROXY_HTTPS) ?
458 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
459 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
460 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000461 void SetAllocatorFlags(int endpoint, int flags) {
462 GetAllocator(endpoint)->set_flags(flags);
463 }
deadbeef14f97f52016-06-22 17:14:15 -0700464 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000465 GetEndpoint(endpoint)->SetIceRole(role);
466 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200467 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000468 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
469 }
470 bool GetRoleConflict(int endpoint) {
471 return GetEndpoint(endpoint)->role_conflict();
472 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200473 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000474 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
475 }
476 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
477 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
478 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700479
480 // Return true if the approprite parts of the expected Result, based
481 // on the local and remote candidate of ep1_ch1, match. This can be
482 // used in an EXPECT_TRUE_WAIT.
483 bool CheckCandidate1(const Result& expected) {
484 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700485 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700486 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700487 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
488 return (local_protocol == expected.controlling_protocol &&
489 remote_protocol == expected.controlled_protocol &&
490 local_type == expected.controlling_type &&
491 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700492 }
493
494 // EXPECT_EQ on the approprite parts of the expected Result, based
495 // on the local and remote candidate of ep1_ch1. This is like
496 // CheckCandidate1, except that it will provide more detail about
497 // what didn't match.
498 void ExpectCandidate1(const Result& expected) {
499 if (CheckCandidate1(expected)) {
500 return;
501 }
502
503 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700504 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700505 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700506 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
507 EXPECT_EQ(expected.controlling_type, local_type);
508 EXPECT_EQ(expected.controlled_type, remote_type);
509 EXPECT_EQ(expected.controlling_protocol, local_protocol);
510 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700511 }
512
513 // Return true if the approprite parts of the expected Result, based
514 // on the local and remote candidate of ep2_ch1, match. This can be
515 // used in an EXPECT_TRUE_WAIT.
516 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700517 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
518 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
519 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
520 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
521 return (local_protocol == expected.controlled_protocol &&
522 remote_protocol == expected.controlling_protocol &&
523 local_type == expected.controlled_type &&
524 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700525 }
526
527 // EXPECT_EQ on the approprite parts of the expected Result, based
528 // on the local and remote candidate of ep2_ch1. This is like
529 // CheckCandidate2, except that it will provide more detail about
530 // what didn't match.
531 void ExpectCandidate2(const Result& expected) {
532 if (CheckCandidate2(expected)) {
533 return;
534 }
535
536 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700537 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700538 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700539 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
540 EXPECT_EQ(expected.controlled_type, local_type);
541 EXPECT_EQ(expected.controlling_type, remote_type);
542 EXPECT_EQ(expected.controlled_protocol, local_protocol);
543 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700544 }
545
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000546 void Test(const Result& expected) {
honghaize58d73d2016-10-24 16:38:26 -0700547 rtc::ScopedFakeClock clock;
nisse1bffc1d2016-05-02 08:18:55 -0700548 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700549 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000550
551 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700552 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -0700553 EXPECT_TRUE_SIMULATED_WAIT(
554 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
555 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
556 ep2_ch1()->writable(),
557 expected.connect_wait + kShortTimeout, clock);
nisse1bffc1d2016-05-02 08:18:55 -0700558 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000559 if (connect_time < expected.connect_wait) {
560 LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
561 } else {
562 LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
563 << expected.connect_wait << " ms)";
564 }
565
Honghai Zhang572b0942016-06-23 12:26:57 -0700566 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000567 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700568 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700569 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700570 int64_t converge_time;
Honghai Zhang572b0942016-06-23 12:26:57 -0700571 // Verifying local and remote channel selected connection information.
572 // This is done only for the RFC 5245 as controlled agent will use
573 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
574 // EP1 result matrix.
honghaize58d73d2016-10-24 16:38:26 -0700575 EXPECT_TRUE_SIMULATED_WAIT(
576 CheckCandidate1(expected) && CheckCandidate2(expected),
577 kMediumTimeout, clock);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700578 // Also do EXPECT_EQ on each part so that failures are more verbose.
579 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700580 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000581
nisse1bffc1d2016-05-02 08:18:55 -0700582 converge_time = rtc::TimeMillis() - converge_start;
honghaize58d73d2016-10-24 16:38:26 -0700583 int64_t converge_wait = 2000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000584 if (converge_time < converge_wait) {
585 LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
586 } else {
587 LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
588 << converge_wait << " ms)";
589 }
590 }
591 // Try sending some data to other end.
honghaize58d73d2016-10-24 16:38:26 -0700592 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000593
594 // Destroy the channels, and wait for them to be fully cleaned up.
595 DestroyChannels();
596 }
597
honghaize58d73d2016-10-24 16:38:26 -0700598 void TestSendRecv(rtc::FakeClock& clock) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000599 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700600 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000601 int len = static_cast<int>(strlen(data));
602 // local_channel1 <==> remote_channel1
honghaize58d73d2016-10-24 16:38:26 -0700603 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
604 kMediumTimeout, clock);
605 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
606 kMediumTimeout, clock);
607 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
608 kMediumTimeout, clock);
609 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
610 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000611 }
612 }
613
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700614 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700615 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000616 // restart the ice gathering. Finally it waits for the transport to select a
617 // new connection using the newly generated ice candidates.
618 // Before calling this function the end points must be configured.
619 void TestHandleIceUfragPasswordChanged() {
honghaize58d73d2016-10-24 16:38:26 -0700620 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700621 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
622 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
honghaize58d73d2016-10-24 16:38:26 -0700623 EXPECT_TRUE_SIMULATED_WAIT(
624 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
625 ep2_ch1()->receiving() && ep2_ch1()->writable(),
626 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000627
deadbeef14f97f52016-06-22 17:14:15 -0700628 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
629 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
630 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
631 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000632
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700633 ep1_ch1()->SetIceParameters(kIceParams[2]);
634 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700635 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700636 ep2_ch1()->SetIceParameters(kIceParams[3]);
637
638 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700639 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000640
honghaize58d73d2016-10-24 16:38:26 -0700641 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
642 old_local_candidate1->generation(),
643 kMediumTimeout, clock);
644 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
645 old_local_candidate2->generation(),
646 kMediumTimeout, clock);
647 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
648 old_remote_candidate1->generation(),
649 kMediumTimeout, clock);
650 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
651 old_remote_candidate2->generation(),
652 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000653 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
654 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
655 }
656
657 void TestSignalRoleConflict() {
honghaize58d73d2016-10-24 16:38:26 -0700658 rtc::ScopedFakeClock clock;
659 // Default EP1 is in controlling state.
660 SetIceTiebreaker(0, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000661
deadbeef14f97f52016-06-22 17:14:15 -0700662 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700663 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000664
665 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700666 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000667 // Since both the channels initiated with controlling state and channel2
668 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
honghaize58d73d2016-10-24 16:38:26 -0700669 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000670 EXPECT_FALSE(GetRoleConflict(1));
671
honghaize58d73d2016-10-24 16:38:26 -0700672 EXPECT_TRUE_SIMULATED_WAIT(
673 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
674 ep2_ch1()->receiving() && ep2_ch1()->writable(),
675 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000676
Honghai Zhang572b0942016-06-23 12:26:57 -0700677 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
678 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000679
honghaize58d73d2016-10-24 16:38:26 -0700680 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000681 }
682
deadbeef5bd5ca32017-02-10 11:31:50 -0800683 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700684 GetEndpoint(transport)->ready_to_send_ = true;
deadbeef14f97f52016-06-22 17:14:15 -0700685 }
686
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000687 // We pass the candidates directly to the other side.
zhihuangd06adf62017-01-12 15:58:31 -0800688 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
deadbeef14f97f52016-06-22 17:14:15 -0700689 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000690 return;
691
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000692 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700693 GetEndpoint(ch)->saved_candidates_.push_back(
694 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000695 } else {
nisse7eaa4ea2017-05-08 05:25:41 -0700696 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
697 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000698 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000699 }
honghaiz9ad0db52016-07-14 19:30:28 -0700700 void OnSelectedCandidatePairChanged(
zhihuangd06adf62017-01-12 15:58:31 -0800701 IceTransportInternal* transport_channel,
honghaiz9ad0db52016-07-14 19:30:28 -0700702 CandidatePairInterface* selected_candidate_pair,
703 int last_sent_packet_id,
704 bool ready_to_send) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700705 // Do not count if it switches to nullptr. This may happen if all
706 // connections timed out.
707 if (selected_candidate_pair != nullptr) {
708 ++selected_candidate_pair_switches_;
709 }
honghaiz9ad0db52016-07-14 19:30:28 -0700710 }
711
712 int reset_selected_candidate_pair_switches() {
713 int switches = selected_candidate_pair_switches_;
714 selected_candidate_pair_switches_ = 0;
715 return switches;
716 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000717
718 void PauseCandidates(int endpoint) {
719 GetEndpoint(endpoint)->save_candidates_ = true;
720 }
721
zhihuangd06adf62017-01-12 15:58:31 -0800722 void OnCandidatesRemoved(IceTransportInternal* ch,
deadbeef14f97f52016-06-22 17:14:15 -0700723 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700724 // Candidate removals are not paused.
725 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
nisse7eaa4ea2017-05-08 05:25:41 -0700726 main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700727 }
728
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800729 // Tcp candidate verification has to be done when they are generated.
730 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
731 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700732 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700733 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700734 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700735 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
736 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
737 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
738 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700739 } else {
740 FAIL() << "Unknown tcptype: " << candidate.tcptype();
741 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800742 }
743 }
744 }
745
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000746 void ResumeCandidates(int endpoint) {
747 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700748 for (auto& candidate : ed->saved_candidates_) {
nisse7eaa4ea2017-05-08 05:25:41 -0700749 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000750 }
751 ed->saved_candidates_.clear();
752 ed->save_candidates_ = false;
753 }
754
755 void OnMessage(rtc::Message* msg) {
756 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700757 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700758 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700759 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700760 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
761 if (!rch) {
762 return;
763 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700764 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700765 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700766 c.set_username("");
767 c.set_password("");
768 }
769 LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
770 << rch->component() << "): " << c.ToString();
771 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000772 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700773 break;
774 }
775 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700776 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700777 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700778 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
779 if (!rch) {
780 return;
781 }
782 for (Candidate& c : data->candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700783 LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
784 rch->RemoveRemoteCandidate(c);
785 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000786 break;
787 }
788 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000789 }
johand89ab142016-10-25 10:50:32 -0700790
deadbeef5bd5ca32017-02-10 11:31:50 -0800791 void OnReadPacket(rtc::PacketTransportInternal* transport,
deadbeef14f97f52016-06-22 17:14:15 -0700792 const char* data,
793 size_t len,
794 const rtc::PacketTime& packet_time,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000795 int flags) {
johand89ab142016-10-25 10:50:32 -0700796 std::list<std::string>& packets = GetPacketList(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000797 packets.push_front(std::string(data, len));
798 }
johand89ab142016-10-25 10:50:32 -0700799
zhihuangd06adf62017-01-12 15:58:31 -0800800 void OnRoleConflict(IceTransportInternal* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000801 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700802 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
803 ? ICEROLE_CONTROLLED
804 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000805 channel->SetIceRole(new_role);
806 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700807
zhihuangd06adf62017-01-12 15:58:31 -0800808 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000809 rtc::PacketOptions options;
810 return channel->SendPacket(data, len, options, 0);
811 }
zhihuangd06adf62017-01-12 15:58:31 -0800812 bool CheckDataOnChannel(IceTransportInternal* channel,
deadbeef14f97f52016-06-22 17:14:15 -0700813 const char* data,
814 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000815 return GetChannelData(channel)->CheckData(data, len);
816 }
deadbeef14f97f52016-06-22 17:14:15 -0700817 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700818 return (ch && ch->selected_connection())
819 ? &ch->selected_connection()->local_candidate()
820 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000821 }
deadbeef14f97f52016-06-22 17:14:15 -0700822 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700823 return (ch && ch->selected_connection())
824 ? &ch->selected_connection()->remote_candidate()
825 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000826 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800827 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700828 if (ep1_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000829 return &ep1_;
johand89ab142016-10-25 10:50:32 -0700830 } else if (ep2_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000831 return &ep2_;
832 } else {
833 return NULL;
834 }
835 }
zhihuangd06adf62017-01-12 15:58:31 -0800836 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000837 if (ch == ep1_ch1())
838 return ep2_ch1();
839 else if (ch == ep1_ch2())
840 return ep2_ch2();
841 else if (ch == ep2_ch1())
842 return ep1_ch1();
843 else if (ch == ep2_ch2())
844 return ep1_ch2();
845 else
846 return NULL;
847 }
johand89ab142016-10-25 10:50:32 -0700848 std::list<std::string>& GetPacketList(
deadbeef5bd5ca32017-02-10 11:31:50 -0800849 rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700850 return GetChannelData(transport)->ch_packets_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000851 }
852
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700853 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700854
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700855 // How does the test pass ICE parameters to the P2PTransportChannel?
856 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700857 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700858 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
859 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000860 }
861
862 void set_force_relay(bool relay) {
863 force_relay_ = relay;
864 }
865
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700866 void ConnectSignalNominated(Connection* conn) {
867 conn->SignalNominated.connect(this,
868 &P2PTransportChannelTestBase::OnNominated);
869 }
870
871 void OnNominated(Connection* conn) { nominated_ = true; }
872 bool nominated() { return nominated_; }
873
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000874 private:
kwiberg3ec46792016-04-27 07:22:53 -0700875 std::unique_ptr<rtc::VirtualSocketServer> vss_;
876 std::unique_ptr<rtc::NATSocketServer> nss_;
877 std::unique_ptr<rtc::FirewallSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700878 rtc::AutoSocketServerThread main_;
deadbeef14f97f52016-06-22 17:14:15 -0700879 std::unique_ptr<TestStunServer> stun_server_;
880 TestTurnServer turn_server_;
deadbeeff137e972017-03-23 15:45:49 -0700881 rtc::SocksProxyServer socks_server1_;
882 rtc::SocksProxyServer socks_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000883 Endpoint ep1_;
884 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700885 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000886 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700887 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700888
889 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000890};
891
892// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700893const P2PTransportChannelTestBase::Result
894 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
895 "udp",
896 "local",
897 "udp",
898 1000);
899const P2PTransportChannelTestBase::Result
900 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
901 "udp",
902 "stun",
903 "udp",
904 1000);
905const P2PTransportChannelTestBase::Result
906 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
907 "udp",
908 "prflx",
909 "udp",
910 1000);
911const P2PTransportChannelTestBase::Result
912 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
913 "udp",
914 "local",
915 "udp",
916 1000);
917const P2PTransportChannelTestBase::Result
918 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
919 "udp",
920 "local",
921 "udp",
922 1000);
923const P2PTransportChannelTestBase::Result
924 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
925 "udp",
926 "stun",
927 "udp",
928 1000);
929const P2PTransportChannelTestBase::Result
930 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
931 "udp",
932 "prflx",
933 "udp",
934 1000);
935const P2PTransportChannelTestBase::Result
936 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
937 "udp",
938 "stun",
939 "udp",
940 1000);
941const P2PTransportChannelTestBase::Result
942 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
943 "udp",
944 "relay",
945 "udp",
946 2000);
947const P2PTransportChannelTestBase::Result
948 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
949 "udp",
950 "relay",
951 "udp",
952 2000);
953const P2PTransportChannelTestBase::Result
954 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
955 "udp",
956 "prflx",
957 "udp",
958 2000);
959const P2PTransportChannelTestBase::Result
960 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
961 "tcp",
962 "local",
963 "tcp",
964 3000);
965const P2PTransportChannelTestBase::Result
966 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
967 "tcp",
968 "prflx",
969 "tcp",
970 3000);
971const P2PTransportChannelTestBase::Result
972 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
973 "tcp",
974 "local",
975 "tcp",
976 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000977
978// Test the matrix of all the connectivity types we expect to see in the wild.
979// Just test every combination of the configs in the Config enum.
980class P2PTransportChannelTest : public P2PTransportChannelTestBase {
981 protected:
982 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700983 void ConfigureEndpoints(Config config1,
984 Config config2,
985 int allocator_flags1,
986 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000987 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000988 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700989 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000990 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000991 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700992 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000993
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700994 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000995 }
996 void ConfigureEndpoint(int endpoint, Config config) {
997 switch (config) {
998 case OPEN:
999 AddAddress(endpoint, kPublicAddrs[endpoint]);
1000 break;
1001 case NAT_FULL_CONE:
1002 case NAT_ADDR_RESTRICTED:
1003 case NAT_PORT_RESTRICTED:
1004 case NAT_SYMMETRIC:
1005 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1006 // Add a single NAT of the desired type
1007 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1008 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
1009 AddClient(kPrivateAddrs[endpoint]);
1010 break;
1011 case NAT_DOUBLE_CONE:
1012 case NAT_SYMMETRIC_THEN_CONE:
1013 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1014 // Add a two cascaded NATs of the desired types
1015 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1016 (config == NAT_DOUBLE_CONE) ?
1017 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
1018 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1019 rtc::NAT_OPEN_CONE)->
1020 AddClient(kCascadedPrivateAddrs[endpoint]);
1021 break;
1022 case BLOCK_UDP:
1023 case BLOCK_UDP_AND_INCOMING_TCP:
deadbeeff137e972017-03-23 15:45:49 -07001024 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1025 case PROXY_HTTPS:
1026 case PROXY_SOCKS:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001027 AddAddress(endpoint, kPublicAddrs[endpoint]);
1028 // Block all UDP
1029 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
1030 kPublicAddrs[endpoint]);
1031 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1032 // Block TCP inbound to the endpoint
1033 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1034 kPublicAddrs[endpoint]);
deadbeeff137e972017-03-23 15:45:49 -07001035 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1036 // Block all TCP to/from the endpoint except 80/443 out
1037 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1038 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1039 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1040 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1041 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1042 kPublicAddrs[endpoint]);
1043 } else if (config == PROXY_HTTPS) {
1044 // Block all TCP to/from the endpoint except to the proxy server
1045 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1046 kHttpsProxyAddrs[endpoint]);
1047 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1048 kPublicAddrs[endpoint]);
1049 SetProxy(endpoint, rtc::PROXY_HTTPS);
1050 } else if (config == PROXY_SOCKS) {
1051 // Block all TCP to/from the endpoint except to the proxy server
1052 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1053 kSocksProxyAddrs[endpoint]);
1054 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1055 kPublicAddrs[endpoint]);
1056 SetProxy(endpoint, rtc::PROXY_SOCKS5);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001057 }
1058 break;
1059 default:
deadbeef1ee21252017-06-13 15:49:45 -07001060 RTC_NOTREACHED();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001061 break;
1062 }
1063 }
1064};
1065
1066// Shorthands for use in the test matrix.
1067#define LULU &kLocalUdpToLocalUdp
1068#define LUSU &kLocalUdpToStunUdp
1069#define LUPU &kLocalUdpToPrflxUdp
1070#define PULU &kPrflxUdpToLocalUdp
1071#define SULU &kStunUdpToLocalUdp
1072#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001073#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001074#define PUSU &kPrflxUdpToStunUdp
1075#define LURU &kLocalUdpToRelayUdp
1076#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001077#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001078#define LTLT &kLocalTcpToLocalTcp
1079#define LTPT &kLocalTcpToPrflxTcp
1080#define PTLT &kPrflxTcpToLocalTcp
1081// TODO: Enable these once TestRelayServer can accept external TCP.
1082#define LTRT NULL
1083#define LSRS NULL
1084
1085// Test matrix. Originator behavior defined by rows, receiever by columns.
1086
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001087// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
deadbeeff137e972017-03-23 15:45:49 -07001088// TODO: Fix NULLs caused by no HTTP proxy support.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001089// TODO: Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001090const P2PTransportChannelTest::Result*
1091 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
deadbeeff137e972017-03-23 15:45:49 -07001092// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1093/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL, LTPT},
1094/*CO*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1095/*AD*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1096/*PO*/ {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, LTRT},
1097/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1098/*2C*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1099/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1100/*!U*/ {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, LTRT},
1101/*!T*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1102/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1103/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1104/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001105};
1106
1107// The actual tests that exercise all the various configurations.
1108// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001109#define P2P_TEST_DECLARATION(x, y, z) \
1110 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1111 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1112 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001113 if (kMatrix[x][y] != NULL) \
1114 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001115 else \
1116 LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001117 }
1118
1119#define P2P_TEST(x, y) \
1120 P2P_TEST_DECLARATION(x, y,)
1121
deadbeeff137e972017-03-23 15:45:49 -07001122#define P2P_TEST_SET(x) \
1123 P2P_TEST(x, OPEN) \
1124 P2P_TEST(x, NAT_FULL_CONE) \
1125 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1126 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1127 P2P_TEST(x, NAT_SYMMETRIC) \
1128 P2P_TEST(x, NAT_DOUBLE_CONE) \
1129 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1130 P2P_TEST(x, BLOCK_UDP) \
1131 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1132 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1133 P2P_TEST(x, PROXY_HTTPS) \
1134 P2P_TEST(x, PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001135
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001136P2P_TEST_SET(OPEN)
1137P2P_TEST_SET(NAT_FULL_CONE)
1138P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1139P2P_TEST_SET(NAT_PORT_RESTRICTED)
1140P2P_TEST_SET(NAT_SYMMETRIC)
1141P2P_TEST_SET(NAT_DOUBLE_CONE)
1142P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1143P2P_TEST_SET(BLOCK_UDP)
1144P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
deadbeeff137e972017-03-23 15:45:49 -07001145P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1146P2P_TEST_SET(PROXY_HTTPS)
1147P2P_TEST_SET(PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001148
1149// Test that we restart candidate allocation when local ufrag&pwd changed.
1150// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001151TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001152 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001153 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001154 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001155 TestHandleIceUfragPasswordChanged();
1156 DestroyChannels();
1157}
1158
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001159// Same as above test, but with a symmetric NAT.
1160// We should end up with relay<->prflx candidate pairs, with generation "1".
1161TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1162 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1163 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001164 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001165 TestHandleIceUfragPasswordChanged();
1166 DestroyChannels();
1167}
1168
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001169// Test the operation of GetStats.
1170TEST_F(P2PTransportChannelTest, GetStats) {
honghaize58d73d2016-10-24 16:38:26 -07001171 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001172 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001173 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001174 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -07001175 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1176 ep2_ch1()->receiving() &&
1177 ep2_ch1()->writable(),
1178 kMediumTimeout, clock);
1179 TestSendRecv(clock);
deadbeef14f97f52016-06-22 17:14:15 -07001180 ConnectionInfos infos;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001181 ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001182 ASSERT_TRUE(infos.size() >= 1);
deadbeef14f97f52016-06-22 17:14:15 -07001183 ConnectionInfo* best_conn_info = nullptr;
1184 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001185 if (info.best_connection) {
1186 best_conn_info = &info;
1187 break;
1188 }
1189 }
1190 ASSERT_TRUE(best_conn_info != nullptr);
1191 EXPECT_TRUE(best_conn_info->new_connection);
1192 EXPECT_TRUE(best_conn_info->receiving);
1193 EXPECT_TRUE(best_conn_info->writable);
1194 EXPECT_FALSE(best_conn_info->timeout);
1195 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1196 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1197 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1198 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001199 DestroyChannels();
1200}
1201
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001202// Tests that UMAs are recorded when ICE restarts while the channel
1203// is disconnected.
1204TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1205 rtc::ScopedFakeClock clock;
1206 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1207
1208 CreateChannels();
1209 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1210 ep2_ch1()->receiving() &&
1211 ep2_ch1()->writable(),
1212 kDefaultTimeout, clock);
1213
1214 // Drop all packets so that both channels become not writable.
1215 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
skvlad51072462017-02-02 11:50:14 -08001216 const int kWriteTimeoutDelay = 8000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001217 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1218 kWriteTimeoutDelay, clock);
1219
1220 ep1_ch1()->SetIceParameters(kIceParams[2]);
1221 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1222 ep1_ch1()->MaybeStartGathering();
1223 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1224 webrtc::kEnumCounterIceRestart,
1225 static_cast<int>(IceRestartState::DISCONNECTED)));
1226
1227 ep2_ch1()->SetIceParameters(kIceParams[3]);
1228 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1229 ep2_ch1()->MaybeStartGathering();
1230 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1231 webrtc::kEnumCounterIceRestart,
1232 static_cast<int>(IceRestartState::DISCONNECTED)));
1233
1234 DestroyChannels();
1235}
1236
1237// Tests that UMAs are recorded when ICE restarts while the channel
1238// is connected.
1239TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1240 rtc::ScopedFakeClock clock;
1241 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1242
1243 CreateChannels();
1244 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1245 ep2_ch1()->receiving() &&
1246 ep2_ch1()->writable(),
1247 kDefaultTimeout, clock);
1248
1249 ep1_ch1()->SetIceParameters(kIceParams[2]);
1250 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1251 ep1_ch1()->MaybeStartGathering();
1252 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1253 webrtc::kEnumCounterIceRestart,
1254 static_cast<int>(IceRestartState::CONNECTED)));
1255
1256 ep2_ch1()->SetIceParameters(kIceParams[3]);
1257 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1258 ep2_ch1()->MaybeStartGathering();
1259 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1260 webrtc::kEnumCounterIceRestart,
1261 static_cast<int>(IceRestartState::CONNECTED)));
1262
1263 DestroyChannels();
1264}
1265
1266// Tests that UMAs are recorded when ICE restarts while the channel
1267// is connecting.
1268TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1269 rtc::ScopedFakeClock clock;
1270 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1271
1272 // Create the channels without waiting for them to become connected.
1273 CreateChannels();
1274
1275 ep1_ch1()->SetIceParameters(kIceParams[2]);
1276 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1277 ep1_ch1()->MaybeStartGathering();
1278 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1279 webrtc::kEnumCounterIceRestart,
1280 static_cast<int>(IceRestartState::CONNECTING)));
1281
1282 ep2_ch1()->SetIceParameters(kIceParams[3]);
1283 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1284 ep2_ch1()->MaybeStartGathering();
1285 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1286 webrtc::kEnumCounterIceRestart,
1287 static_cast<int>(IceRestartState::CONNECTING)));
1288
1289 DestroyChannels();
1290}
1291
1292// Tests that a UMA on ICE regathering is recorded when there is a network
1293// change if and only if continual gathering is enabled.
1294TEST_F(P2PTransportChannelTest,
1295 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1296 rtc::ScopedFakeClock clock;
1297 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1298
1299 // ep1 gathers continually but ep2 does not.
1300 IceConfig continual_gathering_config =
1301 CreateIceConfig(1000, GATHER_CONTINUALLY);
1302 IceConfig default_config;
1303 CreateChannels(continual_gathering_config, default_config);
1304
1305 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1306 ep2_ch1()->receiving() &&
1307 ep2_ch1()->writable(),
1308 kDefaultTimeout, clock);
1309
1310 // Adding address in ep1 will trigger continual gathering.
1311 AddAddress(0, kAlternateAddrs[0]);
1312 EXPECT_EQ_SIMULATED_WAIT(
1313 1, GetMetricsObserver(0)->GetEnumCounter(
1314 webrtc::kEnumCounterIceRegathering,
1315 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)),
1316 kDefaultTimeout, clock);
1317
1318 ep2_ch1()->SetIceParameters(kIceParams[3]);
1319 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1320 ep2_ch1()->MaybeStartGathering();
1321
1322 AddAddress(1, kAlternateAddrs[1]);
1323 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1324 // ep2 has not enabled continual gathering.
1325 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1326 webrtc::kEnumCounterIceRegathering,
1327 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)));
1328
1329 DestroyChannels();
1330}
1331
1332// Tests that a UMA on ICE regathering is recorded when there is a network
1333// failure if and only if continual gathering is enabled.
1334TEST_F(P2PTransportChannelTest,
1335 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1336 rtc::ScopedFakeClock clock;
1337 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1338
1339 // ep1 gathers continually but ep2 does not.
1340 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1341 config1.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
1342 IceConfig config2;
1343 config2.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
1344 CreateChannels(config1, config2);
1345
1346 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1347 ep2_ch1()->receiving() &&
1348 ep2_ch1()->writable(),
1349 kDefaultTimeout, clock);
1350
1351 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1352 // Timeout value such that all connections are deleted.
1353 const int kNetworkFailureTimeout = 35000;
1354 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
1355 EXPECT_LE(1, GetMetricsObserver(0)->GetEnumCounter(
1356 webrtc::kEnumCounterIceRegathering,
1357 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1358 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1359 webrtc::kEnumCounterIceRegathering,
1360 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1361
1362 DestroyChannels();
1363}
1364
Steve Anton300bf8e2017-07-14 10:13:10 -07001365// Tests that ICE regathering occurs regularly when
1366// regather_all_networks_interval_range configuration value is set.
1367TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
1368 rtc::ScopedFakeClock clock;
1369 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1370
1371 // ep1 gathers continually but ep2 does not.
1372 const int kRegatherInterval = 2000;
1373 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1374 config1.regather_all_networks_interval_range.emplace(
1375 kRegatherInterval, kRegatherInterval);
1376 IceConfig config2;
Steve Anton300bf8e2017-07-14 10:13:10 -07001377 CreateChannels(config1, config2);
1378
1379 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1380 ep2_ch1()->receiving() &&
1381 ep2_ch1()->writable(),
1382 kDefaultTimeout, clock);
1383
1384 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1385 // Timeout value such that all connections are deleted.
1386 const int kNetworkGatherDuration = 11000;
1387 SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
1388 // Expect regathering to happen 5 times in 11s with 2s interval.
1389 EXPECT_LE(5, GetMetricsObserver(0)->GetEnumCounter(
1390 webrtc::kEnumCounterIceRegathering,
1391 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1392 // Expect no regathering if continual gathering not configured.
1393 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1394 webrtc::kEnumCounterIceRegathering,
1395 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1396
1397 DestroyChannels();
1398}
1399
1400// Test that ICE periodic regathering can change the selected connection on the
1401// specified interval and that the peers can communicate over the new
1402// connection. The test is parameterized to test that it works when regathering
1403// is done by the ICE controlling peer and when done by the controlled peer.
1404class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
1405 protected:
1406 void TestWithRoles(IceRole p1_role, IceRole p2_role) {
1407 rtc::ScopedFakeClock clock;
1408 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1409 kDefaultPortAllocatorFlags);
1410 set_force_relay(true);
1411
1412 const int kRegatherInterval = 2000;
1413 const int kNumRegathers = 2;
1414
1415 // Set up peer 1 to auto regather every 2s.
1416 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1417 config1.regather_all_networks_interval_range.emplace(
1418 kRegatherInterval, kRegatherInterval);
1419 IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1420
1421 // Set peer roles.
1422 SetIceRole(0, p1_role);
1423 SetIceRole(1, p2_role);
1424
1425 CreateChannels(config1, config2);
1426
1427 // Wait for initial connection to be made.
1428 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() &&
1429 ep1_ch1()->writable() &&
1430 ep2_ch1()->receiving() &&
1431 ep2_ch1()->writable(),
1432 kMediumTimeout, clock);
1433
1434 const Connection* initial_selected = ep1_ch1()->selected_connection();
1435
1436 // Wait long enough for 2 regathering cycles to happen plus some extra so
1437 // the new connection has time to settle.
1438 const int kWaitRegather =
1439 kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
1440 SIMULATED_WAIT(false, kWaitRegather, clock);
1441 EXPECT_EQ(kNumRegathers, GetMetricsObserver(0)->GetEnumCounter(
1442 webrtc::kEnumCounterIceRegathering,
1443 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1444
1445 const Connection* new_selected = ep1_ch1()->selected_connection();
1446
1447 // Want the new selected connection to be different.
1448 ASSERT_NE(initial_selected, new_selected);
1449
1450 // Make sure we can communicate over the new connection too.
1451 TestSendRecv(clock);
1452 }
1453};
1454
1455TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
1456 TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
1457}
1458
1459TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
1460 TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
1461}
1462
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001463// Test that we properly create a connection on a STUN ping from unknown address
1464// when the signaling is slow.
1465TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001466 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001467 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001468 // Emulate no remote parameters coming in.
1469 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001470 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001471 // Only have remote parameters come in for ep2, not ep1.
1472 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001473
1474 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1475 // candidate.
1476 PauseCandidates(1);
1477
Honghai Zhange05bcc22016-08-16 18:19:14 -07001478 // Wait until the callee becomes writable to make sure that a ping request is
1479 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001480 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001481 // Add two sets of remote ICE credentials, so that the ones used by the
1482 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001483 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1484 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001485 // The caller should have the selected connection connected to the peer
1486 // reflexive candidate.
1487 const Connection* selected_connection = nullptr;
1488 ASSERT_TRUE_WAIT(
1489 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001490 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001491 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1492 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1493 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1494 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001495
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001496 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001497 // Verify ep1's selected connection is updated to use the 'local' candidate.
1498 EXPECT_EQ_WAIT("local",
1499 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001500 kMediumTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001501 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001502 DestroyChannels();
1503}
1504
1505// Test that we properly create a connection on a STUN ping from unknown address
1506// when the signaling is slow and the end points are behind NAT.
1507TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001508 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001509 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001510 // Emulate no remote parameters coming in.
1511 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001512 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001513 // Only have remote parameters come in for ep2, not ep1.
1514 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001515 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1516 // candidate.
1517 PauseCandidates(1);
1518
Honghai Zhange05bcc22016-08-16 18:19:14 -07001519 // Wait until the callee becomes writable to make sure that a ping request is
1520 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001521 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001522 // Add two sets of remote ICE credentials, so that the ones used by the
1523 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001524 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1525 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001526
1527 // The caller's selected connection should be connected to the peer reflexive
1528 // candidate.
1529 const Connection* selected_connection = nullptr;
1530 ASSERT_TRUE_WAIT(
1531 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001532 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001533 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1534 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1535 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1536 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001537
1538 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001539
Honghai Zhange05bcc22016-08-16 18:19:14 -07001540 EXPECT_EQ_WAIT("prflx",
1541 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001542 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001543 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001544 DestroyChannels();
1545}
1546
deadbeef0af180b2016-06-21 13:15:32 -07001547// Test that we properly create a connection on a STUN ping from unknown address
1548// when the signaling is slow, even if the new candidate is created due to the
1549// remote peer doing an ICE restart, pairing this candidate across generations.
1550//
1551// Previously this wasn't working due to a bug where the peer reflexive
1552// candidate was only updated for the newest generation candidate pairs, and
1553// not older-generation candidate pairs created by pairing candidates across
1554// generations. This resulted in the old-generation prflx candidate being
1555// prioritized above new-generation candidate pairs.
1556TEST_F(P2PTransportChannelTest,
1557 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1558 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1559 kDefaultPortAllocatorFlags);
1560 // Only gather relay candidates, so that when the prflx candidate arrives
1561 // it's prioritized above the current candidate pair.
deadbeef14f97f52016-06-22 17:14:15 -07001562 GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
1563 GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001564 // Setting this allows us to control when SetRemoteIceParameters is called.
1565 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001566 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001567 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001568 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1569 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001570 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1571 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1572 kDefaultTimeout);
1573
1574 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001575 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001576 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001577 ep2_ch1()->SetIceParameters(kIceParams[3]);
1578
1579 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001580 ep2_ch1()->MaybeStartGathering();
1581
Honghai Zhang572b0942016-06-23 12:26:57 -07001582 // The caller should have the selected connection connected to the peer
1583 // reflexive candidate.
deadbeef0af180b2016-06-21 13:15:32 -07001584 EXPECT_EQ_WAIT("prflx",
Honghai Zhang572b0942016-06-23 12:26:57 -07001585 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001586 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001587 const Connection* prflx_selected_connection =
1588 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001589
1590 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001591 ep1_ch1()->SetIceParameters(kIceParams[2]);
1592
1593 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001594 ep1_ch1()->MaybeStartGathering();
1595
1596 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1597 // their information to update the peer reflexive candidate.
1598 ResumeCandidates(1);
1599
1600 EXPECT_EQ_WAIT("relay",
Honghai Zhang572b0942016-06-23 12:26:57 -07001601 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001602 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001603 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001604 DestroyChannels();
1605}
1606
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001607// Test that if remote candidates don't have ufrag and pwd, we still work.
1608TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001609 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001610 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001611 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001612 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001613 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001614 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001615 // Wait until the callee's connections are created.
Honghai Zhang161a5862016-10-20 11:47:02 -07001616 EXPECT_TRUE_SIMULATED_WAIT(
1617 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1618 kMediumTimeout, clock);
1619 // Wait to make sure the selected connection is not changed.
1620 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1621 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001622 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001623 DestroyChannels();
1624}
1625
1626// Test that a host behind NAT cannot be reached when incoming_only
1627// is set to true.
1628TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
honghaize58d73d2016-10-24 16:38:26 -07001629 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001630 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001631 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001632
1633 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001634 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001635 ep1_ch1()->set_incoming_only(true);
1636
1637 // Pump for 1 second and verify that the channels are not connected.
honghaize58d73d2016-10-24 16:38:26 -07001638 SIMULATED_WAIT(false, kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001639
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001640 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001641 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001642 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001643 EXPECT_FALSE(ep2_ch1()->writable());
1644
1645 DestroyChannels();
1646}
1647
1648// Test that a peer behind NAT can connect to a peer that has
1649// incoming_only flag set.
1650TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
honghaize58d73d2016-10-24 16:38:26 -07001651 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001652 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001653 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001654
1655 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001656 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001657 ep1_ch1()->set_incoming_only(true);
1658
honghaize58d73d2016-10-24 16:38:26 -07001659 EXPECT_TRUE_SIMULATED_WAIT(
1660 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1661 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1662 ep2_ch1()->writable(),
1663 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001664
1665 DestroyChannels();
1666}
1667
deadbeef1ee21252017-06-13 15:49:45 -07001668// Test that two peers can connect when one can only make outgoing TCP
1669// connections. This has been observed in some scenarios involving
1670// VPNs/firewalls.
1671TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
1672 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1673 // application needs this use case to work, since the application must accept
1674 // the tradeoff that more candidates need to be allocated.
1675 //
1676 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1677 // things to ensure extra candidates don't waste resources?
1678 ConfigureEndpoints(
1679 OPEN, OPEN,
1680 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1681 kDefaultPortAllocatorFlags);
1682 // In order to simulate nothing working but outgoing TCP connections, prevent
1683 // the endpoint from binding to its interface's address as well as the
1684 // "any" addresses. It can then only make a connection by using "Connect()".
1685 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1686 kPublicAddrs[0].ipaddr()});
1687 CreateChannels();
1688 // Expect a "prflx" candidate on the side that can only make outgoing
1689 // connections, endpoint 0.
1690 Test(kPrflxTcpToLocalTcp);
1691 DestroyChannels();
1692}
1693
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001694TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
honghaize58d73d2016-10-24 16:38:26 -07001695 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001696 AddAddress(0, kPublicAddrs[0]);
1697 AddAddress(1, kPublicAddrs[1]);
1698
1699 SetAllocationStepDelay(0, kMinimumStepDelay);
1700 SetAllocationStepDelay(1, kMinimumStepDelay);
1701
deadbeef14f97f52016-06-22 17:14:15 -07001702 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1703 PORTALLOCATOR_DISABLE_STUN |
1704 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001705 // Disable all protocols except TCP.
1706 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1707 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1708
1709 SetAllowTcpListen(0, true); // actpass.
1710 SetAllowTcpListen(1, false); // active.
1711
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001712 // We want SetRemoteIceParameters to be called as it normally would.
1713 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001714 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001715 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001716
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001717 // Pause candidate so we could verify the candidate properties.
1718 PauseCandidates(0);
1719 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001720 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001721
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001722 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001723 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1724 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001725
1726 // Resume candidates.
1727 ResumeCandidates(0);
1728 ResumeCandidates(1);
1729
honghaize58d73d2016-10-24 16:38:26 -07001730 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1731 ep2_ch1()->receiving() &&
1732 ep2_ch1()->writable(),
1733 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001734 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1735 ep2_ch1()->selected_connection() &&
1736 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1737 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001738
honghaize58d73d2016-10-24 16:38:26 -07001739 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001740 DestroyChannels();
1741}
1742
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001743TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001744 AddAddress(0, kPublicAddrs[0]);
1745 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001746 TestSignalRoleConflict();
1747}
1748
1749// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1750// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001751TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
honghaize58d73d2016-10-24 16:38:26 -07001752 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001753 AddAddress(0, kPublicAddrs[0]);
1754 AddAddress(1, kPublicAddrs[1]);
1755
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001756 // Give the first connection the higher tiebreaker so its role won't
1757 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001758 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001759 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001760 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001761 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001762
johan02bd5122016-09-20 00:23:27 -07001763 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001764
honghaize58d73d2016-10-24 16:38:26 -07001765 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001766
deadbeef14f97f52016-06-22 17:14:15 -07001767 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001768 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001769 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001770 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001771 }
1772
deadbeef14f97f52016-06-22 17:14:15 -07001773 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001774 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001775
deadbeef14f97f52016-06-22 17:14:15 -07001776 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001777 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001778 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001779 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001780 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001781 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001782 }
1783
honghaize58d73d2016-10-24 16:38:26 -07001784 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1785 ep2_ch1()->receiving() &&
1786 ep2_ch1()->writable(),
1787 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001788
Honghai Zhang572b0942016-06-23 12:26:57 -07001789 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1790 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001791
honghaize58d73d2016-10-24 16:38:26 -07001792 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001793 DestroyChannels();
1794}
1795
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001796// Verify that we can set DSCP value and retrieve properly from P2PTC.
1797TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1798 AddAddress(0, kPublicAddrs[0]);
1799 AddAddress(1, kPublicAddrs[1]);
1800
johan02bd5122016-09-20 00:23:27 -07001801 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001802 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1803 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1804 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1805 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1806 GetEndpoint(0)->cd1_.ch_->SetOption(
1807 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1808 GetEndpoint(1)->cd1_.ch_->SetOption(
1809 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1810 EXPECT_EQ(rtc::DSCP_CS6,
1811 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1812 EXPECT_EQ(rtc::DSCP_CS6,
1813 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1814 GetEndpoint(0)->cd1_.ch_->SetOption(
1815 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1816 GetEndpoint(1)->cd1_.ch_->SetOption(
1817 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1818 EXPECT_EQ(rtc::DSCP_AF41,
1819 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1820 EXPECT_EQ(rtc::DSCP_AF41,
1821 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1822}
1823
1824// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001825TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
honghaize58d73d2016-10-24 16:38:26 -07001826 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001827 AddAddress(0, kIPv6PublicAddrs[0]);
1828 AddAddress(0, kPublicAddrs[0]);
1829 AddAddress(1, kIPv6PublicAddrs[1]);
1830 AddAddress(1, kPublicAddrs[1]);
1831
1832 SetAllocationStepDelay(0, kMinimumStepDelay);
1833 SetAllocationStepDelay(1, kMinimumStepDelay);
1834
1835 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08001836 SetAllocatorFlags(
1837 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1838 SetAllocatorFlags(
1839 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001840
johan02bd5122016-09-20 00:23:27 -07001841 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001842
honghaize58d73d2016-10-24 16:38:26 -07001843 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1844 ep2_ch1()->receiving() &&
1845 ep2_ch1()->writable(),
1846 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001847 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001848 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001849 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1850 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1851
honghaize58d73d2016-10-24 16:38:26 -07001852 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001853 DestroyChannels();
1854}
1855
1856// Testing forceful TURN connections.
1857TEST_F(P2PTransportChannelTest, TestForceTurn) {
honghaize58d73d2016-10-24 16:38:26 -07001858 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001859 ConfigureEndpoints(
1860 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001861 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1862 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001863 set_force_relay(true);
1864
1865 SetAllocationStepDelay(0, kMinimumStepDelay);
1866 SetAllocationStepDelay(1, kMinimumStepDelay);
1867
johan02bd5122016-09-20 00:23:27 -07001868 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001869
honghaize58d73d2016-10-24 16:38:26 -07001870 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1871 ep2_ch1()->receiving() &&
1872 ep2_ch1()->writable(),
1873 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001874
Honghai Zhang572b0942016-06-23 12:26:57 -07001875 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1876 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001877
1878 EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
1879 EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
1880 EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
1881 EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
1882
honghaize58d73d2016-10-24 16:38:26 -07001883 TestSendRecv(clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001884 DestroyChannels();
1885}
1886
honghaiz98db68f2015-09-29 07:58:17 -07001887// Test that if continual gathering is set to true, ICE gathering state will
1888// not change to "Complete", and vice versa.
1889TEST_F(P2PTransportChannelTest, TestContinualGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001890 rtc::ScopedFakeClock clock;
honghaiz98db68f2015-09-29 07:58:17 -07001891 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1892 kDefaultPortAllocatorFlags);
1893 SetAllocationStepDelay(0, kDefaultStepDelay);
1894 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07001895 IceConfig continual_gathering_config =
1896 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001897 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07001898 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07001899 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07001900
Honghai Zhang161a5862016-10-20 11:47:02 -07001901 EXPECT_TRUE_SIMULATED_WAIT(
1902 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1903 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1904 ep2_ch1()->writable(),
1905 kMediumTimeout, clock);
1906 SIMULATED_WAIT(
1907 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
1908 kShortTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07001909 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001910 ep1_ch1()->gathering_state());
1911 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001912 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001913 ep2_ch1()->gathering_state());
1914
1915 DestroyChannels();
1916}
1917
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001918// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1919// PortAllocatorSession that has not yet finished gathering candidates.
1920TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001921 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001922 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1923 kDefaultPortAllocatorFlags);
1924 // First create a pooled session for each endpoint.
1925 auto& allocator_1 = GetEndpoint(0)->allocator_;
1926 auto& allocator_2 = GetEndpoint(1)->allocator_;
1927 int pool_size = 1;
1928 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001929 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001930 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001931 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001932 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001933 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001934 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001935 allocator_2->GetPooledSession();
1936 ASSERT_NE(nullptr, pooled_session_1);
1937 ASSERT_NE(nullptr, pooled_session_2);
1938 // Sanity check that pooled sessions haven't gathered anything yet.
1939 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1940 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1941 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1942 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1943 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001944 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001945 EXPECT_TRUE_SIMULATED_WAIT(
1946 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1947 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1948 ep2_ch1()->writable(),
1949 kMediumTimeout, clock);
honghaize58d73d2016-10-24 16:38:26 -07001950 TestSendRecv(clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001951 // Make sure the P2PTransportChannels are actually using ports from the
1952 // pooled sessions.
1953 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1954 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1955 EXPECT_NE(pooled_ports_1.end(),
1956 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001957 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001958 EXPECT_NE(pooled_ports_2.end(),
1959 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001960 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001961}
1962
1963// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1964// PortAllocatorSession that already finished gathering candidates.
1965TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001966 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001967 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1968 kDefaultPortAllocatorFlags);
1969 // First create a pooled session for each endpoint.
1970 auto& allocator_1 = GetEndpoint(0)->allocator_;
1971 auto& allocator_2 = GetEndpoint(1)->allocator_;
1972 int pool_size = 1;
1973 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001974 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001975 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001976 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001977 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001978 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001979 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001980 allocator_2->GetPooledSession();
1981 ASSERT_NE(nullptr, pooled_session_1);
1982 ASSERT_NE(nullptr, pooled_session_2);
1983 // Wait for the pooled sessions to finish gathering before the
1984 // P2PTransportChannels try to use them.
Honghai Zhang161a5862016-10-20 11:47:02 -07001985 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
1986 pooled_session_2->CandidatesAllocationDone(),
1987 kDefaultTimeout, clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001988 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001989 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001990 EXPECT_TRUE_SIMULATED_WAIT(
1991 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1992 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1993 ep2_ch1()->writable(),
1994 kMediumTimeout, clock);
honghaize58d73d2016-10-24 16:38:26 -07001995 TestSendRecv(clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001996 // Make sure the P2PTransportChannels are actually using ports from the
1997 // pooled sessions.
1998 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1999 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
2000 EXPECT_NE(pooled_ports_1.end(),
2001 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002002 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002003 EXPECT_NE(pooled_ports_2.end(),
2004 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07002005 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002006}
2007
deadbeef14f97f52016-06-22 17:14:15 -07002008// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07002009// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07002010// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07002011// TODO(deadbeef): Move this and other "presumed writable" tests into a test
2012// class that operates on a single P2PTransportChannel, once an appropriate one
2013// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07002014TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
2015 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2016 kDefaultPortAllocatorFlags);
2017 // Only configure one channel so we can control when the remote candidate
2018 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002019 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2020 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07002021 IceConfig config;
2022 config.presume_writable_when_fully_relayed = true;
2023 ep1_ch1()->SetIceConfig(config);
2024 ep1_ch1()->MaybeStartGathering();
2025 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2026 ep1_ch1()->gathering_state(), kDefaultTimeout);
2027 // Add two remote candidates; a host candidate (with higher priority)
2028 // and TURN candidate.
2029 ep1_ch1()->AddRemoteCandidate(
2030 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2031 ep1_ch1()->AddRemoteCandidate(
2032 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2033 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2034 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07002035 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002036 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2037 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2038 // Also expect that the channel instantly indicates that it's writable since
2039 // it has a TURN-TURN pair.
2040 EXPECT_TRUE(ep1_ch1()->writable());
2041 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002042 // Also make sure we can immediately send packets.
2043 const char* data = "test";
2044 int len = static_cast<int>(strlen(data));
2045 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07002046}
2047
Taylor Brandstetteref184702016-06-23 17:35:47 -07002048// Test that a TURN/peer reflexive candidate pair is also presumed writable.
2049TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
2050 rtc::ScopedFakeClock fake_clock;
2051
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002052 // We need to add artificial network delay to verify that the connection
2053 // is presumed writable before it's actually writable. Without this delay
2054 // it would become writable instantly.
2055 virtual_socket_server()->set_delay_mean(50);
2056 virtual_socket_server()->UpdateDelayDistribution();
2057
Taylor Brandstetteref184702016-06-23 17:35:47 -07002058 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2059 kDefaultPortAllocatorFlags);
2060 // We want the remote TURN candidate to show up as prflx. To do this we need
2061 // to configure the server to accept packets from an address we haven't
2062 // explicitly installed permission for.
2063 test_turn_server()->set_enable_permission_checks(false);
2064 IceConfig config;
2065 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002066 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2067 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2068 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2069 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07002070 ep1_ch1()->SetIceConfig(config);
2071 ep2_ch1()->SetIceConfig(config);
2072 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2073 // candidate as peer reflexive.
2074 PauseCandidates(1);
2075 ep1_ch1()->MaybeStartGathering();
2076 ep2_ch1()->MaybeStartGathering();
2077
2078 // Wait for the TURN<->prflx connection.
2079 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002080 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002081 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2082 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2083 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2084 // Make sure that at this point the connection is only presumed writable,
2085 // not fully writable.
2086 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2087
2088 // Now wait for it to actually become writable.
Honghai Zhang161a5862016-10-20 11:47:02 -07002089 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2090 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002091
2092 // Explitly destroy channels, before fake clock is destroyed.
2093 DestroyChannels();
2094}
2095
deadbeef14f97f52016-06-22 17:14:15 -07002096// Test that a presumed-writable TURN<->TURN connection is preferred above an
2097// unreliable connection (one that has failed to be pinged for some time).
2098TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
2099 rtc::ScopedFakeClock fake_clock;
2100
2101 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2102 kDefaultPortAllocatorFlags);
2103 IceConfig config;
2104 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002105 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2106 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2107 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2108 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07002109 ep1_ch1()->SetIceConfig(config);
2110 ep2_ch1()->SetIceConfig(config);
2111 ep1_ch1()->MaybeStartGathering();
2112 ep2_ch1()->MaybeStartGathering();
2113 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07002114 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2115 ep1_ch1()->selected_connection()->writable() &&
2116 ep2_ch1()->receiving() &&
2117 ep2_ch1()->writable() &&
2118 ep2_ch1()->selected_connection()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002119 kShortTimeout, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002120 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07002121 // Destroy the second channel and wait for the current connection on the
2122 // first channel to become "unreliable", making it no longer writable.
2123 GetEndpoint(1)->cd1_.ch_.reset();
Honghai Zhang161a5862016-10-20 11:47:02 -07002124 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2125 fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002126 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002127 // Add a remote TURN candidate. The first channel should still have a TURN
2128 // port available to make a TURN<->TURN pair that's presumed writable.
2129 ep1_ch1()->AddRemoteCandidate(
2130 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2131 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2132 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2133 EXPECT_TRUE(ep1_ch1()->writable());
2134 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07002135 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002136 // Explitly destroy channels, before fake clock is destroyed.
2137 DestroyChannels();
2138}
2139
deadbeefdd7fb432016-09-30 15:16:48 -07002140// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2141// writable" connection. Previously this did not work.
2142TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
2143 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2144 kDefaultPortAllocatorFlags);
2145 // Only test one endpoint, so we can ensure the connection doesn't receive a
2146 // binding response and advance beyond being "presumed" writable.
2147 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2148 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2149 IceConfig config;
2150 config.presume_writable_when_fully_relayed = true;
2151 ep1_ch1()->SetIceConfig(config);
2152 ep1_ch1()->MaybeStartGathering();
2153 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2154 ep1_ch1()->gathering_state(), kDefaultTimeout);
2155 ep1_ch1()->AddRemoteCandidate(
2156 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2157 // Sanity checking the type of the connection.
2158 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
2159 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2160 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2161
2162 // Tell the socket server to block packets (returning EWOULDBLOCK).
2163 virtual_socket_server()->SetSendingBlocked(true);
2164 const char* data = "test";
2165 int len = static_cast<int>(strlen(data));
2166 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2167
2168 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2169 // should.
2170 GetEndpoint(0)->ready_to_send_ = false;
2171 virtual_socket_server()->SetSendingBlocked(false);
2172 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2173 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2174}
2175
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002176// Test what happens when we have 2 users behind the same NAT. This can lead
2177// to interesting behavior because the STUN server will only give out the
2178// address of the outermost NAT.
2179class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2180 protected:
2181 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
kwibergee89e782017-08-09 17:22:01 -07002182 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2183 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002184 rtc::NATSocketServer::Translator* outer_nat =
2185 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
2186 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
2187 ConfigureEndpoint(outer_nat, 0, config1);
2188 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002189 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002190 }
2191 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
2192 int endpoint, Config config) {
nissec8ee8822017-01-18 07:20:55 -08002193 RTC_CHECK(config <= NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002194 if (config == OPEN) {
2195 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2196 nat->AddClient(kPrivateAddrs[endpoint]);
2197 } else {
2198 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2199 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
2200 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
2201 kCascadedPrivateAddrs[endpoint]);
2202 }
2203 }
2204};
2205
2206TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2207 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002208 Test(
2209 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002210}
2211
2212// Test what happens when we have multiple available pathways.
2213// In the future we will try different RTTs and configs for the different
2214// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2215class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002216 public:
honghaiz7252a002016-11-08 20:04:09 -08002217 const Connection* GetConnectionWithRemoteAddress(
2218 P2PTransportChannel* channel,
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002219 const SocketAddress& address) {
honghaiz7252a002016-11-08 20:04:09 -08002220 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002221 if (conn->remote_candidate().address().EqualIPs(address)) {
2222 return conn;
2223 }
2224 }
2225 return nullptr;
2226 }
2227
honghaiz7252a002016-11-08 20:04:09 -08002228 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2229 const SocketAddress& address) {
2230 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002231 if (conn->local_candidate().address().EqualIPs(address)) {
2232 return conn;
2233 }
2234 }
2235 return nullptr;
2236 }
2237
honghaiz7252a002016-11-08 20:04:09 -08002238 Connection* GetConnection(P2PTransportChannel* channel,
2239 const SocketAddress& local,
2240 const SocketAddress& remote) {
2241 for (Connection* conn : channel->connections()) {
2242 if (conn->local_candidate().address().EqualIPs(local) &&
2243 conn->remote_candidate().address().EqualIPs(remote)) {
2244 return conn;
2245 }
2246 }
2247 return nullptr;
2248 }
2249
2250 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2251 const Connection* selected_connection = channel->selected_connection();
2252 for (Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002253 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002254 conn->Destroy();
2255 }
2256 }
2257 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002258};
2259
2260// Test that we can establish connectivity when both peers are multihomed.
zhihuanga3095d02016-11-10 13:59:46 -08002261TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002262 AddAddress(0, kPublicAddrs[0]);
2263 AddAddress(0, kAlternateAddrs[0]);
2264 AddAddress(1, kPublicAddrs[1]);
2265 AddAddress(1, kAlternateAddrs[1]);
2266 Test(kLocalUdpToLocalUdp);
2267}
2268
Honghai Zhang52dce732016-03-31 12:37:31 -07002269// Test that we can quickly switch links if an interface goes down.
2270// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002271TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002272 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002273 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002274 // Simulate failing over from Wi-Fi to cell interface.
2275 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2276 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002277
2278 // Use only local ports for simplicity.
2279 SetAllocatorFlags(0, kOnlyLocalPorts);
2280 SetAllocatorFlags(1, kOnlyLocalPorts);
2281
deadbeefb60a8192016-08-24 15:15:00 -07002282 // Make the receiving timeout shorter for testing.
2283 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002284 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002285 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002286
honghaiz9ad0db52016-07-14 19:30:28 -07002287 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2288 ep2_ch1()->receiving() &&
2289 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002290 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002291 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2292 ep2_ch1()->selected_connection() &&
2293 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2294 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002295
2296 // Blackhole any traffic to or from the public addrs.
2297 LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002298 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002299 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002300 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2301 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002302 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002303 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002304 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002305 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002306
honghaiz9ad0db52016-07-14 19:30:28 -07002307 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002308 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002309 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2310 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002311 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002312 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2313 EXPECT_TRUE(
2314 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2315 EXPECT_TRUE(
2316 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2317
2318 DestroyChannels();
2319}
2320
Honghai Zhang52dce732016-03-31 12:37:31 -07002321// Test that we can quickly switch links if an interface goes down.
2322// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002323TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002324 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002325 // Simulate failing over from Wi-Fi to cell interface.
2326 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2327 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiza58ea782015-09-24 08:13:36 -07002328 AddAddress(1, kPublicAddrs[1]);
2329
2330 // Use only local ports for simplicity.
2331 SetAllocatorFlags(0, kOnlyLocalPorts);
2332 SetAllocatorFlags(1, kOnlyLocalPorts);
2333
deadbeefb60a8192016-08-24 15:15:00 -07002334 // Make the receiving timeout shorter for testing.
2335 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002336 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002337 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002338 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2339 ep2_ch1()->receiving() &&
2340 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002341 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002342 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2343 ep2_ch1()->selected_connection() &&
2344 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2345 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002346
2347 // Blackhole any traffic to or from the public addrs.
2348 LOG(LS_INFO) << "Failing over...";
2349 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002350 // The selected connections will switch, so keep references to them.
2351 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2352 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002353 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002354 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002355 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002356 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002357
honghaiz9ad0db52016-07-14 19:30:28 -07002358 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002359 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002360 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2361 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002362 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002363 EXPECT_TRUE(
2364 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
2365 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2366 EXPECT_TRUE(
2367 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002368
2369 DestroyChannels();
2370}
2371
honghaiz7252a002016-11-08 20:04:09 -08002372// Tests that we can quickly switch links if an interface goes down when
2373// there are many connections.
2374TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2375 rtc::ScopedFakeClock clock;
2376 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
2377 RelayServerConfig turn_server(RELAY_TURN);
2378 turn_server.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08002379 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
honghaiz7252a002016-11-08 20:04:09 -08002380 GetAllocator(0)->AddTurnServer(turn_server);
2381 GetAllocator(1)->AddTurnServer(turn_server);
2382 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08002383 SetAllocatorFlags(
2384 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2385 SetAllocatorFlags(
2386 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002387 SetAllocationStepDelay(0, kMinimumStepDelay);
2388 SetAllocationStepDelay(1, kMinimumStepDelay);
2389
2390 auto& wifi = kPublicAddrs;
2391 auto& cellular = kAlternateAddrs;
2392 auto& wifiIpv6 = kIPv6PublicAddrs;
2393 auto& cellularIpv6 = kIPv6AlternateAddrs;
2394 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2395 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2396 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2397 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2398 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2399 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2400 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2401 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2402
2403 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2404 // will be created in time.
2405 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2406 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2407 virtual_socket_server()->set_delay_mean(500);
2408 virtual_socket_server()->UpdateDelayDistribution();
2409
2410 // Make the receiving timeout shorter for testing.
2411 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2412 // Create channels and let them go writable, as usual.
2413 CreateChannels(config, config, true /* ice_renomination */);
2414 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2415 ep2_ch1()->receiving() &&
2416 ep2_ch1()->writable(),
2417 kMediumTimeout, clock);
2418 EXPECT_TRUE_SIMULATED_WAIT(
2419 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
2420 LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
2421 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
2422 kMediumTimeout, clock);
2423
2424 // Blackhole any traffic to or from the wifi on endpoint 1.
2425 LOG(LS_INFO) << "Failing over...";
2426 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2427 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2428
2429 // The selected connections may switch, so keep references to them.
2430 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2431 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2432 EXPECT_TRUE_SIMULATED_WAIT(
2433 !selected_connection1->receiving() && !selected_connection2->receiving(),
2434 kMediumTimeout, clock);
2435
2436 // Per-network best connections will be pinged at relatively higher rate when
2437 // the selected connection becomes not receiving.
2438 Connection* per_network_best_connection1 =
2439 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2440 ASSERT_NE(nullptr, per_network_best_connection1);
2441 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2442 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2443 EXPECT_TRUE_SIMULATED_WAIT(
2444 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2445 kMediumTimeout, clock);
2446 int64_t ping_interval1 =
2447 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2448 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2449 constexpr int SCHEDULING_DELAY = 200;
2450 EXPECT_LT(
2451 ping_interval1,
2452 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2453
2454 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2455 // it timed out on writing.
2456 EXPECT_TRUE_SIMULATED_WAIT(
2457 ep1_ch1()->selected_connection()->receiving() &&
2458 ep2_ch1()->selected_connection()->receiving() &&
2459 RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
2460 LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
2461 kMediumTimeout, clock);
2462
2463 DestroyChannels();
2464}
2465
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002466// Test that when the controlling side switches the selected connection,
2467// the nomination of the selected connection on the controlled side will
2468// increase.
2469TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2470 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002471 // Simulate failing over from Wi-Fi to cell interface.
2472 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2473 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002474 AddAddress(1, kPublicAddrs[1]);
2475
2476 // Use only local ports for simplicity.
2477 SetAllocatorFlags(0, kOnlyLocalPorts);
2478 SetAllocatorFlags(1, kOnlyLocalPorts);
2479
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002480 // We want it to set the remote ICE parameters when creating channels.
2481 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002482 // Make the receiving timeout shorter for testing.
2483 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002484 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002485 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002486 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2487 ep2_ch1()->receiving() &&
2488 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002489 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002490 EXPECT_TRUE_SIMULATED_WAIT(
2491 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2492 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2493 kDefaultTimeout, clock);
2494 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2495 Connection* selected_connection2 =
2496 const_cast<Connection*>(ep2_ch1()->selected_connection());
2497 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2498 // |selected_connection2| should not be nominated any more since the previous
2499 // nomination has been acknowledged.
2500 ConnectSignalNominated(selected_connection2);
Honghai Zhang161a5862016-10-20 11:47:02 -07002501 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002502 EXPECT_FALSE(nominated());
2503
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002504 // Blackhole any traffic to or from the public addrs.
2505 LOG(LS_INFO) << "Failing over...";
2506 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2507
2508 // The selected connection on the controlling side should switch.
2509 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002510 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2511 clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002512 // The connection on the controlled side should be nominated again
2513 // and have an increased nomination.
2514 EXPECT_TRUE_SIMULATED_WAIT(
2515 ep2_ch1()->selected_connection()->remote_nomination() >
2516 remote_nomination2,
2517 kDefaultTimeout, clock);
2518
2519 DestroyChannels();
2520}
2521
honghaiz9ad0db52016-07-14 19:30:28 -07002522// Test that if an interface fails temporarily and then recovers quickly,
2523// the selected connection will not switch.
2524// The case that it will switch over to the backup connection if the selected
2525// connection does not recover after enough time is covered in
2526// TestFailoverControlledSide and TestFailoverControllingSide.
2527TEST_F(P2PTransportChannelMultihomedTest,
2528 TestConnectionSwitchDampeningControlledSide) {
2529 rtc::ScopedFakeClock clock;
2530 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002531 // Simulate failing over from Wi-Fi to cell interface.
2532 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2533 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002534
2535 // Use only local ports for simplicity.
2536 SetAllocatorFlags(0, kOnlyLocalPorts);
2537 SetAllocatorFlags(1, kOnlyLocalPorts);
2538
2539 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002540 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002541
2542 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2543 ep2_ch1()->receiving() &&
2544 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002545 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002546 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2547 ep2_ch1()->selected_connection() &&
2548 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2549 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2550
2551 // Make the receiving timeout shorter for testing.
2552 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2553 ep1_ch1()->SetIceConfig(config);
2554 ep2_ch1()->SetIceConfig(config);
2555 reset_selected_candidate_pair_switches();
2556
2557 // Blackhole any traffic to or from the public addrs.
2558 LOG(LS_INFO) << "Failing over...";
2559 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2560
2561 // The selected connections may switch, so keep references to them.
2562 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2563 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2564 // We should detect loss of receiving within 1 second or so.
2565 EXPECT_TRUE_SIMULATED_WAIT(
2566 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002567 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002568 // After a short while, the link recovers itself.
2569 SIMULATED_WAIT(false, 10, clock);
2570 fw()->ClearRules();
2571
2572 // We should remain on the public address on both sides and no connection
2573 // switches should have happened.
2574 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2575 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002576 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002577 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2578 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2579 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2580
2581 DestroyChannels();
2582}
2583
2584// Test that if an interface fails temporarily and then recovers quickly,
2585// the selected connection will not switch.
2586TEST_F(P2PTransportChannelMultihomedTest,
2587 TestConnectionSwitchDampeningControllingSide) {
2588 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002589 // Simulate failing over from Wi-Fi to cell interface.
2590 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2591 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002592 AddAddress(1, kPublicAddrs[1]);
2593
2594 // Use only local ports for simplicity.
2595 SetAllocatorFlags(0, kOnlyLocalPorts);
2596 SetAllocatorFlags(1, kOnlyLocalPorts);
2597
2598 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002599 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002600 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2601 ep2_ch1()->receiving() &&
2602 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002603 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002604 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2605 ep2_ch1()->selected_connection() &&
2606 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2607 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2608
2609 // Make the receiving timeout shorter for testing.
2610 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2611 ep1_ch1()->SetIceConfig(config);
2612 ep2_ch1()->SetIceConfig(config);
2613 reset_selected_candidate_pair_switches();
2614
2615 // Blackhole any traffic to or from the public addrs.
2616 LOG(LS_INFO) << "Failing over...";
2617 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2618 // The selected connections may switch, so keep references to them.
2619 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2620 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2621 // We should detect loss of receiving within 1 second or so.
2622 EXPECT_TRUE_SIMULATED_WAIT(
2623 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002624 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002625 // The link recovers after a short while.
2626 SIMULATED_WAIT(false, 10, clock);
2627 fw()->ClearRules();
2628
2629 // We should not switch to the alternate addr on both sides because of the
2630 // dampening.
2631 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2632 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002633 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002634 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2635 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2636 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2637 DestroyChannels();
2638}
2639
Honghai Zhangfd16da22016-08-17 16:12:46 -07002640// Tests that if the remote side's network failed, it won't cause the local
2641// side to switch connections and networks.
2642TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2643 rtc::ScopedFakeClock clock;
2644 // The interface names are chosen so that |cellular| would have higher
2645 // candidate priority and higher cost.
2646 auto& wifi = kPublicAddrs;
2647 auto& cellular = kAlternateAddrs;
2648 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2649 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2650 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2651
2652 // Use only local ports for simplicity.
2653 SetAllocatorFlags(0, kOnlyLocalPorts);
2654 SetAllocatorFlags(1, kOnlyLocalPorts);
2655 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002656 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002657 // Make the receiving timeout shorter for testing.
2658 // Set the backup connection ping interval to 25s.
2659 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2660 // Ping the best connection more frequently since we don't have traffic.
2661 config.stable_writable_connection_ping_interval = 900;
2662 ep1_ch1()->SetIceConfig(config);
2663 ep2_ch1()->SetIceConfig(config);
2664 // Need to wait to make sure the connections on both networks are writable.
2665 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2666 ep2_ch1()->receiving() &&
2667 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002668 kMediumTimeout, clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002669 EXPECT_TRUE_SIMULATED_WAIT(
2670 ep1_ch1()->selected_connection() &&
2671 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2672 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2673 kDefaultTimeout, clock);
2674 Connection* backup_conn =
2675 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2676 ASSERT_NE(nullptr, backup_conn);
2677 // After a short while, the backup connection will be writable but not
2678 // receiving because backup connection is pinged at a slower rate.
2679 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002680 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
2681 clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002682 reset_selected_candidate_pair_switches();
2683 // Blackhole any traffic to or from the remote WiFi networks.
2684 LOG(LS_INFO) << "Failing over...";
2685 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2686
2687 int num_switches = 0;
2688 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2689 20000, clock);
2690 EXPECT_EQ(0, num_switches);
2691 DestroyChannels();
2692}
2693
honghaize1a0c942016-02-16 14:54:56 -08002694// Tests that a Wifi-Wifi connection has the highest precedence.
2695TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2696 // The interface names are chosen so that |cellular| would have higher
2697 // candidate priority if it is not for the network type.
2698 auto& wifi = kAlternateAddrs;
2699 auto& cellular = kPublicAddrs;
2700 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2701 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2702 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2703 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2704
2705 // Use only local ports for simplicity.
2706 SetAllocatorFlags(0, kOnlyLocalPorts);
2707 SetAllocatorFlags(1, kOnlyLocalPorts);
2708
2709 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002710 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002711
2712 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2713 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2714 1000, 1000);
2715 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002716 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002717 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2718 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2719 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002720 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002721 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2722 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2723 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002724 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002725}
2726
2727// Tests that a Wifi-Cellular connection has higher precedence than
2728// a Cellular-Cellular connection.
2729TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2730 // The interface names are chosen so that |cellular| would have higher
2731 // candidate priority if it is not for the network type.
2732 auto& wifi = kAlternateAddrs;
2733 auto& cellular = kPublicAddrs;
2734 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2735 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2736 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2737
2738 // Use only local ports for simplicity.
2739 SetAllocatorFlags(0, kOnlyLocalPorts);
2740 SetAllocatorFlags(1, kOnlyLocalPorts);
2741
2742 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002743 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002744
2745 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2746 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2747 1000, 1000);
2748 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002749 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002750 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2751 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002752 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002753 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2754 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002755 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002756}
2757
Honghai Zhang381b4212015-12-04 12:24:03 -08002758// Test that the backup connection is pinged at a rate no faster than
2759// what was configured.
2760TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2761 AddAddress(0, kPublicAddrs[0]);
2762 // Adding alternate address will make sure |kPublicAddrs| has the higher
2763 // priority than others. This is due to FakeNetwork::AddInterface method.
2764 AddAddress(1, kAlternateAddrs[1]);
2765 AddAddress(1, kPublicAddrs[1]);
2766
2767 // Use only local ports for simplicity.
2768 SetAllocatorFlags(0, kOnlyLocalPorts);
2769 SetAllocatorFlags(1, kOnlyLocalPorts);
2770
2771 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002772 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002773 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2774 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2775 1000, 1000);
2776 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002777 ep2_ch1()->SetIceConfig(
2778 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002779 // After the state becomes COMPLETED, the backup connection will be pinged
2780 // once every |backup_ping_interval| milliseconds.
zhihuangd06adf62017-01-12 15:58:31 -08002781 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
2782 1000);
deadbeef14f97f52016-06-22 17:14:15 -07002783 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002784 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002785 Connection* backup_conn = connections[1];
Honghai Zhang161a5862016-10-20 11:47:02 -07002786 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
honghaiz34b11eb2016-03-16 08:55:44 -07002787 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002788 EXPECT_TRUE_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002789 last_ping_response_ms < backup_conn->last_ping_response_received(),
2790 kDefaultTimeout);
Honghai Zhang381b4212015-12-04 12:24:03 -08002791 int time_elapsed =
2792 backup_conn->last_ping_response_received() - last_ping_response_ms;
2793 LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
2794 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002795
2796 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002797}
2798
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002799TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002800 rtc::ScopedFakeClock clock;
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002801 AddAddress(0, kAlternateAddrs[0]);
2802 AddAddress(0, kPublicAddrs[0]);
2803 AddAddress(1, kPublicAddrs[1]);
2804 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002805 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002806
2807 // Both transport channels will reach STATE_COMPLETED quickly.
zhihuangd06adf62017-01-12 15:58:31 -08002808 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002809 ep1_ch1()->GetState(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08002810 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002811 ep2_ch1()->GetState(), kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002812}
2813
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002814// Tests that when a network interface becomes inactive, if Continual Gathering
2815// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002816// will be removed from the port list of the channel, and the respective
2817// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002818TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002819 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002820 AddAddress(0, kPublicAddrs[0]);
2821 AddAddress(1, kPublicAddrs[1]);
2822 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07002823 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
2824 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07002825 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08002826
2827 SetAllocatorFlags(0, kOnlyLocalPorts);
2828 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002829 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2830 ep2_ch1()->receiving() &&
2831 ep2_ch1()->writable(),
2832 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002833 // More than one port has been created.
2834 EXPECT_LE(1U, ep1_ch1()->ports().size());
2835 // Endpoint 1 enabled continual gathering; the port will be removed
2836 // when the interface is removed.
2837 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002838 EXPECT_TRUE(ep1_ch1()->ports().empty());
2839 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002840 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2841 clock);
honghaize3c6c822016-02-17 13:00:28 -08002842
2843 size_t num_ports = ep2_ch1()->ports().size();
2844 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002845 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002846 // Endpoint 2 did not enable continual gathering; the local port will still be
2847 // removed when the interface is removed but the remote candidates on the
2848 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002849 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002850
2851 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2852 clock);
2853 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002854 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002855
2856 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002857}
2858
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002859// Tests that continual gathering will create new connections when a new
2860// interface is added.
2861TEST_F(P2PTransportChannelMultihomedTest,
2862 TestContinualGatheringOnNewInterface) {
2863 auto& wifi = kAlternateAddrs;
2864 auto& cellular = kPublicAddrs;
2865 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2866 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002867 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002868 IceConfig continual_gathering_config =
2869 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07002870 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002871 SetAllocatorFlags(0, kOnlyLocalPorts);
2872 SetAllocatorFlags(1, kOnlyLocalPorts);
2873 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2874 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2875 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002876
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002877 // Add a new wifi interface on end point 2. We should expect a new connection
2878 // to be created and the new one will be the best connection.
2879 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002880 const Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002881 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002882 conn->remote_candidate().address().EqualIPs(wifi[1]),
2883 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002884 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002885 conn->local_candidate().address().EqualIPs(wifi[1]),
2886 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002887
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002888 // Add a new cellular interface on end point 1, we should expect a new
2889 // backup connection created using this new interface.
2890 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002891 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002892 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002893 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2894 nullptr &&
2895 conn != ep1_ch1()->selected_connection() && conn->writable(),
2896 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002897 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08002898 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002899 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
2900 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002901 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002902 kDefaultTimeout);
2903
2904 DestroyChannels();
2905}
2906
2907// Tests that we can switch links via continual gathering.
2908TEST_F(P2PTransportChannelMultihomedTest,
2909 TestSwitchLinksViaContinualGathering) {
2910 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002911 AddAddress(0, kPublicAddrs[0]);
2912 AddAddress(1, kPublicAddrs[1]);
2913 // Use only local ports for simplicity.
2914 SetAllocatorFlags(0, kOnlyLocalPorts);
2915 SetAllocatorFlags(1, kOnlyLocalPorts);
2916
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002917 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002918 IceConfig continual_gathering_config =
2919 CreateIceConfig(1000, GATHER_CONTINUALLY);
2920 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002921 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002922 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2923 ep2_ch1()->receiving() &&
2924 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002925 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002926 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07002927 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002928 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2929 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2930
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002931 // Add the new address first and then remove the other one.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002932 LOG(LS_INFO) << "Draining...";
2933 AddAddress(1, kAlternateAddrs[1]);
2934 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002935 // We should switch to use the alternate address after an exchange of pings.
2936 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002937 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002938 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2939 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002940 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002941
2942 // Remove one address first and then add another address.
2943 LOG(LS_INFO) << "Draining again...";
2944 RemoveAddress(1, kAlternateAddrs[1]);
2945 AddAddress(1, kAlternateAddrs[0]);
2946 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002947 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002948 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2949 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002950 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002951
2952 DestroyChannels();
2953}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002954
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002955/*
2956TODO(honghaiz) Once continual gathering fully supports
2957GATHER_CONTINUALLY_AND_RECOVER, put this test back.
2958
2959// Tests that if the backup connections are lost and then the interface with the
2960// selected connection is gone, continual gathering will restore the
2961// connectivity.
2962TEST_F(P2PTransportChannelMultihomedTest,
2963 TestBackupConnectionLostThenInterfaceGone) {
2964 rtc::ScopedFakeClock clock;
2965 auto& wifi = kAlternateAddrs;
2966 auto& cellular = kPublicAddrs;
2967 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2968 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2969 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2970 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2971 // Use only local ports for simplicity.
2972 SetAllocatorFlags(0, kOnlyLocalPorts);
2973 SetAllocatorFlags(1, kOnlyLocalPorts);
2974
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002975 // Set continual gathering policy.
2976 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER);
deadbeefb60a8192016-08-24 15:15:00 -07002977 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002978 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002979 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2980 ep2_ch1()->receiving() && ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002981 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002982 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2983 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002984 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2985 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2986
2987 // First destroy all backup connection.
2988 DestroyAllButBestConnection(ep1_ch1());
2989
2990 SIMULATED_WAIT(false, 10, clock);
2991 // Then the interface of the best connection goes away.
2992 RemoveAddress(0, wifi[0]);
2993 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002994 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002995 LocalCandidate(ep1_ch1())->address().EqualIPs(cellular[0]) &&
2996 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07002997 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002998
2999 DestroyChannels();
3000}
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003001*/
3002
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003003// Tests that the backup connection will be restored after it is destroyed.
3004TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3005 rtc::ScopedFakeClock clock;
3006 auto& wifi = kAlternateAddrs;
3007 auto& cellular = kPublicAddrs;
3008 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3009 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3010 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3011 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3012 // Use only local ports for simplicity.
3013 SetAllocatorFlags(0, kOnlyLocalPorts);
3014 SetAllocatorFlags(1, kOnlyLocalPorts);
3015
3016 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003017 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
3018 config.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
johan02bd5122016-09-20 00:23:27 -07003019 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003020 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3021 ep2_ch1()->receiving() &&
3022 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003023 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003024 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3025 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003026 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
3027 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
3028
3029 // Destroy all backup connections.
3030 DestroyAllButBestConnection(ep1_ch1());
3031 // Ensure the backup connection is removed first.
3032 EXPECT_TRUE_SIMULATED_WAIT(
3033 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3034 kDefaultTimeout, clock);
honghaiz7252a002016-11-08 20:04:09 -08003035 const Connection* conn;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003036 EXPECT_TRUE_SIMULATED_WAIT(
3037 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3038 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003039 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003040 kDefaultTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003041
3042 DestroyChannels();
3043}
3044
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003045// A collection of tests which tests a single P2PTransportChannel by sending
3046// pings.
3047class P2PTransportChannelPingTest : public testing::Test,
3048 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003049 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003050 P2PTransportChannelPingTest()
deadbeef98e186c2017-05-16 18:00:06 -07003051 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003052
3053 protected:
deadbeef14f97f52016-06-22 17:14:15 -07003054 void PrepareChannel(P2PTransportChannel* ch) {
3055 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003056 ch->SetIceParameters(kIceParams[0]);
3057 ch->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhang52dce732016-03-31 12:37:31 -07003058 ch->SignalSelectedCandidatePairChanged.connect(
3059 this, &P2PTransportChannelPingTest::OnSelectedCandidatePairChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07003060 ch->SignalReadyToSend.connect(this,
3061 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07003062 ch->SignalStateChanged.connect(
3063 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003064 }
3065
deadbeef14f97f52016-06-22 17:14:15 -07003066 Connection* WaitForConnectionTo(P2PTransportChannel* ch,
3067 const std::string& ip,
Honghai Zhange05bcc22016-08-16 18:19:14 -07003068 int port_num,
3069 rtc::FakeClock* clock = nullptr) {
3070 if (clock == nullptr) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003071 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3072 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003073 } else {
3074 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003075 kMediumTimeout, *clock);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003076 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003077 return GetConnectionTo(ch, ip, port_num);
3078 }
3079
sprang716978d2016-10-11 06:43:28 -07003080 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003081 if (ch->ports().empty()) {
3082 return nullptr;
3083 }
deadbeef14f97f52016-06-22 17:14:15 -07003084 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003085 }
3086
Honghai Zhanga74363c2016-07-28 18:06:15 -07003087 Port* GetPrunedPort(P2PTransportChannel* ch) {
3088 if (ch->pruned_ports().empty()) {
3089 return nullptr;
3090 }
3091 return static_cast<Port*>(ch->pruned_ports()[0]);
3092 }
3093
deadbeef14f97f52016-06-22 17:14:15 -07003094 Connection* GetConnectionTo(P2PTransportChannel* ch,
3095 const std::string& ip,
3096 int port_num) {
sprang716978d2016-10-11 06:43:28 -07003097 Port* port = GetPort(ch);
3098 if (!port) {
3099 return nullptr;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003100 }
sprang716978d2016-10-11 06:43:28 -07003101 return port->GetConnection(rtc::SocketAddress(ip, port_num));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003102 }
3103
deadbeef14f97f52016-06-22 17:14:15 -07003104 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3105 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08003106 if (conn) {
3107 ch->MarkConnectionPinged(conn);
3108 }
3109 return conn;
3110 }
3111
zhihuangd06adf62017-01-12 15:58:31 -08003112 int SendData(IceTransportInternal& channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07003113 const char* data,
3114 size_t len,
3115 int packet_id) {
3116 rtc::PacketOptions options;
3117 options.packet_id = packet_id;
3118 return channel.SendPacket(data, len, options, 0);
3119 }
3120
Honghai Zhang572b0942016-06-23 12:26:57 -07003121 Connection* CreateConnectionWithCandidate(P2PTransportChannel& channel,
3122 rtc::ScopedFakeClock& clock,
3123 const std::string& ip_addr,
3124 int port,
3125 int priority,
3126 bool writable) {
3127 channel.AddRemoteCandidate(
3128 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3129 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003130 GetConnectionTo(&channel, ip_addr, port) != nullptr, kMediumTimeout,
3131 clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07003132 Connection* conn = GetConnectionTo(&channel, ip_addr, port);
3133
3134 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003135 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07003136 }
3137 return conn;
3138 }
3139
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003140 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3141 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07003142 conn->SignalNominated(conn);
3143 }
3144
Honghai Zhang52dce732016-03-31 12:37:31 -07003145 void OnSelectedCandidatePairChanged(
zhihuangd06adf62017-01-12 15:58:31 -08003146 IceTransportInternal* transport_channel,
deadbeef14f97f52016-06-22 17:14:15 -07003147 CandidatePairInterface* selected_candidate_pair,
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003148 int last_sent_packet_id,
3149 bool ready_to_send) {
Honghai Zhang52dce732016-03-31 12:37:31 -07003150 last_selected_candidate_pair_ = selected_candidate_pair;
3151 last_sent_packet_id_ = last_sent_packet_id;
Honghai Zhang572b0942016-06-23 12:26:57 -07003152 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07003153 }
3154
deadbeef14f97f52016-06-22 17:14:15 -07003155 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07003156 const std::string& remote_ufrag,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003157 int priority,
3158 uint32_t nomination = 0) {
deadbeef14f97f52016-06-22 17:14:15 -07003159 IceMessage msg;
3160 msg.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003161 msg.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
deadbeef14f97f52016-06-22 17:14:15 -07003162 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07003163 conn->local_candidate().username() + ":" + remote_ufrag));
zsteinf42cc9d2017-03-27 16:17:19 -07003164 msg.AddAttribute(
3165 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003166 if (nomination != 0) {
zsteinf42cc9d2017-03-27 16:17:19 -07003167 msg.AddAttribute(rtc::MakeUnique<StunUInt32Attribute>(
3168 STUN_ATTR_NOMINATION, nomination));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003169 }
deadbeef14f97f52016-06-22 17:14:15 -07003170 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07003171 msg.AddMessageIntegrity(conn->local_candidate().password());
3172 msg.AddFingerprint();
3173 rtc::ByteBufferWriter buf;
3174 msg.Write(&buf);
3175 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
3176 }
3177
deadbeef5bd5ca32017-02-10 11:31:50 -08003178 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07003179 channel_ready_to_send_ = true;
3180 }
zhihuangd06adf62017-01-12 15:58:31 -08003181 void OnChannelStateChanged(IceTransportInternal* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07003182 channel_state_ = channel->GetState();
3183 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003184
deadbeef14f97f52016-06-22 17:14:15 -07003185 CandidatePairInterface* last_selected_candidate_pair() {
Honghai Zhang52dce732016-03-31 12:37:31 -07003186 return last_selected_candidate_pair_;
3187 }
3188 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003189 bool channel_ready_to_send() { return channel_ready_to_send_; }
3190 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
zhihuangd06adf62017-01-12 15:58:31 -08003191 IceTransportState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07003192 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07003193 int switches = selected_candidate_pair_switches_;
3194 selected_candidate_pair_switches_ = 0;
3195 return switches;
3196 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003197
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003198 private:
kwiberg3ec46792016-04-27 07:22:53 -07003199 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -07003200 rtc::AutoSocketServerThread thread_;
deadbeef14f97f52016-06-22 17:14:15 -07003201 CandidatePairInterface* last_selected_candidate_pair_ = nullptr;
Honghai Zhang572b0942016-06-23 12:26:57 -07003202 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07003203 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07003204 bool channel_ready_to_send_ = false;
zhihuangd06adf62017-01-12 15:58:31 -08003205 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003206};
3207
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003208TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07003209 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3210 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003211 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003212 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003213 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3214 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003215
deadbeef14f97f52016-06-22 17:14:15 -07003216 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3217 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003218 ASSERT_TRUE(conn1 != nullptr);
3219 ASSERT_TRUE(conn2 != nullptr);
3220
3221 // Before a triggered check, the first connection to ping is the
3222 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08003223 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003224
3225 // Receiving a ping causes a triggered check which should make conn1
3226 // be pinged first instead of conn2, even though conn2 has a higher
3227 // priority.
3228 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08003229 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003230}
3231
honghaiz524ecc22016-05-25 12:48:31 -07003232TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07003233 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3234 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07003235 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07003236 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003237 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3238 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07003239
deadbeef14f97f52016-06-22 17:14:15 -07003240 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3241 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07003242 ASSERT_TRUE(conn1 != nullptr);
3243 ASSERT_TRUE(conn2 != nullptr);
3244
3245 // Low-priority connection becomes writable so that the other connection
3246 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003247 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07003248 EXPECT_TRUE_WAIT(
3249 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3250 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3251 kDefaultTimeout);
3252}
3253
zhihuang435264a2016-06-21 11:28:38 -07003254// Verify that the connections are pinged at the right time.
3255TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
3256 rtc::ScopedFakeClock clock;
3257 int RTT_RATIO = 4;
3258 int SCHEDULING_RANGE = 200;
3259 int RTT_RANGE = 10;
3260
deadbeef14f97f52016-06-22 17:14:15 -07003261 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3262 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07003263 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07003264 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003265 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3266 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003267
3268 ASSERT_TRUE(conn != nullptr);
3269 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3270
3271 // Initializing.
3272
3273 int64_t start = clock.TimeNanos();
3274 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3275 kDefaultTimeout, clock);
3276 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3277 rtc::kNumNanosecsPerMillisec /
3278 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003279 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003280
3281 // Stabilizing.
3282
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003283 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003284 int ping_sent_before = conn->num_pings_sent();
3285 start = clock.TimeNanos();
3286 // The connection becomes strong but not stable because we haven't been able
3287 // to converge the RTT.
Honghai Zhang161a5862016-10-20 11:47:02 -07003288 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3289 clock);
zhihuang435264a2016-06-21 11:28:38 -07003290 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003291 EXPECT_GE(ping_interval_ms,
3292 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3293 EXPECT_LE(
3294 ping_interval_ms,
3295 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003296
3297 // Stabilized.
3298
3299 // The connection becomes stable after receiving more than RTT_RATIO rtt
3300 // samples.
3301 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003302 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003303 }
3304 ping_sent_before = conn->num_pings_sent();
3305 start = clock.TimeNanos();
Honghai Zhang161a5862016-10-20 11:47:02 -07003306 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3307 clock);
zhihuang435264a2016-06-21 11:28:38 -07003308 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003309 EXPECT_GE(ping_interval_ms,
3310 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3311 EXPECT_LE(
3312 ping_interval_ms,
3313 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003314
3315 // Destabilized.
3316
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003317 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003318 // Create a in-flight ping.
3319 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3320 start = clock.TimeNanos();
3321 // In-flight ping timeout and the connection will be unstable.
3322 SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003323 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3324 kMediumTimeout, clock);
zhihuang435264a2016-06-21 11:28:38 -07003325 int64_t duration_ms =
3326 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3327 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3328 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3329 // The connection become unstable due to not receiving ping responses.
3330 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003331 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3332 clock);
zhihuang435264a2016-06-21 11:28:38 -07003333 // The interval is expected to be
honghaiz7252a002016-11-08 20:04:09 -08003334 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
zhihuang435264a2016-06-21 11:28:38 -07003335 start = clock.TimeNanos();
3336 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003337 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3338 clock);
zhihuang435264a2016-06-21 11:28:38 -07003339 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003340 EXPECT_GE(ping_interval_ms,
3341 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3342 EXPECT_LE(
3343 ping_interval_ms,
3344 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003345}
3346
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003347// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003348// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003349TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3350 rtc::ScopedFakeClock clock;
3351
3352 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3353 P2PTransportChannel ch("TestChannel", 1, &pa);
3354 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003355 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003356 ch.MaybeStartGathering();
3357 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3358 kDefaultTimeout);
3359
3360 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003361 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003362 IceMessage request;
3363 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003364 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3365 STUN_ATTR_USERNAME, kIceUfrag[1]));
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003366 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3367 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003368 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003369 Port* port = GetPort(&ch);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003370 ASSERT_NE(nullptr, port);
3371 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3372 &request, kIceUfrag[1], false);
3373 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3374 ASSERT_NE(nullptr, conn);
3375
3376 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003377 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003378 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3379 EXPECT_EQ(0, conn->num_pings_sent());
3380
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003381 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003382 // the first ping is sent as soon as possible, within one simulated clock
3383 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003384 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003385 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3386}
3387
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003388TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003389 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3390 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003391 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003392 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003393 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3394 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003395
deadbeef14f97f52016-06-22 17:14:15 -07003396 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3397 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003398 ASSERT_TRUE(conn1 != nullptr);
3399 ASSERT_TRUE(conn2 != nullptr);
3400
guoweis36f01372016-03-02 18:02:40 -08003401 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3402 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003403 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003404 ASSERT_TRUE(conn1->writable());
3405 conn1->ReceivedPing();
3406
3407 // Ping received, but the connection is already writable, so no
3408 // "triggered check" and conn2 is pinged before conn1 because it has
3409 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003410 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003411}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003412
honghaiz079a7a12016-06-22 16:26:29 -07003413TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003414 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3415 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003416 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003417 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003418 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003419
deadbeef14f97f52016-06-22 17:14:15 -07003420 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003421 ASSERT_TRUE(conn1 != nullptr);
3422
3423 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3424 conn1->Prune(); // A pruned connection may still be pingable.
3425 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3426 conn1->FailAndPrune();
3427 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3428}
3429
Honghai Zhang1590c392016-05-24 13:15:02 -07003430TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003431 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3432 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003433 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003434 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003435 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3436 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003437 ASSERT_TRUE(conn1 != nullptr);
3438 // Pruning the connection reduces the set of active connections and changes
3439 // the channel state.
3440 conn1->Prune();
zhihuangd06adf62017-01-12 15:58:31 -08003441 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3442 kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003443}
3444
honghaiza54a0802015-12-16 18:37:23 -08003445// Test adding remote candidates with different ufrags. If a remote candidate
3446// is added with an old ufrag, it will be discarded. If it is added with a
3447// ufrag that was not seen before, it will be used to create connections
3448// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003449// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003450// ufrag, its pwd and generation will be set properly.
3451TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003452 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3453 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003454 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003455 ch.MaybeStartGathering();
3456 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003457 ch.AddRemoteCandidate(
3458 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3459 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003460 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003461 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003462 EXPECT_EQ(kIceUfrag[2], candidate.username());
3463 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003464 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003465
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003466 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003467 // This should set the ICE pwd in the remote candidate of |conn1|, making
3468 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003469 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003470 EXPECT_EQ(kIceUfrag[2], candidate.username());
3471 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003472 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003473
3474 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003475 ch.AddRemoteCandidate(
3476 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003477 rtc::Thread::Current()->ProcessMessages(500);
3478 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3479
3480 // Add a candidate with the current ufrag, its pwd and generation will be
3481 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003482 ch.AddRemoteCandidate(
3483 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3484 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003485 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003486 kMediumTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07003487 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003488 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3489 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003490
3491 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003492 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003493 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3494 candidate.username() == kIceUfrag[2]);
3495 if (candidate.username() == kIceUfrag[1]) {
3496 EXPECT_EQ(kIcePwd[1], candidate.password());
3497 } else if (candidate.username() == kIceUfrag[2]) {
3498 EXPECT_EQ(kIcePwd[2], candidate.password());
3499 }
3500 }
honghaiza54a0802015-12-16 18:37:23 -08003501}
3502
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003503TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003504 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3505 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003506 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003507 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003508
3509 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003510 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3511 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003512 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003513 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003514
3515 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003516 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003517 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3518 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003519 ASSERT_TRUE(conn2 != nullptr);
3520 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003521 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003522
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003523 // Wait for conn1 to be pruned.
Honghai Zhang161a5862016-10-20 11:47:02 -07003524 EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003525 // Destroy the connection to test SignalUnknownAddress.
3526 conn1->Destroy();
honghaize58d73d2016-10-24 16:38:26 -07003527 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
3528 kMediumTimeout);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003529
3530 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003531 IceMessage request;
3532 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003533 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3534 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003535 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3536 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003537 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003538 EXPECT_NE(prflx_priority, remote_priority);
3539
sprang716978d2016-10-11 06:43:28 -07003540 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003541 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003542 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3543 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003544 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3545 ASSERT_TRUE(conn1 != nullptr);
3546 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3547
3548 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003549 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3550 &request, kIceUfrag[1], false);
3551 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003552 ASSERT_TRUE(conn3 != nullptr);
3553 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3554}
Peter Thatcher54360512015-07-08 11:08:35 -07003555
3556TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
honghaize58d73d2016-10-24 16:38:26 -07003557 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003558 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3559 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003560 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003561 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003562 // small.
3563 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003564 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003565 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Peter Thatcher54360512015-07-08 11:08:35 -07003566 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003567 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003568 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003569 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaize58d73d2016-10-24 16:38:26 -07003570 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003571 ASSERT_TRUE(conn1 != nullptr);
3572
honghaize58d73d2016-10-24 16:38:26 -07003573 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Peter Thatcher54360512015-07-08 11:08:35 -07003574 conn1->ReceivedPing();
3575 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
honghaize58d73d2016-10-24 16:38:26 -07003576 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
3577 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003578}
honghaiz5a3acd82015-08-20 15:53:17 -07003579
Honghai Zhang572b0942016-06-23 12:26:57 -07003580// The controlled side will select a connection as the "selected connection"
3581// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003582// point the controlled side will select that connection as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003583// "selected connection". Plus, SignalSelectedCandidatePair will be fired if the
3584// selected connection changes and SignalReadyToSend will be fired if the new
3585// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003586TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003587 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3588 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003589 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003590 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003591 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003592 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3593 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003594 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003595 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003596 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003597 int last_packet_id = 0;
3598 const char* data = "ABCDEFGH";
3599 int len = static_cast<int>(strlen(data));
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003600 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003601 EXPECT_EQ(-1, last_sent_packet_id());
3602
3603 // A connection needs to be writable before it is selected for transmission.
3604 conn1->ReceivedPingResponse(LOW_RTT, "id");
3605 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
3606 EXPECT_EQ(conn1, last_selected_candidate_pair());
3607 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
3608
honghaiz5a3acd82015-08-20 15:53:17 -07003609 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003610 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003611 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3612 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003613 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003614 conn2->ReceivedPingResponse(LOW_RTT, "id");
3615 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003616 EXPECT_EQ(conn2, last_selected_candidate_pair());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003617 EXPECT_TRUE(channel_ready_to_send());
3618 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003619
3620 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003621 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003622 // its priority is lower.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003623 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003624 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3625 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003626 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003627 // Because it has a lower priority, the selected connection is still conn2.
3628 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003629 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003630 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003631 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003632 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003633 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07003634 EXPECT_EQ(conn3, last_selected_candidate_pair());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003635 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003636 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003637
Honghai Zhang572b0942016-06-23 12:26:57 -07003638 // Even if another higher priority candidate arrives, it will not be set as
3639 // the selected connection because the selected connection is nominated by
3640 // the controlling side.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003641 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003642 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3643 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003644 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003645 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003646 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003647 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003648 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003649 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003650 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003651 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003652 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003653 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003654 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003655 EXPECT_EQ(conn4, last_selected_candidate_pair());
3656 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003657 // SignalReadyToSend is fired again because conn4 is writable.
3658 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003659}
3660
Honghai Zhang572b0942016-06-23 12:26:57 -07003661// The controlled side will select a connection as the "selected connection"
3662// based on requests from an unknown address before the controlling side
3663// nominates a connection, and will nominate a connection from an unknown
3664// address if the request contains the use_candidate attribute. Plus, it will
3665// also sends back a ping response and set the ICE pwd in the remote candidate
3666// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003667TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003668 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3669 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003670 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003671 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003672 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003673 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003674 IceMessage request;
3675 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003676 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3677 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003678 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3679 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003680 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003681 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
deadbeef14f97f52016-06-22 17:14:15 -07003682 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3683 &request, kIceUfrag[1], false);
3684 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003685 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003686 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003687 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003688 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003689 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003690 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003691
3692 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003693 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3694 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003695 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003696 // Because it has a lower priority, the selected connection is still conn1.
3697 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003698 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003699 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003700 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3701 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003702 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003703
Honghai Zhang572b0942016-06-23 12:26:57 -07003704 // Another request with unknown address, it will not be set as the selected
3705 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003706 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003707 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3708 &request, kIceUfrag[1], false);
3709 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003710 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003711 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003712 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003713 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003714 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003715
3716 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003717 // selected as the selected connection.
zsteinf42cc9d2017-03-27 16:17:19 -07003718 request.AddAttribute(
3719 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
deadbeef14f97f52016-06-22 17:14:15 -07003720 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3721 &request, kIceUfrag[1], false);
3722 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003723 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003724 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003725 // conn4 is not the selected connection yet because it is not writable.
3726 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003727 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003728 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003729
3730 // Test that the request from an unknown address contains a ufrag from an old
3731 // generation.
3732 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003733 ch.SetRemoteIceParameters(kIceParams[2]);
3734 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003735 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3736 &request, kIceUfrag[2], false);
3737 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003738 ASSERT_TRUE(conn5 != nullptr);
3739 EXPECT_TRUE(port->sent_binding_response());
3740 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003741}
3742
Honghai Zhang572b0942016-06-23 12:26:57 -07003743// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003744// based on media received until the controlling side nominates a connection,
3745// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003746// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003747TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003748 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3749 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003750 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003751 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003752 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003753 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3754 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003755 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003756 conn1->ReceivedPingResponse(LOW_RTT, "id");
3757 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003758
Honghai Zhang572b0942016-06-23 12:26:57 -07003759 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003760 // switch to conn2 because the controlled side must mirror the media path
3761 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003762 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3763 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003764 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003765 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003766 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003767 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003768 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003769
3770 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003771 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003772 IceMessage request;
3773 request.SetType(STUN_BINDING_REQUEST);
zsteinf42cc9d2017-03-27 16:17:19 -07003774 request.AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
3775 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003776 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3777 request.AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -07003778 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, prflx_priority));
3779 request.AddAttribute(
3780 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
sprang716978d2016-10-11 06:43:28 -07003781 Port* port = GetPort(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003782 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3783 &request, kIceUfrag[1], false);
3784 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003785 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003786 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003787 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003788 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003789
Honghai Zhang572b0942016-06-23 12:26:57 -07003790 // Now another data packet will not switch the selected connection because the
3791 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003792 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003793 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz5a3acd82015-08-20 15:53:17 -07003794 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003795 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3796}
3797
3798TEST_F(P2PTransportChannelPingTest,
3799 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3800 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003801 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003802 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3803 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3804 PrepareChannel(&ch);
3805 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003806 ch.MaybeStartGathering();
3807 // The connections have decreasing priority.
3808 Connection* conn1 =
3809 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
3810 ASSERT_TRUE(conn1 != nullptr);
3811 Connection* conn2 =
3812 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
3813 ASSERT_TRUE(conn2 != nullptr);
3814
3815 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003816 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003817 EXPECT_EQ(conn1, last_selected_candidate_pair());
3818
3819 // conn2 receives data; it becomes selected.
3820 // Advance the clock by 1ms so that the last data receiving timestamp of
3821 // conn2 is larger.
3822 SIMULATED_WAIT(false, 1, clock);
3823 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003824 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003825 EXPECT_EQ(conn2, last_selected_candidate_pair());
3826
3827 // conn1 also receives data; it becomes selected due to priority again.
3828 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003829 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003830 EXPECT_EQ(conn1, last_selected_candidate_pair());
3831
Honghai Zhange05bcc22016-08-16 18:19:14 -07003832 // conn2 received data more recently; it is selected now because it
3833 // received data more recently.
3834 SIMULATED_WAIT(false, 1, clock);
3835 // Need to become writable again because it was pruned.
3836 conn2->ReceivedPingResponse(LOW_RTT, "id");
3837 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3838 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3839 EXPECT_EQ(conn2, last_selected_candidate_pair());
3840
Honghai Zhang572b0942016-06-23 12:26:57 -07003841 // Make sure sorting won't reselect candidate pair.
3842 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003843 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003844}
3845
3846TEST_F(P2PTransportChannelPingTest,
3847 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3848 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003849 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003850
3851 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3852 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3853 PrepareChannel(&ch);
3854 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003855 ch.MaybeStartGathering();
3856 // The connections have decreasing priority.
3857 Connection* conn1 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003858 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003859 ASSERT_TRUE(conn1 != nullptr);
3860 Connection* conn2 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003861 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003862 ASSERT_TRUE(conn2 != nullptr);
3863
3864 // conn1 received data; it is the selected connection.
3865 // Advance the clock to have a non-zero last-data-receiving time.
3866 SIMULATED_WAIT(false, 1, clock);
3867 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003868 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003869 EXPECT_EQ(conn1, last_selected_candidate_pair());
3870
3871 // conn2 is nominated; it becomes the selected connection.
3872 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003873 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003874 EXPECT_EQ(conn2, last_selected_candidate_pair());
3875
Honghai Zhange05bcc22016-08-16 18:19:14 -07003876 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07003877 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003878 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003879 EXPECT_EQ(conn1, last_selected_candidate_pair());
3880
Honghai Zhang572b0942016-06-23 12:26:57 -07003881 // Make sure sorting won't reselect candidate pair.
3882 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003883 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003884}
3885
3886TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003887 TestControlledAgentSelectsConnectionWithHigherNomination) {
3888 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003889 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003890
3891 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3892 P2PTransportChannel ch("test", 1, &pa);
3893 PrepareChannel(&ch);
3894 ch.SetIceRole(ICEROLE_CONTROLLED);
3895 ch.MaybeStartGathering();
3896 // The connections have decreasing priority.
3897 Connection* conn1 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003898 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003899 ASSERT_TRUE(conn1 != nullptr);
3900 Connection* conn2 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003901 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003902 ASSERT_TRUE(conn2 != nullptr);
3903
3904 // conn1 is the selected connection because it has a higher priority,
3905 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3906 kDefaultTimeout, clock);
3907 reset_selected_candidate_pair_switches();
3908
3909 // conn2 is nominated; it becomes selected.
3910 NominateConnection(conn2);
3911 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3912 EXPECT_EQ(conn2, last_selected_candidate_pair());
3913
3914 // conn1 is selected because of its priority.
3915 NominateConnection(conn1);
3916 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3917 EXPECT_EQ(conn1, last_selected_candidate_pair());
3918
3919 // conn2 gets higher remote nomination; it is selected again.
3920 NominateConnection(conn2, 2U);
3921 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3922 EXPECT_EQ(conn2, last_selected_candidate_pair());
3923
3924 // Make sure sorting won't reselect candidate pair.
3925 SIMULATED_WAIT(false, 100, clock);
3926 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3927}
3928
3929TEST_F(P2PTransportChannelPingTest,
3930 TestControlledAgentIgnoresSmallerNomination) {
3931 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07003932 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
3933
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003934 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3935 P2PTransportChannel ch("test", 1, &pa);
3936 PrepareChannel(&ch);
3937 ch.SetIceRole(ICEROLE_CONTROLLED);
3938 ch.MaybeStartGathering();
3939 Connection* conn =
3940 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3941 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
3942 EXPECT_EQ(2U, conn->remote_nomination());
3943 // Smaller nomination is ignored.
3944 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
3945 EXPECT_EQ(2U, conn->remote_nomination());
3946}
3947
3948TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07003949 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3950 rtc::ScopedFakeClock clock;
3951
3952 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3953 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3954 PrepareChannel(&ch);
3955 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003956 ch.MaybeStartGathering();
3957 // The connections have decreasing priority.
3958 Connection* conn1 =
3959 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3960 ASSERT_TRUE(conn1 != nullptr);
3961 Connection* conn2 =
3962 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3963 ASSERT_TRUE(conn2 != nullptr);
3964
3965 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003966 // There is no selected connection because no connection is writable.
3967 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003968
3969 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003970 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003971 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003972 kDefaultTimeout, clock);
3973 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(),
3974 kDefaultTimeout, clock);
3975
3976 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003977 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003978 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003979 kDefaultTimeout, clock);
3980 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3981 kDefaultTimeout, clock);
3982
3983 // Make sure sorting won't reselect candidate pair.
3984 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003985 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07003986}
honghaiz89374372015-09-24 13:14:47 -07003987
honghaiz36f50e82016-06-01 15:57:03 -07003988// Test that if a new remote candidate has the same address and port with
3989// an old one, it will be used to create a new connection.
3990TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07003991 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3992 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07003993 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07003994 ch.MaybeStartGathering();
3995 const std::string host_address = "1.1.1.1";
3996 const int port_num = 1;
3997
3998 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003999 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4000 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07004001 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004002 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004003 ASSERT_TRUE(conn1 != nullptr);
4004 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4005
4006 // Simply adding the same candidate again won't create a new connection.
4007 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004008 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004009 EXPECT_EQ(conn1, conn2);
4010
4011 // Update the ufrag of the candidate and add it again.
4012 candidate.set_username(kIceUfrag[2]);
4013 ch.AddRemoteCandidate(candidate);
4014 conn2 = GetConnectionTo(&ch, host_address, port_num);
4015 EXPECT_NE(conn1, conn2);
4016 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4017 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4018
4019 // Verify that a ping with the new ufrag can be received on the new
4020 // connection.
4021 EXPECT_EQ(0, conn2->last_ping_received());
4022 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
4023 EXPECT_TRUE(conn2->last_ping_received() > 0);
4024}
4025
Honghai Zhang572b0942016-06-23 12:26:57 -07004026// When the current selected connection is strong, lower-priority connections
4027// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07004028TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004029 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07004030 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004031 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4032 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07004033 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004034 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07004035 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004036 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4037 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07004038 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004039 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004040 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07004041
4042 // When a higher-priority, nominated candidate comes in, the connections with
4043 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07004044 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004045 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07004046 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004047 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4048 NominateConnection(conn2);
Honghai Zhang161a5862016-10-20 11:47:02 -07004049 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004050
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004051 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07004052 // Wait until conn2 becomes not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004053 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004054
deadbeef14f97f52016-06-22 17:14:15 -07004055 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004056 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07004057 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07004058 // The selected connection should still be conn2. Even through conn3 has lower
4059 // priority and is not receiving/writable, it is not pruned because the
4060 // selected connection is not receiving.
honghaize58d73d2016-10-24 16:38:26 -07004061 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004062 EXPECT_FALSE(conn3->pruned());
4063}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004064
Honghai Zhang572b0942016-06-23 12:26:57 -07004065TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4066 rtc::ScopedFakeClock clock;
4067 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4068 P2PTransportChannel ch("test channel", 1, &pa);
4069 PrepareChannel(&ch);
4070 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004071 ch.MaybeStartGathering();
4072 Connection* conn1 =
4073 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 100, true);
4074 ASSERT_TRUE(conn1 != nullptr);
4075 Connection* conn2 =
4076 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 200, false);
4077 ASSERT_TRUE(conn2 != nullptr);
4078 // Even if conn1 is writable, nominated, receiving data, it should not prune
4079 // conn2.
4080 NominateConnection(conn1);
4081 SIMULATED_WAIT(false, 1, clock);
4082 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
4083 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4084 EXPECT_FALSE(conn2->pruned());
4085}
4086
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004087// Test that GetState returns the state correctly.
4088TEST_F(P2PTransportChannelPingTest, TestGetState) {
honghaize58d73d2016-10-24 16:38:26 -07004089 rtc::ScopedFakeClock clock;
4090 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004091 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4092 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004093 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004094 ch.MaybeStartGathering();
zhihuangd06adf62017-01-12 15:58:31 -08004095 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
deadbeef14f97f52016-06-22 17:14:15 -07004096 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4097 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004098 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4099 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004100 ASSERT_TRUE(conn1 != nullptr);
4101 ASSERT_TRUE(conn2 != nullptr);
4102 // Now there are two connections, so the transport channel is connecting.
zhihuangd06adf62017-01-12 15:58:31 -08004103 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004104 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004105 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaize58d73d2016-10-24 16:38:26 -07004106 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004107 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004108 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08004109 // Need to wait until the channel state is updated.
zhihuangd06adf62017-01-12 15:58:31 -08004110 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
honghaize58d73d2016-10-24 16:38:26 -07004111 kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004112}
4113
4114// Test that when a low-priority connection is pruned, it is not deleted
4115// right away, and it can become active and be pruned again.
4116TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004117 rtc::ScopedFakeClock clock;
honghaize58d73d2016-10-24 16:38:26 -07004118 clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
4119
deadbeef14f97f52016-06-22 17:14:15 -07004120 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4121 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004122 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07004123 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
4124 config.receiving_switching_delay = rtc::Optional<int>(800);
4125 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004126 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004127 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004128 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004129 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004130 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004131 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07004132 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4133 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004134
4135 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07004136 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004137 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07004138 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004139 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004140 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004141 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004142 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004143 // |conn2| should not send a ping yet.
hbos06495bc2017-01-02 08:08:18 -08004144 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
zhihuangd06adf62017-01-12 15:58:31 -08004145 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004146 // Wait for |conn1| becoming not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004147 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004148 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07004149 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004150 ASSERT_TRUE(conn2 != nullptr);
hbos06495bc2017-01-02 08:08:18 -08004151 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
Honghai Zhange05bcc22016-08-16 18:19:14 -07004152 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004153 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004154 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4155 clock);
zhihuangd06adf62017-01-12 15:58:31 -08004156 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004157
4158 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004159 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004160 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4161 clock);
4162 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004163 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004164}
honghaiz77d0d6e2015-10-27 11:34:45 -07004165
4166// Test that if all connections in a channel has timed out on writing, they
4167// will all be deleted. We use Prune to simulate write_time_out.
4168TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
honghaize58d73d2016-10-24 16:38:26 -07004169 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07004170 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4171 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07004172 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07004173 ch.MaybeStartGathering();
4174 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07004175 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
honghaize58d73d2016-10-24 16:38:26 -07004176 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004177 ASSERT_TRUE(conn1 != nullptr);
4178 conn1->ReceivedPing(); // Becomes receiving
4179 conn1->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004180 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004181
4182 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07004183 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004184 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004185 ASSERT_TRUE(conn2 != nullptr);
4186 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07004187 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
honghaize58d73d2016-10-24 16:38:26 -07004188 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004189 ASSERT_TRUE(conn3 != nullptr);
4190 conn3->ReceivedPing(); // Becomes receiving
4191 // Now prune both conn2 and conn3; they will be deleted soon.
4192 conn2->Prune();
4193 conn3->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004194 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004195}
honghaiz9b669572015-11-04 12:07:44 -08004196
Honghai Zhang5a246372016-05-02 17:28:35 -07004197// Tests that after a port allocator session is started, it will be stopped
4198// when a new connection becomes writable and receiving. Also tests that if a
4199// connection belonging to an old session becomes writable, it won't stop
4200// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08004201TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07004202 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4203 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08004204 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004205 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08004206 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004207 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4208 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08004209 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004210 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004211 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4212
Honghai Zhang5a246372016-05-02 17:28:35 -07004213 // Start a new session. Even though conn1, which belongs to an older
4214 // session, becomes unwritable and writable again, it should not stop the
4215 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004216 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08004217 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07004218 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004219 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07004220 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4221
4222 // But if a new connection created from the new session becomes writable,
4223 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07004224 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4225 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08004226 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004227 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004228 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4229}
guoweis36f01372016-03-02 18:02:40 -08004230
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004231// Test that the ICE role is updated even on ports that has been removed.
4232// These ports may still have connections that need a correct role, in case that
4233// the connections on it may still receive stun pings.
4234TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07004235 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4236 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004237 // Starts with ICEROLE_CONTROLLING.
4238 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004239 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07004240 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07004241 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004242 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004243
deadbeef14f97f52016-06-22 17:14:15 -07004244 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004245 ASSERT_TRUE(conn != nullptr);
4246
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004247 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4248 // change the ICE role and expect it to be updated.
4249 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07004250 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07004251 ch.SetIceRole(ICEROLE_CONTROLLED);
4252 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004253}
4254
4255// Test that the ICE role is updated even on ports with inactive networks.
4256// These ports may still have connections that need a correct role, for the
4257// pings sent by those connections until they're replaced by newer-generation
4258// connections.
4259TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07004260 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4261 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004262 // Starts with ICEROLE_CONTROLLING.
4263 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07004264 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004265 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004266
deadbeef14f97f52016-06-22 17:14:15 -07004267 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004268 ASSERT_TRUE(conn != nullptr);
4269
4270 // Do an ICE restart, change the role, and expect the old port to have its
4271 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004272 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07004273 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004274 ch.SetIceRole(ICEROLE_CONTROLLED);
4275 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004276}
4277
4278// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07004279// will be destroyed. The port will only be destroyed after it is marked as
4280// "pruned."
4281TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07004282 rtc::ScopedFakeClock fake_clock;
4283
deadbeef14f97f52016-06-22 17:14:15 -07004284 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4285 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004286 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004287 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07004288 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004289 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004290
deadbeef14f97f52016-06-22 17:14:15 -07004291 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004292 ASSERT_TRUE(conn != nullptr);
4293
4294 // Simulate 2 minutes going by. This should be enough time for the port to
4295 // time out.
4296 for (int second = 0; second < 120; ++second) {
4297 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
4298 }
4299 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004300 // Port will not be removed because it is not pruned yet.
sprang716978d2016-10-11 06:43:28 -07004301 PortInterface* port = GetPort(&ch);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004302 ASSERT_NE(nullptr, port);
4303
4304 // If the session prunes all ports, the port will be destroyed.
4305 ch.allocator_session()->PruneAllPorts();
sprang716978d2016-10-11 06:43:28 -07004306 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004307 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004308}
4309
guoweis36f01372016-03-02 18:02:40 -08004310class P2PTransportChannelMostLikelyToWorkFirstTest
4311 : public P2PTransportChannelPingTest {
4312 public:
4313 P2PTransportChannelMostLikelyToWorkFirstTest()
4314 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4315 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004316 allocator_.reset(
4317 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4318 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004319 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4320 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004321 allocator_->set_step_delay(kMinimumStepDelay);
4322 }
4323
deadbeef14f97f52016-06-22 17:14:15 -07004324 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004325 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004326 int stable_writable_connection_ping_interval) {
deadbeef49f34fd2016-12-06 16:22:06 -08004327 channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
deadbeef14f97f52016-06-22 17:14:15 -07004328 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004329 config.prioritize_most_likely_candidate_pairs =
4330 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004331 config.stable_writable_connection_ping_interval =
4332 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004333 channel_->SetIceConfig(config);
4334 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004335 channel_->MaybeStartGathering();
4336 return *channel_.get();
4337 }
4338
deadbeef14f97f52016-06-22 17:14:15 -07004339 BasicPortAllocator* allocator() { return allocator_.get(); }
4340 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004341
4342 // This verifies the next pingable connection has the expected candidates'
4343 // types and, for relay local candidate, the expected relay protocol and ping
4344 // it.
4345 void VerifyNextPingableConnection(
4346 const std::string& local_candidate_type,
4347 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004348 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4349 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004350 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004351 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004352 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4353 }
4354 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4355 }
4356
guoweis36f01372016-03-02 18:02:40 -08004357 private:
deadbeef14f97f52016-06-22 17:14:15 -07004358 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004359 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004360 TestTurnServer turn_server_;
4361 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004362};
4363
4364// Test that Relay/Relay connections will be pinged first when no other
4365// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004366// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004367TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4368 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08004369 const int max_strong_interval = 100;
deadbeef14f97f52016-06-22 17:14:15 -07004370 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
Honghai Zhang161a5862016-10-20 11:47:02 -07004371 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004372 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4373 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004374
deadbeef14f97f52016-06-22 17:14:15 -07004375 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4376 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004377
Honghai Zhang161a5862016-10-20 11:47:02 -07004378 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004379
4380 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004381 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4382 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4383 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004384
4385 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004386 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4387 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4388 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004389 conn2->ReceivedPing();
4390 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4391
Honghai Zhang572b0942016-06-23 12:26:57 -07004392 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004393 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4394 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4395 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004396 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004397 ASSERT_TRUE(conn3->writable());
4398 conn3->ReceivedPing();
4399
honghaiz524ecc22016-05-25 12:48:31 -07004400 /*
4401
4402 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4403 the flakiness. The following test becomes flaky because we now ping the
4404 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004405 times. The selected connection may have been pinged before
4406 |max_strong_interval|, so it may not be the next connection to be pinged as
4407 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004408
Honghai Zhang572b0942016-06-23 12:26:57 -07004409 // Verify that conn3 will be the "selected connection" since it is readable
4410 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004411 // pingable connection.
Honghai Zhang161a5862016-10-20 11:47:02 -07004412 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004413 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004414 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004415 ASSERT_TRUE(conn3->writable());
4416 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004417
4418 */
guoweis36f01372016-03-02 18:02:40 -08004419}
4420
4421// Test that Relay/Relay connections will be pinged first when everything has
4422// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4423// in the first round.
4424TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4425 TestRelayRelayFirstWhenEverythingPinged) {
deadbeef14f97f52016-06-22 17:14:15 -07004426 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004427 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004428 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4429 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004430
deadbeef14f97f52016-06-22 17:14:15 -07004431 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004432 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004433
4434 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004435 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4436 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004437
4438 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004439 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004440 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004441
4442 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004443 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004444
4445 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004446 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004447
4448 // Now, every connection has been pinged once. The next one should be
4449 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004450 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004451}
4452
4453// Test that when we receive a new remote candidate, they will be tried first
4454// before we re-ping Relay/Relay connections again.
4455TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4456 TestNoStarvationOnNonRelayConnection) {
deadbeef14f97f52016-06-22 17:14:15 -07004457 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004458 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004459 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4460 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004461
deadbeef14f97f52016-06-22 17:14:15 -07004462 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004463 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004464
4465 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004466 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004467
4468 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004469 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004470
4471 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004472 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004473 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004474
4475 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004476 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004477
4478 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004479 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004480
4481 // Now, every connection has been pinged once. The next one should be
4482 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004483 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004484}
4485
4486// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4487// followed by the rest.
4488TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4489 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004490 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
4491 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08004492 config.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08004493 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
guoweis36f01372016-03-02 18:02:40 -08004494 allocator()->AddTurnServer(config);
4495
deadbeef14f97f52016-06-22 17:14:15 -07004496 P2PTransportChannel& ch = StartTransportChannel(true, 100);
Honghai Zhang161a5862016-10-20 11:47:02 -07004497 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004498 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4499 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4500 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004501
4502 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004503 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004504 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004505
4506 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004507 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004508
4509 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004510 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4511 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004512
4513 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004514 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004515}
deadbeef14f97f52016-06-22 17:14:15 -07004516
4517} // namespace cricket {