blob: 7e65b4baba93d22a4cac78b71b31705229006f04 [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"
Taylor Brandstettera1c30352016-05-13 08:15:11 -070015#include "webrtc/p2p/base/fakeportallocator.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include "webrtc/p2p/base/p2ptransportchannel.h"
17#include "webrtc/p2p/base/testrelayserver.h"
18#include "webrtc/p2p/base/teststunserver.h"
19#include "webrtc/p2p/base/testturnserver.h"
20#include "webrtc/p2p/client/basicportallocator.h"
21#include "webrtc/base/dscp.h"
deadbeefdfc42442016-06-21 14:19:48 -070022#include "webrtc/base/fakeclock.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023#include "webrtc/base/fakenetwork.h"
24#include "webrtc/base/firewallsocketserver.h"
25#include "webrtc/base/gunit.h"
26#include "webrtc/base/helpers.h"
27#include "webrtc/base/logging.h"
28#include "webrtc/base/natserver.h"
29#include "webrtc/base/natsocketfactory.h"
30#include "webrtc/base/physicalsocketserver.h"
31#include "webrtc/base/proxyserver.h"
32#include "webrtc/base/socketaddress.h"
33#include "webrtc/base/ssladapter.h"
34#include "webrtc/base/thread.h"
35#include "webrtc/base/virtualsocketserver.h"
36
deadbeef14f97f52016-06-22 17:14:15 -070037namespace {
38
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039using rtc::SocketAddress;
40
deadbeef14f97f52016-06-22 17:14:15 -070041// Default timeout for tests in this file.
42// Should be large enough for slow buildbots to run the tests reliably.
43static const int kDefaultTimeout = 10000;
44
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000045static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
46 cricket::PORTALLOCATOR_DISABLE_RELAY |
47 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070048static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000049// Addresses on the public internet.
50static const SocketAddress kPublicAddrs[2] =
51 { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
52// IPv6 Addresses on the public internet.
53static const SocketAddress kIPv6PublicAddrs[2] = {
54 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
55 SocketAddress("2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)
56};
57// For configuring multihomed clients.
Honghai Zhangfd16da22016-08-17 16:12:46 -070058static const SocketAddress kAlternateAddrs[2] = {
59 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000060// Addresses for HTTP proxy servers.
61static const SocketAddress kHttpsProxyAddrs[2] =
62 { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
63// Addresses for SOCKS proxy servers.
64static const SocketAddress kSocksProxyAddrs[2] =
65 { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
66// Internal addresses for NAT boxes.
67static const SocketAddress kNatAddrs[2] =
68 { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
69// Private addresses inside the NAT private networks.
70static const SocketAddress kPrivateAddrs[2] =
71 { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
72// For cascaded NATs, the internal addresses of the inner NAT boxes.
73static const SocketAddress kCascadedNatAddrs[2] =
74 { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
75// For cascaded NATs, private addresses inside the inner private networks.
76static const SocketAddress kCascadedPrivateAddrs[2] =
77 { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
78// The address of the public STUN server.
79static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080// The addresses for the public turn server.
Honghai Zhangb73d2692016-09-29 22:46:09 -070081static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000082 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -080083static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
84 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
86static const cricket::RelayCredentials kRelayCredentials("test", "test");
87
88// Based on ICE_UFRAG_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070089const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090// Based on ICE_PWD_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070091const char* kIcePwd[4] = {
92 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
93 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
94const cricket::IceParameters kIceParams[4] = {
95 {kIceUfrag[0], kIcePwd[0], false},
96 {kIceUfrag[1], kIcePwd[1], false},
97 {kIceUfrag[2], kIcePwd[2], false},
98 {kIceUfrag[3], kIcePwd[3], false}};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000099
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700100const uint64_t kLowTiebreaker = 11111;
101const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700103enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000104
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700105cricket::IceConfig CreateIceConfig(
106 int receiving_timeout,
107 cricket::ContinualGatheringPolicy continual_gathering_policy,
108 int backup_ping_interval = -1) {
honghaiz1f429e32015-09-28 07:57:34 -0700109 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800110 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700111 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800112 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700113 return config;
114}
115
deadbeef14f97f52016-06-22 17:14:15 -0700116cricket::Candidate CreateUdpCandidate(const std::string& type,
117 const std::string& ip,
118 int port,
119 int priority,
120 const std::string& ufrag = "") {
121 cricket::Candidate c;
122 c.set_address(rtc::SocketAddress(ip, port));
123 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
124 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
125 c.set_priority(priority);
126 c.set_username(ufrag);
127 c.set_type(type);
128 return c;
129}
130
Honghai Zhangb73d2692016-09-29 22:46:09 -0700131cricket::BasicPortAllocator* CreateBasicPortAllocator(
132 rtc::NetworkManager* network_manager,
133 const cricket::ServerAddresses& stun_servers,
134 const rtc::SocketAddress& turn_server_udp,
135 const rtc::SocketAddress& turn_server_tcp) {
136 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
137 turn_server.credentials = kRelayCredentials;
138 if (!turn_server_udp.IsNil()) {
139 turn_server.ports.push_back(
140 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP, false));
141 }
142 if (!turn_server_tcp.IsNil()) {
143 turn_server.ports.push_back(
144 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP, false));
145 }
146 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
147
148 cricket::BasicPortAllocator* allocator =
149 new cricket::BasicPortAllocator(network_manager);
150 allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
151 return allocator;
152}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700153} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700154
155namespace cricket {
156
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000157// This test simulates 2 P2P endpoints that want to establish connectivity
158// with each other over various network topologies and conditions, which can be
159// specified in each individial test.
160// A virtual network (via VirtualSocketServer) along with virtual firewalls and
161// NATs (via Firewall/NATSocketServer) are used to simulate the various network
162// conditions. We can configure the IP addresses of the endpoints,
163// block various types of connectivity, or add arbitrary levels of NAT.
164// We also run a STUN server and a relay server on the virtual network to allow
165// our typical P2P mechanisms to do their thing.
166// For each case, we expect the P2P stack to eventually settle on a specific
167// form of connectivity to the other side. The test checks that the P2P
168// negotiation successfully establishes connectivity within a certain time,
169// and that the result is what we expect.
170// Note that this class is a base class for use by other tests, who will provide
171// specialized test behavior.
172class P2PTransportChannelTestBase : public testing::Test,
173 public rtc::MessageHandler,
174 public sigslot::has_slots<> {
175 public:
176 P2PTransportChannelTestBase()
177 : main_(rtc::Thread::Current()),
178 pss_(new rtc::PhysicalSocketServer),
179 vss_(new rtc::VirtualSocketServer(pss_.get())),
180 nss_(new rtc::NATSocketServer(vss_.get())),
181 ss_(new rtc::FirewallSocketServer(nss_.get())),
182 ss_scope_(ss_.get()),
deadbeef14f97f52016-06-22 17:14:15 -0700183 stun_server_(TestStunServer::Create(main_, kStunAddr)),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeef14f97f52016-06-22 17:14:15 -0700185 socks_server1_(ss_.get(),
186 kSocksProxyAddrs[0],
187 ss_.get(),
188 kSocksProxyAddrs[0]),
189 socks_server2_(ss_.get(),
190 kSocksProxyAddrs[1],
191 ss_.get(),
192 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700194 ep1_.role_ = ICEROLE_CONTROLLING;
195 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000196
197 ServerAddresses stun_servers;
198 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700199 ep1_.allocator_.reset(
200 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
201 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700202 ep1_.metrics_observer_ =
203 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
204 ep1_.allocator_->SetMetricsObserver(ep1_.metrics_observer_);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700205 ep2_.allocator_.reset(
206 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
207 kTurnUdpIntAddr, rtc::SocketAddress()));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700208 ep2_.metrics_observer_ =
209 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
210 ep2_.allocator_->SetMetricsObserver(ep2_.metrics_observer_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000211 }
212
213 protected:
214 enum Config {
215 OPEN, // Open to the Internet
216 NAT_FULL_CONE, // NAT, no filtering
217 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
218 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
219 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
220 NAT_DOUBLE_CONE, // Double NAT, both cone
221 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
222 BLOCK_UDP, // Firewall, UDP in/out blocked
223 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
224 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
225 PROXY_HTTPS, // All traffic through HTTPS proxy
226 PROXY_SOCKS, // All traffic through SOCKS proxy
227 NUM_CONFIGS
228 };
229
230 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700231 Result(const std::string& controlling_type,
232 const std::string& controlling_protocol,
233 const std::string& controlled_type,
234 const std::string& controlled_protocol,
235 int wait)
236 : controlling_type(controlling_type),
237 controlling_protocol(controlling_protocol),
238 controlled_type(controlled_type),
239 controlled_protocol(controlled_protocol),
240 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700241
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700242 // The expected candidate type and protocol of the controlling ICE agent.
243 std::string controlling_type;
244 std::string controlling_protocol;
245 // The expected candidate type and protocol of the controlled ICE agent.
246 std::string controlled_type;
247 std::string controlled_protocol;
248 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000249 int connect_wait;
250 };
251
252 struct ChannelData {
253 bool CheckData(const char* data, int len) {
254 bool ret = false;
255 if (!ch_packets_.empty()) {
256 std::string packet = ch_packets_.front();
257 ret = (packet == std::string(data, len));
258 ch_packets_.pop_front();
259 }
260 return ret;
261 }
262
263 std::string name_; // TODO - Currently not used.
264 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700265 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 };
267
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700268 struct CandidatesData : public rtc::MessageData {
deadbeef14f97f52016-06-22 17:14:15 -0700269 CandidatesData(TransportChannel* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700270 : channel(ch), candidates(1, c) {}
deadbeef14f97f52016-06-22 17:14:15 -0700271 CandidatesData(TransportChannel* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700272 : channel(ch), candidates(cc) {}
deadbeef14f97f52016-06-22 17:14:15 -0700273 TransportChannel* channel;
274 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000275 };
276
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000277 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000278 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700279 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000280 tiebreaker_(0),
281 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700282 save_candidates_(false) {}
deadbeef14f97f52016-06-22 17:14:15 -0700283 bool HasChannel(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000284 return (ch == cd1_.ch_.get() || ch == cd2_.ch_.get());
285 }
deadbeef14f97f52016-06-22 17:14:15 -0700286 ChannelData* GetChannelData(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000287 if (!HasChannel(ch)) return NULL;
288 if (cd1_.ch_.get() == ch)
289 return &cd1_;
290 else
291 return &cd2_;
292 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000293
deadbeef14f97f52016-06-22 17:14:15 -0700294 void SetIceRole(IceRole role) { role_ = role; }
295 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200296 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
297 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000298 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
299 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200300 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 allocator_->set_step_delay(delay);
302 }
303 void SetAllowTcpListen(bool allow_tcp_listen) {
304 allocator_->set_allow_tcp_listen(allow_tcp_listen);
305 }
306
307 rtc::FakeNetworkManager network_manager_;
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700308 // |metrics_observer_| should outlive |allocator_| as the former may be
309 // used by the latter.
310 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer_;
deadbeef14f97f52016-06-22 17:14:15 -0700311 std::unique_ptr<BasicPortAllocator> allocator_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000312 ChannelData cd1_;
313 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700314 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200315 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000316 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000317 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700318 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700319 bool ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000320 };
321
deadbeef14f97f52016-06-22 17:14:15 -0700322 ChannelData* GetChannelData(TransportChannel* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000323 if (ep1_.HasChannel(channel))
324 return ep1_.GetChannelData(channel);
325 else
326 return ep2_.GetChannelData(channel);
327 }
328
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700329 IceParameters IceParamsWithRenomination(const IceParameters& ice,
330 bool renomination) {
331 IceParameters new_ice = ice;
332 new_ice.renomination = renomination;
333 return new_ice;
334 }
335
johan02bd5122016-09-20 00:23:27 -0700336 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700337 const IceConfig& ep2_config,
338 bool renomination = false) {
339 IceParameters ice_ep1_cd1_ch =
340 IceParamsWithRenomination(kIceParams[0], renomination);
341 IceParameters ice_ep2_cd1_ch =
342 IceParamsWithRenomination(kIceParams[1], renomination);
343 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
344 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
345 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
346 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700347 ep1_.cd1_.ch_->SetMetricsObserver(ep1_.metrics_observer_);
348 ep2_.cd1_.ch_->SetMetricsObserver(ep2_.metrics_observer_);
deadbeefb60a8192016-08-24 15:15:00 -0700349 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
350 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700351 ep1_.cd1_.ch_->MaybeStartGathering();
352 ep2_.cd1_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000353 }
deadbeefb60a8192016-08-24 15:15:00 -0700354
johan02bd5122016-09-20 00:23:27 -0700355 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700356 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700357 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700358 }
359
deadbeef14f97f52016-06-22 17:14:15 -0700360 P2PTransportChannel* CreateChannel(int endpoint,
361 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700362 const IceParameters& local_ice,
363 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700364 P2PTransportChannel* channel = new P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800365 "test content name", component, GetAllocator(endpoint));
deadbeef14f97f52016-06-22 17:14:15 -0700366 channel->SignalReadyToSend.connect(
367 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700368 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700369 this, &P2PTransportChannelTestBase::OnCandidateGathered);
370 channel->SignalCandidatesRemoved.connect(
371 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000372 channel->SignalReadPacket.connect(
373 this, &P2PTransportChannelTestBase::OnReadPacket);
374 channel->SignalRoleConflict.connect(
375 this, &P2PTransportChannelTestBase::OnRoleConflict);
honghaiz9ad0db52016-07-14 19:30:28 -0700376 channel->SignalSelectedCandidatePairChanged.connect(
377 this, &P2PTransportChannelTestBase::OnSelectedCandidatePairChanged);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700378 channel->SetIceParameters(local_ice);
379 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
380 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000381 }
382 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
383 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000384 return channel;
385 }
386 void DestroyChannels() {
387 ep1_.cd1_.ch_.reset();
388 ep2_.cd1_.ch_.reset();
389 ep1_.cd2_.ch_.reset();
390 ep2_.cd2_.ch_.reset();
391 }
deadbeef14f97f52016-06-22 17:14:15 -0700392 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
393 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
394 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
395 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000396
Taylor Brandstetteref184702016-06-23 17:35:47 -0700397 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700398 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700399
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000400 // Common results.
401 static const Result kLocalUdpToLocalUdp;
402 static const Result kLocalUdpToStunUdp;
403 static const Result kLocalUdpToPrflxUdp;
404 static const Result kPrflxUdpToLocalUdp;
405 static const Result kStunUdpToLocalUdp;
406 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700407 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000408 static const Result kPrflxUdpToStunUdp;
409 static const Result kLocalUdpToRelayUdp;
410 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700411 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000412 static const Result kLocalTcpToLocalTcp;
413 static const Result kLocalTcpToPrflxTcp;
414 static const Result kPrflxTcpToLocalTcp;
415
416 rtc::NATSocketServer* nat() { return nss_.get(); }
417 rtc::FirewallSocketServer* fw() { return ss_.get(); }
418
419 Endpoint* GetEndpoint(int endpoint) {
420 if (endpoint == 0) {
421 return &ep1_;
422 } else if (endpoint == 1) {
423 return &ep2_;
424 } else {
425 return NULL;
426 }
427 }
deadbeef14f97f52016-06-22 17:14:15 -0700428 PortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000429 return GetEndpoint(endpoint)->allocator_.get();
430 }
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700431 webrtc::FakeMetricsObserver* GetMetricsObserver(int endpoint) {
432 return GetEndpoint(endpoint)->metrics_observer_;
433 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000434 void AddAddress(int endpoint, const SocketAddress& addr) {
435 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
436 }
honghaize1a0c942016-02-16 14:54:56 -0800437 void AddAddress(int endpoint,
438 const SocketAddress& addr,
439 const std::string& ifname,
440 rtc::AdapterType adapter_type) {
441 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
442 adapter_type);
443 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000444 void RemoveAddress(int endpoint, const SocketAddress& addr) {
445 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700446 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000447 }
448 void SetProxy(int endpoint, rtc::ProxyType type) {
449 rtc::ProxyInfo info;
450 info.type = type;
451 info.address = (type == rtc::PROXY_HTTPS) ?
452 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
453 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
454 }
455 void SetAllocatorFlags(int endpoint, int flags) {
456 GetAllocator(endpoint)->set_flags(flags);
457 }
deadbeef14f97f52016-06-22 17:14:15 -0700458 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000459 GetEndpoint(endpoint)->SetIceRole(role);
460 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200461 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000462 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
463 }
464 bool GetRoleConflict(int endpoint) {
465 return GetEndpoint(endpoint)->role_conflict();
466 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200467 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000468 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
469 }
470 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
471 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
472 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700473
474 // Return true if the approprite parts of the expected Result, based
475 // on the local and remote candidate of ep1_ch1, match. This can be
476 // used in an EXPECT_TRUE_WAIT.
477 bool CheckCandidate1(const Result& expected) {
478 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700479 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700480 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700481 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
482 return (local_protocol == expected.controlling_protocol &&
483 remote_protocol == expected.controlled_protocol &&
484 local_type == expected.controlling_type &&
485 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700486 }
487
488 // EXPECT_EQ on the approprite parts of the expected Result, based
489 // on the local and remote candidate of ep1_ch1. This is like
490 // CheckCandidate1, except that it will provide more detail about
491 // what didn't match.
492 void ExpectCandidate1(const Result& expected) {
493 if (CheckCandidate1(expected)) {
494 return;
495 }
496
497 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700498 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700499 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700500 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
501 EXPECT_EQ(expected.controlling_type, local_type);
502 EXPECT_EQ(expected.controlled_type, remote_type);
503 EXPECT_EQ(expected.controlling_protocol, local_protocol);
504 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700505 }
506
507 // Return true if the approprite parts of the expected Result, based
508 // on the local and remote candidate of ep2_ch1, match. This can be
509 // used in an EXPECT_TRUE_WAIT.
510 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700511 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
512 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
513 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
514 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
515 return (local_protocol == expected.controlled_protocol &&
516 remote_protocol == expected.controlling_protocol &&
517 local_type == expected.controlled_type &&
518 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700519 }
520
521 // EXPECT_EQ on the approprite parts of the expected Result, based
522 // on the local and remote candidate of ep2_ch1. This is like
523 // CheckCandidate2, except that it will provide more detail about
524 // what didn't match.
525 void ExpectCandidate2(const Result& expected) {
526 if (CheckCandidate2(expected)) {
527 return;
528 }
529
530 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700531 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700532 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700533 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
534 EXPECT_EQ(expected.controlled_type, local_type);
535 EXPECT_EQ(expected.controlling_type, remote_type);
536 EXPECT_EQ(expected.controlled_protocol, local_protocol);
537 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700538 }
539
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000540 void Test(const Result& expected) {
nisse1bffc1d2016-05-02 08:18:55 -0700541 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700542 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000543
544 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700545 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000546 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL &&
547 ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700548 ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000549 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700550 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000551 ep2_ch1()->writable(),
552 expected.connect_wait,
553 1000);
nisse1bffc1d2016-05-02 08:18:55 -0700554 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000555 if (connect_time < expected.connect_wait) {
556 LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
557 } else {
558 LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
559 << expected.connect_wait << " ms)";
560 }
561
Honghai Zhang572b0942016-06-23 12:26:57 -0700562 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000563 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700564 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700565 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700566 int64_t converge_time;
567 int64_t converge_wait = 2000;
Honghai Zhang572b0942016-06-23 12:26:57 -0700568 // Verifying local and remote channel selected connection information.
569 // This is done only for the RFC 5245 as controlled agent will use
570 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
571 // EP1 result matrix.
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700572 EXPECT_TRUE_WAIT_MARGIN(
573 CheckCandidate1(expected) && CheckCandidate2(expected), converge_wait,
574 converge_wait);
575 // Also do EXPECT_EQ on each part so that failures are more verbose.
576 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700577 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000578
nisse1bffc1d2016-05-02 08:18:55 -0700579 converge_time = rtc::TimeMillis() - converge_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000580 if (converge_time < converge_wait) {
581 LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
582 } else {
583 LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
584 << converge_wait << " ms)";
585 }
586 }
587 // Try sending some data to other end.
johan02bd5122016-09-20 00:23:27 -0700588 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000589
590 // Destroy the channels, and wait for them to be fully cleaned up.
591 DestroyChannels();
592 }
593
johan02bd5122016-09-20 00:23:27 -0700594 void TestSendRecv() {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000595 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700596 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000597 int len = static_cast<int>(strlen(data));
598 // local_channel1 <==> remote_channel1
599 EXPECT_EQ_WAIT(len, SendData(ep1_ch1(), data, len), 1000);
600 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch1(), data, len), 1000);
601 EXPECT_EQ_WAIT(len, SendData(ep2_ch1(), data, len), 1000);
602 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch1(), data, len), 1000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000603 }
604 }
605
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700606 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700607 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000608 // restart the ice gathering. Finally it waits for the transport to select a
609 // new connection using the newly generated ice candidates.
610 // Before calling this function the end points must be configured.
611 void TestHandleIceUfragPasswordChanged() {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700612 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
613 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700614 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
615 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000616 1000, 1000);
617
deadbeef14f97f52016-06-22 17:14:15 -0700618 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
619 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
620 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
621 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000622
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700623 ep1_ch1()->SetIceParameters(kIceParams[2]);
624 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700625 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700626 ep2_ch1()->SetIceParameters(kIceParams[3]);
627
628 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700629 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000630
631 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep1_ch1())->generation() !=
632 old_local_candidate1->generation(),
633 1000, 1000);
634 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep2_ch1())->generation() !=
635 old_local_candidate2->generation(),
636 1000, 1000);
637 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep1_ch1())->generation() !=
638 old_remote_candidate1->generation(),
639 1000, 1000);
640 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep2_ch1())->generation() !=
641 old_remote_candidate2->generation(),
642 1000, 1000);
643 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
644 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
645 }
646
647 void TestSignalRoleConflict() {
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700648 SetIceTiebreaker(0,
649 kLowTiebreaker); // Default EP1 is in controlling state.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000650
deadbeef14f97f52016-06-22 17:14:15 -0700651 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700652 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000653
654 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700655 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000656 // Since both the channels initiated with controlling state and channel2
657 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
658 EXPECT_TRUE_WAIT(GetRoleConflict(0), 1000);
659 EXPECT_FALSE(GetRoleConflict(1));
660
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700661 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000662 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700663 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000664 ep2_ch1()->writable(),
665 1000);
666
Honghai Zhang572b0942016-06-23 12:26:57 -0700667 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
668 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000669
johan02bd5122016-09-20 00:23:27 -0700670 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000671 }
672
deadbeef14f97f52016-06-22 17:14:15 -0700673 void OnReadyToSend(TransportChannel* ch) {
674 GetEndpoint(ch)->ready_to_send_ = true;
675 }
676
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000677 // We pass the candidates directly to the other side.
deadbeef14f97f52016-06-22 17:14:15 -0700678 void OnCandidateGathered(TransportChannelImpl* ch, const Candidate& c) {
679 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000680 return;
681
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000682 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700683 GetEndpoint(ch)->saved_candidates_.push_back(
684 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000685 } else {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700686 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
687 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000688 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000689 }
honghaiz9ad0db52016-07-14 19:30:28 -0700690 void OnSelectedCandidatePairChanged(
691 TransportChannel* transport_channel,
692 CandidatePairInterface* selected_candidate_pair,
693 int last_sent_packet_id,
694 bool ready_to_send) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700695 // Do not count if it switches to nullptr. This may happen if all
696 // connections timed out.
697 if (selected_candidate_pair != nullptr) {
698 ++selected_candidate_pair_switches_;
699 }
honghaiz9ad0db52016-07-14 19:30:28 -0700700 }
701
702 int reset_selected_candidate_pair_switches() {
703 int switches = selected_candidate_pair_switches_;
704 selected_candidate_pair_switches_ = 0;
705 return switches;
706 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000707
708 void PauseCandidates(int endpoint) {
709 GetEndpoint(endpoint)->save_candidates_ = true;
710 }
711
deadbeef14f97f52016-06-22 17:14:15 -0700712 void OnCandidatesRemoved(TransportChannelImpl* ch,
713 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700714 // Candidate removals are not paused.
715 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700716 main_->Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700717 }
718
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800719 // Tcp candidate verification has to be done when they are generated.
720 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
721 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700722 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700723 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700724 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700725 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
726 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
727 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
728 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700729 } else {
730 FAIL() << "Unknown tcptype: " << candidate.tcptype();
731 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800732 }
733 }
734 }
735
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000736 void ResumeCandidates(int endpoint) {
737 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700738 for (auto& candidate : ed->saved_candidates_) {
739 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000740 }
741 ed->saved_candidates_.clear();
742 ed->save_candidates_ = false;
743 }
744
745 void OnMessage(rtc::Message* msg) {
746 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700747 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700748 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700749 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700750 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
751 if (!rch) {
752 return;
753 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700754 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700755 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700756 c.set_username("");
757 c.set_password("");
758 }
759 LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
760 << rch->component() << "): " << c.ToString();
761 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000762 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700763 break;
764 }
765 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700766 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700767 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700768 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
769 if (!rch) {
770 return;
771 }
772 for (Candidate& c : data->candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700773 LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
774 rch->RemoveRemoteCandidate(c);
775 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000776 break;
777 }
778 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000779 }
deadbeef14f97f52016-06-22 17:14:15 -0700780 void OnReadPacket(TransportChannel* channel,
781 const char* data,
782 size_t len,
783 const rtc::PacketTime& packet_time,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000784 int flags) {
785 std::list<std::string>& packets = GetPacketList(channel);
786 packets.push_front(std::string(data, len));
787 }
deadbeef14f97f52016-06-22 17:14:15 -0700788 void OnRoleConflict(TransportChannelImpl* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000789 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700790 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
791 ? ICEROLE_CONTROLLED
792 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000793 channel->SetIceRole(new_role);
794 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700795
deadbeef14f97f52016-06-22 17:14:15 -0700796 int SendData(TransportChannel* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000797 rtc::PacketOptions options;
798 return channel->SendPacket(data, len, options, 0);
799 }
deadbeef14f97f52016-06-22 17:14:15 -0700800 bool CheckDataOnChannel(TransportChannel* channel,
801 const char* data,
802 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000803 return GetChannelData(channel)->CheckData(data, len);
804 }
deadbeef14f97f52016-06-22 17:14:15 -0700805 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700806 return (ch && ch->selected_connection())
807 ? &ch->selected_connection()->local_candidate()
808 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000809 }
deadbeef14f97f52016-06-22 17:14:15 -0700810 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700811 return (ch && ch->selected_connection())
812 ? &ch->selected_connection()->remote_candidate()
813 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000814 }
deadbeef14f97f52016-06-22 17:14:15 -0700815 Endpoint* GetEndpoint(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000816 if (ep1_.HasChannel(ch)) {
817 return &ep1_;
818 } else if (ep2_.HasChannel(ch)) {
819 return &ep2_;
820 } else {
821 return NULL;
822 }
823 }
deadbeef14f97f52016-06-22 17:14:15 -0700824 P2PTransportChannel* GetRemoteChannel(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000825 if (ch == ep1_ch1())
826 return ep2_ch1();
827 else if (ch == ep1_ch2())
828 return ep2_ch2();
829 else if (ch == ep2_ch1())
830 return ep1_ch1();
831 else if (ch == ep2_ch2())
832 return ep1_ch2();
833 else
834 return NULL;
835 }
deadbeef14f97f52016-06-22 17:14:15 -0700836 std::list<std::string>& GetPacketList(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000837 return GetChannelData(ch)->ch_packets_;
838 }
839
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700840 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700841
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700842 // How does the test pass ICE parameters to the P2PTransportChannel?
843 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700844 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700845 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
846 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000847 }
848
849 void set_force_relay(bool relay) {
850 force_relay_ = relay;
851 }
852
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700853 void ConnectSignalNominated(Connection* conn) {
854 conn->SignalNominated.connect(this,
855 &P2PTransportChannelTestBase::OnNominated);
856 }
857
858 void OnNominated(Connection* conn) { nominated_ = true; }
859 bool nominated() { return nominated_; }
860
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000861 private:
862 rtc::Thread* main_;
kwiberg3ec46792016-04-27 07:22:53 -0700863 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
864 std::unique_ptr<rtc::VirtualSocketServer> vss_;
865 std::unique_ptr<rtc::NATSocketServer> nss_;
866 std::unique_ptr<rtc::FirewallSocketServer> ss_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000867 rtc::SocketServerScope ss_scope_;
deadbeef14f97f52016-06-22 17:14:15 -0700868 std::unique_ptr<TestStunServer> stun_server_;
869 TestTurnServer turn_server_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000870 rtc::SocksProxyServer socks_server1_;
871 rtc::SocksProxyServer socks_server2_;
872 Endpoint ep1_;
873 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700874 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000875 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700876 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700877
878 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000879};
880
881// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700882const P2PTransportChannelTestBase::Result
883 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
884 "udp",
885 "local",
886 "udp",
887 1000);
888const P2PTransportChannelTestBase::Result
889 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
890 "udp",
891 "stun",
892 "udp",
893 1000);
894const P2PTransportChannelTestBase::Result
895 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
896 "udp",
897 "prflx",
898 "udp",
899 1000);
900const P2PTransportChannelTestBase::Result
901 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
902 "udp",
903 "local",
904 "udp",
905 1000);
906const P2PTransportChannelTestBase::Result
907 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
908 "udp",
909 "local",
910 "udp",
911 1000);
912const P2PTransportChannelTestBase::Result
913 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
914 "udp",
915 "stun",
916 "udp",
917 1000);
918const P2PTransportChannelTestBase::Result
919 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
920 "udp",
921 "prflx",
922 "udp",
923 1000);
924const P2PTransportChannelTestBase::Result
925 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
926 "udp",
927 "stun",
928 "udp",
929 1000);
930const P2PTransportChannelTestBase::Result
931 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
932 "udp",
933 "relay",
934 "udp",
935 2000);
936const P2PTransportChannelTestBase::Result
937 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
938 "udp",
939 "relay",
940 "udp",
941 2000);
942const P2PTransportChannelTestBase::Result
943 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
944 "udp",
945 "prflx",
946 "udp",
947 2000);
948const P2PTransportChannelTestBase::Result
949 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
950 "tcp",
951 "local",
952 "tcp",
953 3000);
954const P2PTransportChannelTestBase::Result
955 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
956 "tcp",
957 "prflx",
958 "tcp",
959 3000);
960const P2PTransportChannelTestBase::Result
961 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
962 "tcp",
963 "local",
964 "tcp",
965 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000966
967// Test the matrix of all the connectivity types we expect to see in the wild.
968// Just test every combination of the configs in the Config enum.
969class P2PTransportChannelTest : public P2PTransportChannelTestBase {
970 protected:
971 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700972 void ConfigureEndpoints(Config config1,
973 Config config2,
974 int allocator_flags1,
975 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000976 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000977 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700978 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000979 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000980 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700981 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000982
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700983 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000984 }
985 void ConfigureEndpoint(int endpoint, Config config) {
986 switch (config) {
987 case OPEN:
988 AddAddress(endpoint, kPublicAddrs[endpoint]);
989 break;
990 case NAT_FULL_CONE:
991 case NAT_ADDR_RESTRICTED:
992 case NAT_PORT_RESTRICTED:
993 case NAT_SYMMETRIC:
994 AddAddress(endpoint, kPrivateAddrs[endpoint]);
995 // Add a single NAT of the desired type
996 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
997 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
998 AddClient(kPrivateAddrs[endpoint]);
999 break;
1000 case NAT_DOUBLE_CONE:
1001 case NAT_SYMMETRIC_THEN_CONE:
1002 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1003 // Add a two cascaded NATs of the desired types
1004 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1005 (config == NAT_DOUBLE_CONE) ?
1006 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
1007 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1008 rtc::NAT_OPEN_CONE)->
1009 AddClient(kCascadedPrivateAddrs[endpoint]);
1010 break;
1011 case BLOCK_UDP:
1012 case BLOCK_UDP_AND_INCOMING_TCP:
1013 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1014 case PROXY_HTTPS:
1015 case PROXY_SOCKS:
1016 AddAddress(endpoint, kPublicAddrs[endpoint]);
1017 // Block all UDP
1018 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
1019 kPublicAddrs[endpoint]);
1020 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1021 // Block TCP inbound to the endpoint
1022 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1023 kPublicAddrs[endpoint]);
1024 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1025 // Block all TCP to/from the endpoint except 80/443 out
1026 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1027 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1028 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1029 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1030 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1031 kPublicAddrs[endpoint]);
1032 } else if (config == PROXY_HTTPS) {
1033 // Block all TCP to/from the endpoint except to the proxy server
1034 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1035 kHttpsProxyAddrs[endpoint]);
1036 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1037 kPublicAddrs[endpoint]);
1038 SetProxy(endpoint, rtc::PROXY_HTTPS);
1039 } else if (config == PROXY_SOCKS) {
1040 // Block all TCP to/from the endpoint except to the proxy server
1041 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1042 kSocksProxyAddrs[endpoint]);
1043 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1044 kPublicAddrs[endpoint]);
1045 SetProxy(endpoint, rtc::PROXY_SOCKS5);
1046 }
1047 break;
1048 default:
1049 break;
1050 }
1051 }
1052};
1053
1054// Shorthands for use in the test matrix.
1055#define LULU &kLocalUdpToLocalUdp
1056#define LUSU &kLocalUdpToStunUdp
1057#define LUPU &kLocalUdpToPrflxUdp
1058#define PULU &kPrflxUdpToLocalUdp
1059#define SULU &kStunUdpToLocalUdp
1060#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001061#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001062#define PUSU &kPrflxUdpToStunUdp
1063#define LURU &kLocalUdpToRelayUdp
1064#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001065#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001066#define LTLT &kLocalTcpToLocalTcp
1067#define LTPT &kLocalTcpToPrflxTcp
1068#define PTLT &kPrflxTcpToLocalTcp
1069// TODO: Enable these once TestRelayServer can accept external TCP.
1070#define LTRT NULL
1071#define LSRS NULL
1072
1073// Test matrix. Originator behavior defined by rows, receiever by columns.
1074
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001075// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
1076// TODO: Fix NULLs caused by no HTTP proxy support.
1077// TODO: Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001078const P2PTransportChannelTest::Result*
1079 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
1080// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1081/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL, LTPT},
1082/*CO*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1083/*AD*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1084/*PO*/ {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, LTRT},
1085/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1086/*2C*/ {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, LTRT},
1087/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1088/*!U*/ {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, LTRT},
1089/*!T*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1090/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1091/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1092/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001093};
1094
1095// The actual tests that exercise all the various configurations.
1096// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001097#define P2P_TEST_DECLARATION(x, y, z) \
1098 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1099 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1100 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001101 if (kMatrix[x][y] != NULL) \
1102 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001103 else \
1104 LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001105 }
1106
1107#define P2P_TEST(x, y) \
1108 P2P_TEST_DECLARATION(x, y,)
1109
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001110#define P2P_TEST_SET(x) \
1111 P2P_TEST(x, OPEN) \
1112 P2P_TEST(x, NAT_FULL_CONE) \
1113 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1114 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1115 P2P_TEST(x, NAT_SYMMETRIC) \
1116 P2P_TEST(x, NAT_DOUBLE_CONE) \
1117 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1118 P2P_TEST(x, BLOCK_UDP) \
1119 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001120 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001121 P2P_TEST(x, PROXY_HTTPS) \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001122 P2P_TEST(x, PROXY_SOCKS)
1123
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001124P2P_TEST_SET(OPEN)
1125P2P_TEST_SET(NAT_FULL_CONE)
1126P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1127P2P_TEST_SET(NAT_PORT_RESTRICTED)
1128P2P_TEST_SET(NAT_SYMMETRIC)
1129P2P_TEST_SET(NAT_DOUBLE_CONE)
1130P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1131P2P_TEST_SET(BLOCK_UDP)
1132P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
1133P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1134P2P_TEST_SET(PROXY_HTTPS)
1135P2P_TEST_SET(PROXY_SOCKS)
1136
1137// Test that we restart candidate allocation when local ufrag&pwd changed.
1138// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001139TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001140 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001141 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001142 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001143 TestHandleIceUfragPasswordChanged();
1144 DestroyChannels();
1145}
1146
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001147// Same as above test, but with a symmetric NAT.
1148// We should end up with relay<->prflx candidate pairs, with generation "1".
1149TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1150 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1151 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001152 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001153 TestHandleIceUfragPasswordChanged();
1154 DestroyChannels();
1155}
1156
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001157// Test the operation of GetStats.
1158TEST_F(P2PTransportChannelTest, GetStats) {
deadbeefcbecd352015-09-23 11:50:27 -07001159 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001160 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001161 CreateChannels();
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001162 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1163 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001164 1000, 1000);
johan02bd5122016-09-20 00:23:27 -07001165 TestSendRecv();
deadbeef14f97f52016-06-22 17:14:15 -07001166 ConnectionInfos infos;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001167 ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001168 ASSERT_TRUE(infos.size() >= 1);
deadbeef14f97f52016-06-22 17:14:15 -07001169 ConnectionInfo* best_conn_info = nullptr;
1170 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001171 if (info.best_connection) {
1172 best_conn_info = &info;
1173 break;
1174 }
1175 }
1176 ASSERT_TRUE(best_conn_info != nullptr);
1177 EXPECT_TRUE(best_conn_info->new_connection);
1178 EXPECT_TRUE(best_conn_info->receiving);
1179 EXPECT_TRUE(best_conn_info->writable);
1180 EXPECT_FALSE(best_conn_info->timeout);
1181 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1182 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1183 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1184 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
1185 EXPECT_GT(best_conn_info->rtt, 0U);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001186 DestroyChannels();
1187}
1188
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001189// Tests that UMAs are recorded when ICE restarts while the channel
1190// is disconnected.
1191TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1192 rtc::ScopedFakeClock clock;
1193 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1194
1195 CreateChannels();
1196 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1197 ep2_ch1()->receiving() &&
1198 ep2_ch1()->writable(),
1199 kDefaultTimeout, clock);
1200
1201 // Drop all packets so that both channels become not writable.
1202 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1203 const int kWriteTimeoutDelay = 6000;
1204 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1205 kWriteTimeoutDelay, clock);
1206
1207 ep1_ch1()->SetIceParameters(kIceParams[2]);
1208 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1209 ep1_ch1()->MaybeStartGathering();
1210 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1211 webrtc::kEnumCounterIceRestart,
1212 static_cast<int>(IceRestartState::DISCONNECTED)));
1213
1214 ep2_ch1()->SetIceParameters(kIceParams[3]);
1215 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1216 ep2_ch1()->MaybeStartGathering();
1217 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1218 webrtc::kEnumCounterIceRestart,
1219 static_cast<int>(IceRestartState::DISCONNECTED)));
1220
1221 DestroyChannels();
1222}
1223
1224// Tests that UMAs are recorded when ICE restarts while the channel
1225// is connected.
1226TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1227 rtc::ScopedFakeClock clock;
1228 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1229
1230 CreateChannels();
1231 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1232 ep2_ch1()->receiving() &&
1233 ep2_ch1()->writable(),
1234 kDefaultTimeout, clock);
1235
1236 ep1_ch1()->SetIceParameters(kIceParams[2]);
1237 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1238 ep1_ch1()->MaybeStartGathering();
1239 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1240 webrtc::kEnumCounterIceRestart,
1241 static_cast<int>(IceRestartState::CONNECTED)));
1242
1243 ep2_ch1()->SetIceParameters(kIceParams[3]);
1244 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1245 ep2_ch1()->MaybeStartGathering();
1246 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1247 webrtc::kEnumCounterIceRestart,
1248 static_cast<int>(IceRestartState::CONNECTED)));
1249
1250 DestroyChannels();
1251}
1252
1253// Tests that UMAs are recorded when ICE restarts while the channel
1254// is connecting.
1255TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1256 rtc::ScopedFakeClock clock;
1257 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1258
1259 // Create the channels without waiting for them to become connected.
1260 CreateChannels();
1261
1262 ep1_ch1()->SetIceParameters(kIceParams[2]);
1263 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1264 ep1_ch1()->MaybeStartGathering();
1265 EXPECT_EQ(1, GetMetricsObserver(0)->GetEnumCounter(
1266 webrtc::kEnumCounterIceRestart,
1267 static_cast<int>(IceRestartState::CONNECTING)));
1268
1269 ep2_ch1()->SetIceParameters(kIceParams[3]);
1270 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1271 ep2_ch1()->MaybeStartGathering();
1272 EXPECT_EQ(1, GetMetricsObserver(1)->GetEnumCounter(
1273 webrtc::kEnumCounterIceRestart,
1274 static_cast<int>(IceRestartState::CONNECTING)));
1275
1276 DestroyChannels();
1277}
1278
1279// Tests that a UMA on ICE regathering is recorded when there is a network
1280// change if and only if continual gathering is enabled.
1281TEST_F(P2PTransportChannelTest,
1282 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1283 rtc::ScopedFakeClock clock;
1284 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1285
1286 // ep1 gathers continually but ep2 does not.
1287 IceConfig continual_gathering_config =
1288 CreateIceConfig(1000, GATHER_CONTINUALLY);
1289 IceConfig default_config;
1290 CreateChannels(continual_gathering_config, default_config);
1291
1292 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1293 ep2_ch1()->receiving() &&
1294 ep2_ch1()->writable(),
1295 kDefaultTimeout, clock);
1296
1297 // Adding address in ep1 will trigger continual gathering.
1298 AddAddress(0, kAlternateAddrs[0]);
1299 EXPECT_EQ_SIMULATED_WAIT(
1300 1, GetMetricsObserver(0)->GetEnumCounter(
1301 webrtc::kEnumCounterIceRegathering,
1302 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)),
1303 kDefaultTimeout, clock);
1304
1305 ep2_ch1()->SetIceParameters(kIceParams[3]);
1306 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1307 ep2_ch1()->MaybeStartGathering();
1308
1309 AddAddress(1, kAlternateAddrs[1]);
1310 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1311 // ep2 has not enabled continual gathering.
1312 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1313 webrtc::kEnumCounterIceRegathering,
1314 static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)));
1315
1316 DestroyChannels();
1317}
1318
1319// Tests that a UMA on ICE regathering is recorded when there is a network
1320// failure if and only if continual gathering is enabled.
1321TEST_F(P2PTransportChannelTest,
1322 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1323 rtc::ScopedFakeClock clock;
1324 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1325
1326 // ep1 gathers continually but ep2 does not.
1327 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1328 config1.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
1329 IceConfig config2;
1330 config2.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
1331 CreateChannels(config1, config2);
1332
1333 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1334 ep2_ch1()->receiving() &&
1335 ep2_ch1()->writable(),
1336 kDefaultTimeout, clock);
1337
1338 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1339 // Timeout value such that all connections are deleted.
1340 const int kNetworkFailureTimeout = 35000;
1341 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
1342 EXPECT_LE(1, GetMetricsObserver(0)->GetEnumCounter(
1343 webrtc::kEnumCounterIceRegathering,
1344 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1345 EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
1346 webrtc::kEnumCounterIceRegathering,
1347 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
1348
1349 DestroyChannels();
1350}
1351
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001352// Test that we properly create a connection on a STUN ping from unknown address
1353// when the signaling is slow.
1354TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001355 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001356 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001357 // Emulate no remote parameters coming in.
1358 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001359 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001360 // Only have remote parameters come in for ep2, not ep1.
1361 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001362
1363 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1364 // candidate.
1365 PauseCandidates(1);
1366
Honghai Zhange05bcc22016-08-16 18:19:14 -07001367 // Wait until the callee becomes writable to make sure that a ping request is
1368 // received by the caller before his remote ICE credentials are set.
1369 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, 3000);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001370 // Add two sets of remote ICE credentials, so that the ones used by the
1371 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001372 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1373 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001374 // The caller should have the selected connection connected to the peer
1375 // reflexive candidate.
1376 const Connection* selected_connection = nullptr;
1377 ASSERT_TRUE_WAIT(
1378 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
1379 2000);
1380 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1381 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1382 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1383 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001384
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001385 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001386 // Verify ep1's selected connection is updated to use the 'local' candidate.
1387 EXPECT_EQ_WAIT("local",
1388 ep1_ch1()->selected_connection()->remote_candidate().type(),
1389 2000);
1390 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001391 DestroyChannels();
1392}
1393
1394// Test that we properly create a connection on a STUN ping from unknown address
1395// when the signaling is slow and the end points are behind NAT.
1396TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001397 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001398 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001399 // Emulate no remote parameters coming in.
1400 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001401 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001402 // Only have remote parameters come in for ep2, not ep1.
1403 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001404 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1405 // candidate.
1406 PauseCandidates(1);
1407
Honghai Zhange05bcc22016-08-16 18:19:14 -07001408 // Wait until the callee becomes writable to make sure that a ping request is
1409 // received by the caller before his remote ICE credentials are set.
1410 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, 3000);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001411 // Add two sets of remote ICE credentials, so that the ones used by the
1412 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001413 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1414 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001415
1416 // The caller's selected connection should be connected to the peer reflexive
1417 // candidate.
1418 const Connection* selected_connection = nullptr;
1419 ASSERT_TRUE_WAIT(
1420 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
1421 2000);
1422 EXPECT_EQ("prflx", selected_connection->remote_candidate().type());
1423 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1424 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1425 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001426
1427 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001428
Honghai Zhange05bcc22016-08-16 18:19:14 -07001429 EXPECT_EQ_WAIT("prflx",
1430 ep1_ch1()->selected_connection()->remote_candidate().type(),
1431 2000);
1432 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001433 DestroyChannels();
1434}
1435
deadbeef0af180b2016-06-21 13:15:32 -07001436// Test that we properly create a connection on a STUN ping from unknown address
1437// when the signaling is slow, even if the new candidate is created due to the
1438// remote peer doing an ICE restart, pairing this candidate across generations.
1439//
1440// Previously this wasn't working due to a bug where the peer reflexive
1441// candidate was only updated for the newest generation candidate pairs, and
1442// not older-generation candidate pairs created by pairing candidates across
1443// generations. This resulted in the old-generation prflx candidate being
1444// prioritized above new-generation candidate pairs.
1445TEST_F(P2PTransportChannelTest,
1446 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1447 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1448 kDefaultPortAllocatorFlags);
1449 // Only gather relay candidates, so that when the prflx candidate arrives
1450 // it's prioritized above the current candidate pair.
deadbeef14f97f52016-06-22 17:14:15 -07001451 GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
1452 GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001453 // Setting this allows us to control when SetRemoteIceParameters is called.
1454 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001455 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001456 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001457 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1458 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001459 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1460 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1461 kDefaultTimeout);
1462
1463 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001464 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001465 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001466 ep2_ch1()->SetIceParameters(kIceParams[3]);
1467
1468 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001469 ep2_ch1()->MaybeStartGathering();
1470
Honghai Zhang572b0942016-06-23 12:26:57 -07001471 // The caller should have the selected connection connected to the peer
1472 // reflexive candidate.
deadbeef0af180b2016-06-21 13:15:32 -07001473 EXPECT_EQ_WAIT("prflx",
Honghai Zhang572b0942016-06-23 12:26:57 -07001474 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001475 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001476 const Connection* prflx_selected_connection =
1477 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001478
1479 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001480 ep1_ch1()->SetIceParameters(kIceParams[2]);
1481
1482 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001483 ep1_ch1()->MaybeStartGathering();
1484
1485 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1486 // their information to update the peer reflexive candidate.
1487 ResumeCandidates(1);
1488
1489 EXPECT_EQ_WAIT("relay",
Honghai Zhang572b0942016-06-23 12:26:57 -07001490 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001491 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001492 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001493 DestroyChannels();
1494}
1495
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001496// Test that if remote candidates don't have ufrag and pwd, we still work.
1497TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001498 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001499 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001500 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001501 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001502 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001503 // Wait until the callee's connections are created.
Honghai Zhang572b0942016-06-23 12:26:57 -07001504 WAIT((selected_connection = ep2_ch1()->selected_connection()) != NULL, 1000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001505 // Wait to see if they get culled; they shouldn't.
Honghai Zhang572b0942016-06-23 12:26:57 -07001506 WAIT(ep2_ch1()->selected_connection() != selected_connection, 1000);
1507 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001508 DestroyChannels();
1509}
1510
1511// Test that a host behind NAT cannot be reached when incoming_only
1512// is set to true.
1513TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
deadbeefcbecd352015-09-23 11:50:27 -07001514 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001515 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001516
1517 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001518 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001519 ep1_ch1()->set_incoming_only(true);
1520
1521 // Pump for 1 second and verify that the channels are not connected.
1522 rtc::Thread::Current()->ProcessMessages(1000);
1523
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001524 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001525 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001526 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001527 EXPECT_FALSE(ep2_ch1()->writable());
1528
1529 DestroyChannels();
1530}
1531
1532// Test that a peer behind NAT can connect to a peer that has
1533// incoming_only flag set.
1534TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
deadbeefcbecd352015-09-23 11:50:27 -07001535 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001536 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001537
1538 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001539 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001540 ep1_ch1()->set_incoming_only(true);
1541
1542 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001543 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1544 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001545 1000, 1000);
1546
1547 DestroyChannels();
1548}
1549
1550TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
1551 AddAddress(0, kPublicAddrs[0]);
1552 AddAddress(1, kPublicAddrs[1]);
1553
1554 SetAllocationStepDelay(0, kMinimumStepDelay);
1555 SetAllocationStepDelay(1, kMinimumStepDelay);
1556
deadbeef14f97f52016-06-22 17:14:15 -07001557 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1558 PORTALLOCATOR_DISABLE_STUN |
1559 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001560 // Disable all protocols except TCP.
1561 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1562 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1563
1564 SetAllowTcpListen(0, true); // actpass.
1565 SetAllowTcpListen(1, false); // active.
1566
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001567 // We want SetRemoteIceParameters to be called as it normally would.
1568 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001569 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001570 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001571
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001572 // Pause candidate so we could verify the candidate properties.
1573 PauseCandidates(0);
1574 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001575 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001576
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001577 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001578 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1579 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001580
1581 // Resume candidates.
1582 ResumeCandidates(0);
1583 ResumeCandidates(1);
1584
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001585 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1586 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001587 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07001588 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1589 ep2_ch1()->selected_connection() &&
1590 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1591 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001592
johan02bd5122016-09-20 00:23:27 -07001593 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001594 DestroyChannels();
1595}
1596
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001597TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001598 AddAddress(0, kPublicAddrs[0]);
1599 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001600 TestSignalRoleConflict();
1601}
1602
1603// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1604// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001605TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001606 AddAddress(0, kPublicAddrs[0]);
1607 AddAddress(1, kPublicAddrs[1]);
1608
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001609 // Give the first connection the higher tiebreaker so its role won't
1610 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001611 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001612 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001613 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001614 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001615
johan02bd5122016-09-20 00:23:27 -07001616 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001617
1618 EXPECT_EQ_WAIT(2u, ep1_ch1()->ports().size(), 1000);
1619
deadbeef14f97f52016-06-22 17:14:15 -07001620 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001621 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001622 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001623 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001624 }
1625
deadbeef14f97f52016-06-22 17:14:15 -07001626 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001627 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001628
deadbeef14f97f52016-06-22 17:14:15 -07001629 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001630 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001631 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001632 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001633 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001634 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001635 }
1636
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001637 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001638 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001639 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001640 ep2_ch1()->writable(),
1641 1000);
1642
Honghai Zhang572b0942016-06-23 12:26:57 -07001643 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1644 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001645
johan02bd5122016-09-20 00:23:27 -07001646 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001647 DestroyChannels();
1648}
1649
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001650// Verify that we can set DSCP value and retrieve properly from P2PTC.
1651TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1652 AddAddress(0, kPublicAddrs[0]);
1653 AddAddress(1, kPublicAddrs[1]);
1654
johan02bd5122016-09-20 00:23:27 -07001655 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001656 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1657 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1658 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1659 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1660 GetEndpoint(0)->cd1_.ch_->SetOption(
1661 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1662 GetEndpoint(1)->cd1_.ch_->SetOption(
1663 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1664 EXPECT_EQ(rtc::DSCP_CS6,
1665 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1666 EXPECT_EQ(rtc::DSCP_CS6,
1667 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1668 GetEndpoint(0)->cd1_.ch_->SetOption(
1669 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1670 GetEndpoint(1)->cd1_.ch_->SetOption(
1671 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1672 EXPECT_EQ(rtc::DSCP_AF41,
1673 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1674 EXPECT_EQ(rtc::DSCP_AF41,
1675 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1676}
1677
1678// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001679TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001680 AddAddress(0, kIPv6PublicAddrs[0]);
1681 AddAddress(0, kPublicAddrs[0]);
1682 AddAddress(1, kIPv6PublicAddrs[1]);
1683 AddAddress(1, kPublicAddrs[1]);
1684
1685 SetAllocationStepDelay(0, kMinimumStepDelay);
1686 SetAllocationStepDelay(1, kMinimumStepDelay);
1687
1688 // Enable IPv6
deadbeef14f97f52016-06-22 17:14:15 -07001689 SetAllocatorFlags(0, PORTALLOCATOR_ENABLE_IPV6);
1690 SetAllocatorFlags(1, PORTALLOCATOR_ENABLE_IPV6);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001691
johan02bd5122016-09-20 00:23:27 -07001692 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001693
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001694 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1695 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001696 1000);
1697 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001698 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001699 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1700 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1701
johan02bd5122016-09-20 00:23:27 -07001702 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001703 DestroyChannels();
1704}
1705
1706// Testing forceful TURN connections.
1707TEST_F(P2PTransportChannelTest, TestForceTurn) {
deadbeefcbecd352015-09-23 11:50:27 -07001708 ConfigureEndpoints(
1709 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001710 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1711 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001712 set_force_relay(true);
1713
1714 SetAllocationStepDelay(0, kMinimumStepDelay);
1715 SetAllocationStepDelay(1, kMinimumStepDelay);
1716
johan02bd5122016-09-20 00:23:27 -07001717 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001718
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001719 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1720 ep2_ch1()->receiving() && ep2_ch1()->writable(),
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001721 2000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001722
Honghai Zhang572b0942016-06-23 12:26:57 -07001723 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1724 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001725
1726 EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
1727 EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
1728 EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
1729 EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
1730
johan02bd5122016-09-20 00:23:27 -07001731 TestSendRecv();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001732 DestroyChannels();
1733}
1734
honghaiz98db68f2015-09-29 07:58:17 -07001735// Test that if continual gathering is set to true, ICE gathering state will
1736// not change to "Complete", and vice versa.
1737TEST_F(P2PTransportChannelTest, TestContinualGathering) {
1738 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1739 kDefaultPortAllocatorFlags);
1740 SetAllocationStepDelay(0, kDefaultStepDelay);
1741 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07001742 IceConfig continual_gathering_config =
1743 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001744 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07001745 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07001746 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07001747
1748 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1749 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1750 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1751 1000, 1000);
deadbeef14f97f52016-06-22 17:14:15 -07001752 WAIT(IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
honghaiz98db68f2015-09-29 07:58:17 -07001753 1000);
deadbeef14f97f52016-06-22 17:14:15 -07001754 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001755 ep1_ch1()->gathering_state());
1756 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001757 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001758 ep2_ch1()->gathering_state());
1759
1760 DestroyChannels();
1761}
1762
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001763// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1764// PortAllocatorSession that has not yet finished gathering candidates.
1765TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
1766 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1767 kDefaultPortAllocatorFlags);
1768 // First create a pooled session for each endpoint.
1769 auto& allocator_1 = GetEndpoint(0)->allocator_;
1770 auto& allocator_2 = GetEndpoint(1)->allocator_;
1771 int pool_size = 1;
1772 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001773 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001774 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001775 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001776 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001777 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001778 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001779 allocator_2->GetPooledSession();
1780 ASSERT_NE(nullptr, pooled_session_1);
1781 ASSERT_NE(nullptr, pooled_session_2);
1782 // Sanity check that pooled sessions haven't gathered anything yet.
1783 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1784 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1785 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1786 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1787 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001788 CreateChannels();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001789 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1790 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1791 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1792 1000, 1000);
johan02bd5122016-09-20 00:23:27 -07001793 TestSendRecv();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001794 // Make sure the P2PTransportChannels are actually using ports from the
1795 // pooled sessions.
1796 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1797 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1798 EXPECT_NE(pooled_ports_1.end(),
1799 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001800 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001801 EXPECT_NE(pooled_ports_2.end(),
1802 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001803 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001804}
1805
1806// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1807// PortAllocatorSession that already finished gathering candidates.
1808TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
1809 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1810 kDefaultPortAllocatorFlags);
1811 // First create a pooled session for each endpoint.
1812 auto& allocator_1 = GetEndpoint(0)->allocator_;
1813 auto& allocator_2 = GetEndpoint(1)->allocator_;
1814 int pool_size = 1;
1815 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001816 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001817 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001818 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001819 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001820 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001821 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001822 allocator_2->GetPooledSession();
1823 ASSERT_NE(nullptr, pooled_session_1);
1824 ASSERT_NE(nullptr, pooled_session_2);
1825 // Wait for the pooled sessions to finish gathering before the
1826 // P2PTransportChannels try to use them.
1827 EXPECT_TRUE_WAIT(pooled_session_1->CandidatesAllocationDone() &&
1828 pooled_session_2->CandidatesAllocationDone(),
1829 kDefaultTimeout);
1830 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001831 CreateChannels();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001832 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1833 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1834 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1835 1000, 1000);
johan02bd5122016-09-20 00:23:27 -07001836 TestSendRecv();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001837 // Make sure the P2PTransportChannels are actually using ports from the
1838 // pooled sessions.
1839 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1840 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1841 EXPECT_NE(pooled_ports_1.end(),
1842 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001843 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001844 EXPECT_NE(pooled_ports_2.end(),
1845 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001846 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001847}
1848
deadbeef14f97f52016-06-22 17:14:15 -07001849// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07001850// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07001851// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07001852// TODO(deadbeef): Move this and other "presumed writable" tests into a test
1853// class that operates on a single P2PTransportChannel, once an appropriate one
1854// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07001855TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
1856 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1857 kDefaultPortAllocatorFlags);
1858 // Only configure one channel so we can control when the remote candidate
1859 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001860 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
1861 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07001862 IceConfig config;
1863 config.presume_writable_when_fully_relayed = true;
1864 ep1_ch1()->SetIceConfig(config);
1865 ep1_ch1()->MaybeStartGathering();
1866 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
1867 ep1_ch1()->gathering_state(), kDefaultTimeout);
1868 // Add two remote candidates; a host candidate (with higher priority)
1869 // and TURN candidate.
1870 ep1_ch1()->AddRemoteCandidate(
1871 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
1872 ep1_ch1()->AddRemoteCandidate(
1873 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
1874 // Expect that the TURN-TURN candidate pair will be prioritized since it's
1875 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07001876 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07001877 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1878 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1879 // Also expect that the channel instantly indicates that it's writable since
1880 // it has a TURN-TURN pair.
1881 EXPECT_TRUE(ep1_ch1()->writable());
1882 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001883 // Also make sure we can immediately send packets.
1884 const char* data = "test";
1885 int len = static_cast<int>(strlen(data));
1886 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07001887}
1888
Taylor Brandstetteref184702016-06-23 17:35:47 -07001889// Test that a TURN/peer reflexive candidate pair is also presumed writable.
1890TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
1891 rtc::ScopedFakeClock fake_clock;
1892
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001893 // We need to add artificial network delay to verify that the connection
1894 // is presumed writable before it's actually writable. Without this delay
1895 // it would become writable instantly.
1896 virtual_socket_server()->set_delay_mean(50);
1897 virtual_socket_server()->UpdateDelayDistribution();
1898
Taylor Brandstetteref184702016-06-23 17:35:47 -07001899 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1900 kDefaultPortAllocatorFlags);
1901 // We want the remote TURN candidate to show up as prflx. To do this we need
1902 // to configure the server to accept packets from an address we haven't
1903 // explicitly installed permission for.
1904 test_turn_server()->set_enable_permission_checks(false);
1905 IceConfig config;
1906 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001907 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
1908 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
1909 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
1910 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07001911 ep1_ch1()->SetIceConfig(config);
1912 ep2_ch1()->SetIceConfig(config);
1913 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
1914 // candidate as peer reflexive.
1915 PauseCandidates(1);
1916 ep1_ch1()->MaybeStartGathering();
1917 ep2_ch1()->MaybeStartGathering();
1918
1919 // Wait for the TURN<->prflx connection.
1920 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
1921 1000, fake_clock);
1922 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
1923 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1924 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1925 // Make sure that at this point the connection is only presumed writable,
1926 // not fully writable.
1927 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
1928
1929 // Now wait for it to actually become writable.
1930 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(), 1000,
1931 fake_clock);
1932
1933 // Explitly destroy channels, before fake clock is destroyed.
1934 DestroyChannels();
1935}
1936
deadbeef14f97f52016-06-22 17:14:15 -07001937// Test that a presumed-writable TURN<->TURN connection is preferred above an
1938// unreliable connection (one that has failed to be pinged for some time).
1939TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
1940 rtc::ScopedFakeClock fake_clock;
1941
1942 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1943 kDefaultPortAllocatorFlags);
1944 IceConfig config;
1945 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001946 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
1947 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
1948 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
1949 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07001950 ep1_ch1()->SetIceConfig(config);
1951 ep2_ch1()->SetIceConfig(config);
1952 ep1_ch1()->MaybeStartGathering();
1953 ep2_ch1()->MaybeStartGathering();
1954 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07001955 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1956 ep1_ch1()->selected_connection()->writable() &&
1957 ep2_ch1()->receiving() &&
1958 ep2_ch1()->writable() &&
1959 ep2_ch1()->selected_connection()->writable(),
1960 1000, fake_clock);
1961 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07001962 // Destroy the second channel and wait for the current connection on the
1963 // first channel to become "unreliable", making it no longer writable.
1964 GetEndpoint(1)->cd1_.ch_.reset();
1965 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), 10000, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001966 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07001967 // Add a remote TURN candidate. The first channel should still have a TURN
1968 // port available to make a TURN<->TURN pair that's presumed writable.
1969 ep1_ch1()->AddRemoteCandidate(
1970 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
1971 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1972 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1973 EXPECT_TRUE(ep1_ch1()->writable());
1974 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07001975 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07001976 // Explitly destroy channels, before fake clock is destroyed.
1977 DestroyChannels();
1978}
1979
deadbeefdd7fb432016-09-30 15:16:48 -07001980// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
1981// writable" connection. Previously this did not work.
1982TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
1983 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1984 kDefaultPortAllocatorFlags);
1985 // Only test one endpoint, so we can ensure the connection doesn't receive a
1986 // binding response and advance beyond being "presumed" writable.
1987 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
1988 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
1989 IceConfig config;
1990 config.presume_writable_when_fully_relayed = true;
1991 ep1_ch1()->SetIceConfig(config);
1992 ep1_ch1()->MaybeStartGathering();
1993 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
1994 ep1_ch1()->gathering_state(), kDefaultTimeout);
1995 ep1_ch1()->AddRemoteCandidate(
1996 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
1997 // Sanity checking the type of the connection.
1998 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
1999 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2000 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2001
2002 // Tell the socket server to block packets (returning EWOULDBLOCK).
2003 virtual_socket_server()->SetSendingBlocked(true);
2004 const char* data = "test";
2005 int len = static_cast<int>(strlen(data));
2006 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2007
2008 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2009 // should.
2010 GetEndpoint(0)->ready_to_send_ = false;
2011 virtual_socket_server()->SetSendingBlocked(false);
2012 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2013 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2014}
2015
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002016// Test what happens when we have 2 users behind the same NAT. This can lead
2017// to interesting behavior because the STUN server will only give out the
2018// address of the outermost NAT.
2019class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2020 protected:
2021 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
2022 ASSERT(nat_type >= NAT_FULL_CONE && nat_type <= NAT_SYMMETRIC);
2023 rtc::NATSocketServer::Translator* outer_nat =
2024 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
2025 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
2026 ConfigureEndpoint(outer_nat, 0, config1);
2027 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002028 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002029 }
2030 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
2031 int endpoint, Config config) {
2032 ASSERT(config <= NAT_SYMMETRIC);
2033 if (config == OPEN) {
2034 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2035 nat->AddClient(kPrivateAddrs[endpoint]);
2036 } else {
2037 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2038 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
2039 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
2040 kCascadedPrivateAddrs[endpoint]);
2041 }
2042 }
2043};
2044
2045TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2046 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002047 Test(
2048 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002049}
2050
2051// Test what happens when we have multiple available pathways.
2052// In the future we will try different RTTs and configs for the different
2053// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2054class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002055 public:
2056 const cricket::Connection* GetConnectionWithRemoteAddress(
2057 cricket::P2PTransportChannel* channel,
2058 const SocketAddress& address) {
2059 for (cricket::Connection* conn : channel->connections()) {
2060 if (conn->remote_candidate().address().EqualIPs(address)) {
2061 return conn;
2062 }
2063 }
2064 return nullptr;
2065 }
2066
Honghai Zhangfd16da22016-08-17 16:12:46 -07002067 cricket::Connection* GetConnectionWithLocalAddress(
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002068 cricket::P2PTransportChannel* channel,
2069 const SocketAddress& address) {
2070 for (cricket::Connection* conn : channel->connections()) {
2071 if (conn->local_candidate().address().EqualIPs(address)) {
2072 return conn;
2073 }
2074 }
2075 return nullptr;
2076 }
2077
2078 void DestroyAllButBestConnection(cricket::P2PTransportChannel* channel) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002079 const cricket::Connection* selected_connection =
2080 channel->selected_connection();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002081 for (cricket::Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002082 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002083 conn->Destroy();
2084 }
2085 }
2086 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002087};
2088
2089// Test that we can establish connectivity when both peers are multihomed.
2090TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
2091 AddAddress(0, kPublicAddrs[0]);
2092 AddAddress(0, kAlternateAddrs[0]);
2093 AddAddress(1, kPublicAddrs[1]);
2094 AddAddress(1, kAlternateAddrs[1]);
2095 Test(kLocalUdpToLocalUdp);
2096}
2097
Honghai Zhang52dce732016-03-31 12:37:31 -07002098// Test that we can quickly switch links if an interface goes down.
2099// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002100TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002101 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002102 AddAddress(0, kPublicAddrs[0]);
2103 // Adding alternate address will make sure |kPublicAddrs| has the higher
2104 // priority than others. This is due to FakeNetwork::AddInterface method.
2105 AddAddress(1, kAlternateAddrs[1]);
2106 AddAddress(1, kPublicAddrs[1]);
2107
2108 // Use only local ports for simplicity.
2109 SetAllocatorFlags(0, kOnlyLocalPorts);
2110 SetAllocatorFlags(1, kOnlyLocalPorts);
2111
deadbeefb60a8192016-08-24 15:15:00 -07002112 // Make the receiving timeout shorter for testing.
2113 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002114 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002115 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002116
honghaiz9ad0db52016-07-14 19:30:28 -07002117 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2118 ep2_ch1()->receiving() &&
2119 ep2_ch1()->writable(),
2120 3000, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002121 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2122 ep2_ch1()->selected_connection() &&
2123 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2124 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002125
2126 // Blackhole any traffic to or from the public addrs.
2127 LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002128 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002129 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002130 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2131 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002132 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002133 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002134 !selected_connection1->receiving() && !selected_connection2->receiving(),
honghaiz9ad0db52016-07-14 19:30:28 -07002135 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07002136
honghaiz9ad0db52016-07-14 19:30:28 -07002137 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002138 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002139 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2140 ep2_ch1()->selected_connection()->receiving(),
2141 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07002142 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2143 EXPECT_TRUE(
2144 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2145 EXPECT_TRUE(
2146 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2147
2148 DestroyChannels();
2149}
2150
Honghai Zhang52dce732016-03-31 12:37:31 -07002151// Test that we can quickly switch links if an interface goes down.
2152// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002153TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002154 rtc::ScopedFakeClock clock;
honghaiza58ea782015-09-24 08:13:36 -07002155 // Adding alternate address will make sure |kPublicAddrs| has the higher
2156 // priority than others. This is due to FakeNetwork::AddInterface method.
2157 AddAddress(0, kAlternateAddrs[0]);
2158 AddAddress(0, kPublicAddrs[0]);
2159 AddAddress(1, kPublicAddrs[1]);
2160
2161 // Use only local ports for simplicity.
2162 SetAllocatorFlags(0, kOnlyLocalPorts);
2163 SetAllocatorFlags(1, kOnlyLocalPorts);
2164
deadbeefb60a8192016-08-24 15:15:00 -07002165 // Make the receiving timeout shorter for testing.
2166 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002167 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002168 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002169 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2170 ep2_ch1()->receiving() &&
2171 ep2_ch1()->writable(),
2172 3000, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002173 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2174 ep2_ch1()->selected_connection() &&
2175 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2176 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002177
2178 // Blackhole any traffic to or from the public addrs.
2179 LOG(LS_INFO) << "Failing over...";
2180 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002181 // The selected connections will switch, so keep references to them.
2182 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2183 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002184 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002185 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002186 !selected_connection1->receiving() && !selected_connection2->receiving(),
honghaiz9ad0db52016-07-14 19:30:28 -07002187 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07002188
honghaiz9ad0db52016-07-14 19:30:28 -07002189 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002190 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002191 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2192 ep2_ch1()->selected_connection()->receiving(),
2193 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07002194 EXPECT_TRUE(
2195 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
2196 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2197 EXPECT_TRUE(
2198 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002199
2200 DestroyChannels();
2201}
2202
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002203// Test that when the controlling side switches the selected connection,
2204// the nomination of the selected connection on the controlled side will
2205// increase.
2206TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2207 rtc::ScopedFakeClock clock;
2208 // Adding alternate address will make sure |kPublicAddrs| has the higher
2209 // priority than others. This is due to FakeNetwork::AddInterface method.
2210 AddAddress(0, kAlternateAddrs[0]);
2211 AddAddress(0, kPublicAddrs[0]);
2212 AddAddress(1, kPublicAddrs[1]);
2213
2214 // Use only local ports for simplicity.
2215 SetAllocatorFlags(0, kOnlyLocalPorts);
2216 SetAllocatorFlags(1, kOnlyLocalPorts);
2217
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002218 // We want it to set the remote ICE parameters when creating channels.
2219 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002220 // Make the receiving timeout shorter for testing.
2221 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002222 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002223 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002224 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2225 ep2_ch1()->receiving() &&
2226 ep2_ch1()->writable(),
2227 3000, clock);
2228 EXPECT_TRUE_SIMULATED_WAIT(
2229 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2230 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2231 kDefaultTimeout, clock);
2232 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2233 Connection* selected_connection2 =
2234 const_cast<Connection*>(ep2_ch1()->selected_connection());
2235 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2236 // |selected_connection2| should not be nominated any more since the previous
2237 // nomination has been acknowledged.
2238 ConnectSignalNominated(selected_connection2);
2239 SIMULATED_WAIT(nominated(), 3000, clock);
2240 EXPECT_FALSE(nominated());
2241
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002242 // Blackhole any traffic to or from the public addrs.
2243 LOG(LS_INFO) << "Failing over...";
2244 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2245
2246 // The selected connection on the controlling side should switch.
2247 EXPECT_TRUE_SIMULATED_WAIT(
2248 ep1_ch1()->selected_connection() != selected_connection1, 3000, clock);
2249 // The connection on the controlled side should be nominated again
2250 // and have an increased nomination.
2251 EXPECT_TRUE_SIMULATED_WAIT(
2252 ep2_ch1()->selected_connection()->remote_nomination() >
2253 remote_nomination2,
2254 kDefaultTimeout, clock);
2255
2256 DestroyChannels();
2257}
2258
honghaiz9ad0db52016-07-14 19:30:28 -07002259// Test that if an interface fails temporarily and then recovers quickly,
2260// the selected connection will not switch.
2261// The case that it will switch over to the backup connection if the selected
2262// connection does not recover after enough time is covered in
2263// TestFailoverControlledSide and TestFailoverControllingSide.
2264TEST_F(P2PTransportChannelMultihomedTest,
2265 TestConnectionSwitchDampeningControlledSide) {
2266 rtc::ScopedFakeClock clock;
2267 AddAddress(0, kPublicAddrs[0]);
2268 // Adding alternate address will make sure |kPublicAddrs| has the higher
2269 // priority than others. This is due to FakeNetwork::AddInterface method.
2270 AddAddress(1, kAlternateAddrs[1]);
2271 AddAddress(1, kPublicAddrs[1]);
2272
2273 // Use only local ports for simplicity.
2274 SetAllocatorFlags(0, kOnlyLocalPorts);
2275 SetAllocatorFlags(1, kOnlyLocalPorts);
2276
2277 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002278 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002279
2280 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2281 ep2_ch1()->receiving() &&
2282 ep2_ch1()->writable(),
2283 3000, clock);
2284 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2285 ep2_ch1()->selected_connection() &&
2286 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2287 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2288
2289 // Make the receiving timeout shorter for testing.
2290 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2291 ep1_ch1()->SetIceConfig(config);
2292 ep2_ch1()->SetIceConfig(config);
2293 reset_selected_candidate_pair_switches();
2294
2295 // Blackhole any traffic to or from the public addrs.
2296 LOG(LS_INFO) << "Failing over...";
2297 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2298
2299 // The selected connections may switch, so keep references to them.
2300 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2301 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2302 // We should detect loss of receiving within 1 second or so.
2303 EXPECT_TRUE_SIMULATED_WAIT(
2304 !selected_connection1->receiving() && !selected_connection2->receiving(),
2305 3000, clock);
2306 // After a short while, the link recovers itself.
2307 SIMULATED_WAIT(false, 10, clock);
2308 fw()->ClearRules();
2309
2310 // We should remain on the public address on both sides and no connection
2311 // switches should have happened.
2312 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2313 ep2_ch1()->selected_connection()->receiving(),
2314 3000, clock);
2315 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2316 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2317 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2318
2319 DestroyChannels();
2320}
2321
2322// Test that if an interface fails temporarily and then recovers quickly,
2323// the selected connection will not switch.
2324TEST_F(P2PTransportChannelMultihomedTest,
2325 TestConnectionSwitchDampeningControllingSide) {
2326 rtc::ScopedFakeClock clock;
2327 // Adding alternate address will make sure |kPublicAddrs| has the higher
2328 // priority than others. This is due to FakeNetwork::AddInterface method.
2329 AddAddress(0, kAlternateAddrs[0]);
2330 AddAddress(0, kPublicAddrs[0]);
2331 AddAddress(1, kPublicAddrs[1]);
2332
2333 // Use only local ports for simplicity.
2334 SetAllocatorFlags(0, kOnlyLocalPorts);
2335 SetAllocatorFlags(1, kOnlyLocalPorts);
2336
2337 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002338 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002339 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2340 ep2_ch1()->receiving() &&
2341 ep2_ch1()->writable(),
2342 3000, clock);
2343 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2344 ep2_ch1()->selected_connection() &&
2345 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2346 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2347
2348 // Make the receiving timeout shorter for testing.
2349 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2350 ep1_ch1()->SetIceConfig(config);
2351 ep2_ch1()->SetIceConfig(config);
2352 reset_selected_candidate_pair_switches();
2353
2354 // Blackhole any traffic to or from the public addrs.
2355 LOG(LS_INFO) << "Failing over...";
2356 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2357 // The selected connections may switch, so keep references to them.
2358 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2359 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2360 // We should detect loss of receiving within 1 second or so.
2361 EXPECT_TRUE_SIMULATED_WAIT(
2362 !selected_connection1->receiving() && !selected_connection2->receiving(),
2363 3000, clock);
2364 // The link recovers after a short while.
2365 SIMULATED_WAIT(false, 10, clock);
2366 fw()->ClearRules();
2367
2368 // We should not switch to the alternate addr on both sides because of the
2369 // dampening.
2370 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2371 ep2_ch1()->selected_connection()->receiving(),
2372 3000, clock);
2373 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2374 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2375 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2376 DestroyChannels();
2377}
2378
Honghai Zhangfd16da22016-08-17 16:12:46 -07002379// Tests that if the remote side's network failed, it won't cause the local
2380// side to switch connections and networks.
2381TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2382 rtc::ScopedFakeClock clock;
2383 // The interface names are chosen so that |cellular| would have higher
2384 // candidate priority and higher cost.
2385 auto& wifi = kPublicAddrs;
2386 auto& cellular = kAlternateAddrs;
2387 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2388 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2389 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2390
2391 // Use only local ports for simplicity.
2392 SetAllocatorFlags(0, kOnlyLocalPorts);
2393 SetAllocatorFlags(1, kOnlyLocalPorts);
2394 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002395 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002396 // Make the receiving timeout shorter for testing.
2397 // Set the backup connection ping interval to 25s.
2398 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2399 // Ping the best connection more frequently since we don't have traffic.
2400 config.stable_writable_connection_ping_interval = 900;
2401 ep1_ch1()->SetIceConfig(config);
2402 ep2_ch1()->SetIceConfig(config);
2403 // Need to wait to make sure the connections on both networks are writable.
2404 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2405 ep2_ch1()->receiving() &&
2406 ep2_ch1()->writable(),
2407 3000, clock);
2408 EXPECT_TRUE_SIMULATED_WAIT(
2409 ep1_ch1()->selected_connection() &&
2410 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2411 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2412 kDefaultTimeout, clock);
2413 Connection* backup_conn =
2414 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2415 ASSERT_NE(nullptr, backup_conn);
2416 // After a short while, the backup connection will be writable but not
2417 // receiving because backup connection is pinged at a slower rate.
2418 EXPECT_TRUE_SIMULATED_WAIT(
2419 backup_conn->writable() && !backup_conn->receiving(), 5000, clock);
2420 reset_selected_candidate_pair_switches();
2421 // Blackhole any traffic to or from the remote WiFi networks.
2422 LOG(LS_INFO) << "Failing over...";
2423 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2424
2425 int num_switches = 0;
2426 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2427 20000, clock);
2428 EXPECT_EQ(0, num_switches);
2429 DestroyChannels();
2430}
2431
honghaize1a0c942016-02-16 14:54:56 -08002432// Tests that a Wifi-Wifi connection has the highest precedence.
2433TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2434 // The interface names are chosen so that |cellular| would have higher
2435 // candidate priority if it is not for the network type.
2436 auto& wifi = kAlternateAddrs;
2437 auto& cellular = kPublicAddrs;
2438 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2439 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2440 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2441 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2442
2443 // Use only local ports for simplicity.
2444 SetAllocatorFlags(0, kOnlyLocalPorts);
2445 SetAllocatorFlags(1, kOnlyLocalPorts);
2446
2447 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002448 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002449
2450 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2451 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2452 1000, 1000);
2453 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002454 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002455 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2456 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2457 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002458 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002459 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2460 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2461 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002462 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002463}
2464
2465// Tests that a Wifi-Cellular connection has higher precedence than
2466// a Cellular-Cellular connection.
2467TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2468 // The interface names are chosen so that |cellular| would have higher
2469 // candidate priority if it is not for the network type.
2470 auto& wifi = kAlternateAddrs;
2471 auto& cellular = kPublicAddrs;
2472 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2473 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2474 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2475
2476 // Use only local ports for simplicity.
2477 SetAllocatorFlags(0, kOnlyLocalPorts);
2478 SetAllocatorFlags(1, kOnlyLocalPorts);
2479
2480 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002481 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002482
2483 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2484 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2485 1000, 1000);
2486 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002487 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002488 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2489 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002490 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002491 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2492 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002493 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002494}
2495
Honghai Zhang381b4212015-12-04 12:24:03 -08002496// Test that the backup connection is pinged at a rate no faster than
2497// what was configured.
2498TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2499 AddAddress(0, kPublicAddrs[0]);
2500 // Adding alternate address will make sure |kPublicAddrs| has the higher
2501 // priority than others. This is due to FakeNetwork::AddInterface method.
2502 AddAddress(1, kAlternateAddrs[1]);
2503 AddAddress(1, kPublicAddrs[1]);
2504
2505 // Use only local ports for simplicity.
2506 SetAllocatorFlags(0, kOnlyLocalPorts);
2507 SetAllocatorFlags(1, kOnlyLocalPorts);
2508
2509 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002510 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002511 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2512 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2513 1000, 1000);
2514 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002515 ep2_ch1()->SetIceConfig(
2516 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002517 // After the state becomes COMPLETED, the backup connection will be pinged
2518 // once every |backup_ping_interval| milliseconds.
deadbeef14f97f52016-06-22 17:14:15 -07002519 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == STATE_COMPLETED, 1000);
2520 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002521 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002522 Connection* backup_conn = connections[1];
Honghai Zhang381b4212015-12-04 12:24:03 -08002523 EXPECT_TRUE_WAIT(backup_conn->writable(), 3000);
honghaiz34b11eb2016-03-16 08:55:44 -07002524 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002525 EXPECT_TRUE_WAIT(
2526 last_ping_response_ms < backup_conn->last_ping_response_received(), 5000);
2527 int time_elapsed =
2528 backup_conn->last_ping_response_received() - last_ping_response_ms;
2529 LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
2530 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002531
2532 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002533}
2534
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002535TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
2536 AddAddress(0, kAlternateAddrs[0]);
2537 AddAddress(0, kPublicAddrs[0]);
2538 AddAddress(1, kPublicAddrs[1]);
2539 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002540 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002541
2542 // Both transport channels will reach STATE_COMPLETED quickly.
deadbeef14f97f52016-06-22 17:14:15 -07002543 EXPECT_EQ_WAIT(TransportChannelState::STATE_COMPLETED, ep1_ch1()->GetState(),
2544 1000);
2545 EXPECT_EQ_WAIT(TransportChannelState::STATE_COMPLETED, ep2_ch1()->GetState(),
2546 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002547}
2548
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002549// Tests that when a network interface becomes inactive, if Continual Gathering
2550// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002551// will be removed from the port list of the channel, and the respective
2552// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002553TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002554 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002555 AddAddress(0, kPublicAddrs[0]);
2556 AddAddress(1, kPublicAddrs[1]);
2557 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07002558 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
2559 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07002560 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08002561
2562 SetAllocatorFlags(0, kOnlyLocalPorts);
2563 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002564 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2565 ep2_ch1()->receiving() &&
2566 ep2_ch1()->writable(),
2567 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002568 // More than one port has been created.
2569 EXPECT_LE(1U, ep1_ch1()->ports().size());
2570 // Endpoint 1 enabled continual gathering; the port will be removed
2571 // when the interface is removed.
2572 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002573 EXPECT_TRUE(ep1_ch1()->ports().empty());
2574 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002575 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2576 clock);
honghaize3c6c822016-02-17 13:00:28 -08002577
2578 size_t num_ports = ep2_ch1()->ports().size();
2579 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002580 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002581 // Endpoint 2 did not enable continual gathering; the local port will still be
2582 // removed when the interface is removed but the remote candidates on the
2583 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002584 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002585
2586 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2587 clock);
2588 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002589 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002590
2591 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002592}
2593
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002594// Tests that continual gathering will create new connections when a new
2595// interface is added.
2596TEST_F(P2PTransportChannelMultihomedTest,
2597 TestContinualGatheringOnNewInterface) {
2598 auto& wifi = kAlternateAddrs;
2599 auto& cellular = kPublicAddrs;
2600 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2601 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002602 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002603 IceConfig continual_gathering_config =
2604 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07002605 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002606 SetAllocatorFlags(0, kOnlyLocalPorts);
2607 SetAllocatorFlags(1, kOnlyLocalPorts);
2608 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2609 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2610 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002611
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002612 // Add a new wifi interface on end point 2. We should expect a new connection
2613 // to be created and the new one will be the best connection.
2614 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2615 const cricket::Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002616 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002617 conn->remote_candidate().address().EqualIPs(wifi[1]),
2618 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002619 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002620 conn->local_candidate().address().EqualIPs(wifi[1]),
2621 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002622
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002623 // Add a new cellular interface on end point 1, we should expect a new
2624 // backup connection created using this new interface.
2625 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002626 EXPECT_TRUE_WAIT(
2627 ep1_ch1()->GetState() == cricket::STATE_COMPLETED &&
2628 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2629 nullptr &&
2630 conn != ep1_ch1()->selected_connection() && conn->writable(),
2631 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002632 EXPECT_TRUE_WAIT(
2633 ep2_ch1()->GetState() == cricket::STATE_COMPLETED &&
2634 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
2635 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002636 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002637 kDefaultTimeout);
2638
2639 DestroyChannels();
2640}
2641
2642// Tests that we can switch links via continual gathering.
2643TEST_F(P2PTransportChannelMultihomedTest,
2644 TestSwitchLinksViaContinualGathering) {
2645 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002646 AddAddress(0, kPublicAddrs[0]);
2647 AddAddress(1, kPublicAddrs[1]);
2648 // Use only local ports for simplicity.
2649 SetAllocatorFlags(0, kOnlyLocalPorts);
2650 SetAllocatorFlags(1, kOnlyLocalPorts);
2651
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002652 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07002653 IceConfig continual_gathering_config =
2654 CreateIceConfig(1000, GATHER_CONTINUALLY);
2655 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002656 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002657 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2658 ep2_ch1()->receiving() &&
2659 ep2_ch1()->writable(),
2660 3000, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002661 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07002662 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002663 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2664 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2665
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002666 // Add the new address first and then remove the other one.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002667 LOG(LS_INFO) << "Draining...";
2668 AddAddress(1, kAlternateAddrs[1]);
2669 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002670 // We should switch to use the alternate address after an exchange of pings.
2671 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002672 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002673 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2674 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
2675 3000, clock);
2676
2677 // Remove one address first and then add another address.
2678 LOG(LS_INFO) << "Draining again...";
2679 RemoveAddress(1, kAlternateAddrs[1]);
2680 AddAddress(1, kAlternateAddrs[0]);
2681 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002682 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002683 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2684 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
2685 3000, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002686
2687 DestroyChannels();
2688}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002689
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002690/*
2691TODO(honghaiz) Once continual gathering fully supports
2692GATHER_CONTINUALLY_AND_RECOVER, put this test back.
2693
2694// Tests that if the backup connections are lost and then the interface with the
2695// selected connection is gone, continual gathering will restore the
2696// connectivity.
2697TEST_F(P2PTransportChannelMultihomedTest,
2698 TestBackupConnectionLostThenInterfaceGone) {
2699 rtc::ScopedFakeClock clock;
2700 auto& wifi = kAlternateAddrs;
2701 auto& cellular = kPublicAddrs;
2702 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2703 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2704 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2705 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2706 // Use only local ports for simplicity.
2707 SetAllocatorFlags(0, kOnlyLocalPorts);
2708 SetAllocatorFlags(1, kOnlyLocalPorts);
2709
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002710 // Set continual gathering policy.
2711 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER);
deadbeefb60a8192016-08-24 15:15:00 -07002712 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002713 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002714 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2715 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2716 3000, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002717 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2718 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002719 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2720 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2721
2722 // First destroy all backup connection.
2723 DestroyAllButBestConnection(ep1_ch1());
2724
2725 SIMULATED_WAIT(false, 10, clock);
2726 // Then the interface of the best connection goes away.
2727 RemoveAddress(0, wifi[0]);
2728 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002729 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002730 LocalCandidate(ep1_ch1())->address().EqualIPs(cellular[0]) &&
2731 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2732 3000, clock);
2733
2734 DestroyChannels();
2735}
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002736*/
2737
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002738// Tests that the backup connection will be restored after it is destroyed.
2739TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
2740 rtc::ScopedFakeClock clock;
2741 auto& wifi = kAlternateAddrs;
2742 auto& cellular = kPublicAddrs;
2743 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2744 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2745 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2746 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2747 // Use only local ports for simplicity.
2748 SetAllocatorFlags(0, kOnlyLocalPorts);
2749 SetAllocatorFlags(1, kOnlyLocalPorts);
2750
2751 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002752 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2753 config.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
johan02bd5122016-09-20 00:23:27 -07002754 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002755 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2756 ep2_ch1()->receiving() &&
2757 ep2_ch1()->writable(),
2758 3000, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002759 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2760 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002761 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2762 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2763
2764 // Destroy all backup connections.
2765 DestroyAllButBestConnection(ep1_ch1());
2766 // Ensure the backup connection is removed first.
2767 EXPECT_TRUE_SIMULATED_WAIT(
2768 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
2769 kDefaultTimeout, clock);
2770 const cricket::Connection* conn;
2771 EXPECT_TRUE_SIMULATED_WAIT(
2772 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2773 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002774 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002775 5000, clock);
2776
2777 DestroyChannels();
2778}
2779
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002780// A collection of tests which tests a single P2PTransportChannel by sending
2781// pings.
2782class P2PTransportChannelPingTest : public testing::Test,
2783 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002784 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002785 P2PTransportChannelPingTest()
2786 : pss_(new rtc::PhysicalSocketServer),
2787 vss_(new rtc::VirtualSocketServer(pss_.get())),
2788 ss_scope_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002789
2790 protected:
deadbeef14f97f52016-06-22 17:14:15 -07002791 void PrepareChannel(P2PTransportChannel* ch) {
2792 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002793 ch->SetIceParameters(kIceParams[0]);
2794 ch->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhang52dce732016-03-31 12:37:31 -07002795 ch->SignalSelectedCandidatePairChanged.connect(
2796 this, &P2PTransportChannelPingTest::OnSelectedCandidatePairChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07002797 ch->SignalReadyToSend.connect(this,
2798 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07002799 ch->SignalStateChanged.connect(
2800 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002801 }
2802
deadbeef14f97f52016-06-22 17:14:15 -07002803 Connection* WaitForConnectionTo(P2PTransportChannel* ch,
2804 const std::string& ip,
Honghai Zhange05bcc22016-08-16 18:19:14 -07002805 int port_num,
2806 rtc::FakeClock* clock = nullptr) {
2807 if (clock == nullptr) {
2808 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr, 3000);
2809 } else {
2810 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
2811 3000, *clock);
2812 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002813 return GetConnectionTo(ch, ip, port_num);
2814 }
2815
deadbeef14f97f52016-06-22 17:14:15 -07002816 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002817 if (ch->ports().empty()) {
2818 return nullptr;
2819 }
deadbeef14f97f52016-06-22 17:14:15 -07002820 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002821 }
2822
Honghai Zhanga74363c2016-07-28 18:06:15 -07002823 Port* GetPrunedPort(P2PTransportChannel* ch) {
2824 if (ch->pruned_ports().empty()) {
2825 return nullptr;
2826 }
2827 return static_cast<Port*>(ch->pruned_ports()[0]);
2828 }
2829
deadbeef14f97f52016-06-22 17:14:15 -07002830 Connection* GetConnectionTo(P2PTransportChannel* ch,
2831 const std::string& ip,
2832 int port_num) {
2833 Port* port = GetPort(ch);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002834 if (!port) {
2835 return nullptr;
2836 }
2837 return port->GetConnection(rtc::SocketAddress(ip, port_num));
2838 }
2839
deadbeef14f97f52016-06-22 17:14:15 -07002840 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
2841 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08002842 if (conn) {
2843 ch->MarkConnectionPinged(conn);
2844 }
2845 return conn;
2846 }
2847
deadbeef14f97f52016-06-22 17:14:15 -07002848 int SendData(TransportChannel& channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07002849 const char* data,
2850 size_t len,
2851 int packet_id) {
2852 rtc::PacketOptions options;
2853 options.packet_id = packet_id;
2854 return channel.SendPacket(data, len, options, 0);
2855 }
2856
Honghai Zhang572b0942016-06-23 12:26:57 -07002857 Connection* CreateConnectionWithCandidate(P2PTransportChannel& channel,
2858 rtc::ScopedFakeClock& clock,
2859 const std::string& ip_addr,
2860 int port,
2861 int priority,
2862 bool writable) {
2863 channel.AddRemoteCandidate(
2864 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
2865 EXPECT_TRUE_SIMULATED_WAIT(
2866 GetConnectionTo(&channel, ip_addr, port) != nullptr, 3000, clock);
2867 Connection* conn = GetConnectionTo(&channel, ip_addr, port);
2868
2869 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002870 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07002871 }
2872 return conn;
2873 }
2874
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002875 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
2876 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07002877 conn->SignalNominated(conn);
2878 }
2879
Honghai Zhang52dce732016-03-31 12:37:31 -07002880 void OnSelectedCandidatePairChanged(
deadbeef14f97f52016-06-22 17:14:15 -07002881 TransportChannel* transport_channel,
2882 CandidatePairInterface* selected_candidate_pair,
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002883 int last_sent_packet_id,
2884 bool ready_to_send) {
Honghai Zhang52dce732016-03-31 12:37:31 -07002885 last_selected_candidate_pair_ = selected_candidate_pair;
2886 last_sent_packet_id_ = last_sent_packet_id;
Honghai Zhang572b0942016-06-23 12:26:57 -07002887 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07002888 }
2889
deadbeef14f97f52016-06-22 17:14:15 -07002890 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07002891 const std::string& remote_ufrag,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002892 int priority,
2893 uint32_t nomination = 0) {
deadbeef14f97f52016-06-22 17:14:15 -07002894 IceMessage msg;
2895 msg.SetType(STUN_BINDING_REQUEST);
2896 msg.AddAttribute(new StunByteStringAttribute(
2897 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07002898 conn->local_candidate().username() + ":" + remote_ufrag));
deadbeef14f97f52016-06-22 17:14:15 -07002899 msg.AddAttribute(new StunUInt32Attribute(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002900 if (nomination != 0) {
2901 msg.AddAttribute(
2902 new StunUInt32Attribute(STUN_ATTR_NOMINATION, nomination));
2903 }
deadbeef14f97f52016-06-22 17:14:15 -07002904 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07002905 msg.AddMessageIntegrity(conn->local_candidate().password());
2906 msg.AddFingerprint();
2907 rtc::ByteBufferWriter buf;
2908 msg.Write(&buf);
2909 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
2910 }
2911
deadbeef14f97f52016-06-22 17:14:15 -07002912 void OnReadyToSend(TransportChannel* channel) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07002913 channel_ready_to_send_ = true;
2914 }
deadbeef14f97f52016-06-22 17:14:15 -07002915 void OnChannelStateChanged(TransportChannelImpl* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07002916 channel_state_ = channel->GetState();
2917 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002918
deadbeef14f97f52016-06-22 17:14:15 -07002919 CandidatePairInterface* last_selected_candidate_pair() {
Honghai Zhang52dce732016-03-31 12:37:31 -07002920 return last_selected_candidate_pair_;
2921 }
2922 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002923 bool channel_ready_to_send() { return channel_ready_to_send_; }
2924 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
deadbeef14f97f52016-06-22 17:14:15 -07002925 TransportChannelState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07002926 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07002927 int switches = selected_candidate_pair_switches_;
2928 selected_candidate_pair_switches_ = 0;
2929 return switches;
2930 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002931
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002932 private:
kwiberg3ec46792016-04-27 07:22:53 -07002933 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
2934 std::unique_ptr<rtc::VirtualSocketServer> vss_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002935 rtc::SocketServerScope ss_scope_;
deadbeef14f97f52016-06-22 17:14:15 -07002936 CandidatePairInterface* last_selected_candidate_pair_ = nullptr;
Honghai Zhang572b0942016-06-23 12:26:57 -07002937 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07002938 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07002939 bool channel_ready_to_send_ = false;
deadbeef14f97f52016-06-22 17:14:15 -07002940 TransportChannelState channel_state_ = STATE_INIT;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002941};
2942
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002943TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07002944 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2945 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002946 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002947 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002948 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2949 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002950
deadbeef14f97f52016-06-22 17:14:15 -07002951 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2952 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002953 ASSERT_TRUE(conn1 != nullptr);
2954 ASSERT_TRUE(conn2 != nullptr);
2955
2956 // Before a triggered check, the first connection to ping is the
2957 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08002958 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002959
2960 // Receiving a ping causes a triggered check which should make conn1
2961 // be pinged first instead of conn2, even though conn2 has a higher
2962 // priority.
2963 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08002964 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002965}
2966
honghaiz524ecc22016-05-25 12:48:31 -07002967TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07002968 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2969 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07002970 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07002971 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002972 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2973 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07002974
deadbeef14f97f52016-06-22 17:14:15 -07002975 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2976 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07002977 ASSERT_TRUE(conn1 != nullptr);
2978 ASSERT_TRUE(conn2 != nullptr);
2979
2980 // Low-priority connection becomes writable so that the other connection
2981 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002982 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07002983 EXPECT_TRUE_WAIT(
2984 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
2985 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
2986 kDefaultTimeout);
2987}
2988
zhihuang435264a2016-06-21 11:28:38 -07002989// Verify that the connections are pinged at the right time.
2990TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
2991 rtc::ScopedFakeClock clock;
2992 int RTT_RATIO = 4;
2993 int SCHEDULING_RANGE = 200;
2994 int RTT_RANGE = 10;
2995
deadbeef14f97f52016-06-22 17:14:15 -07002996 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2997 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07002998 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07002999 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003000 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3001 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003002
3003 ASSERT_TRUE(conn != nullptr);
3004 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3005
3006 // Initializing.
3007
3008 int64_t start = clock.TimeNanos();
3009 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3010 kDefaultTimeout, clock);
3011 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3012 rtc::kNumNanosecsPerMillisec /
3013 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003014 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003015
3016 // Stabilizing.
3017
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003018 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003019 int ping_sent_before = conn->num_pings_sent();
3020 start = clock.TimeNanos();
3021 // The connection becomes strong but not stable because we haven't been able
3022 // to converge the RTT.
3023 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
3024 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07003025 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003026 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07003027 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003028
3029 // Stabilized.
3030
3031 // The connection becomes stable after receiving more than RTT_RATIO rtt
3032 // samples.
3033 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003034 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003035 }
3036 ping_sent_before = conn->num_pings_sent();
3037 start = clock.TimeNanos();
3038 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
3039 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07003040 EXPECT_GE(ping_interval_ms, STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3041 EXPECT_LE(ping_interval_ms,
3042 STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003043
3044 // Destabilized.
3045
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003046 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003047 // Create a in-flight ping.
3048 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3049 start = clock.TimeNanos();
3050 // In-flight ping timeout and the connection will be unstable.
3051 SIMULATED_WAIT(
3052 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec), 3000,
3053 clock);
3054 int64_t duration_ms =
3055 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3056 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3057 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3058 // The connection become unstable due to not receiving ping responses.
3059 ping_sent_before = conn->num_pings_sent();
3060 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
3061 // The interval is expected to be
3062 // STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
3063 start = clock.TimeNanos();
3064 ping_sent_before = conn->num_pings_sent();
3065 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
3066 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07003067 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003068 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07003069 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003070}
3071
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003072// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003073// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003074TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3075 rtc::ScopedFakeClock clock;
3076
3077 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3078 P2PTransportChannel ch("TestChannel", 1, &pa);
3079 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003080 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003081 ch.MaybeStartGathering();
3082 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3083 kDefaultTimeout);
3084
3085 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003086 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003087 IceMessage request;
3088 request.SetType(STUN_BINDING_REQUEST);
3089 request.AddAttribute(
3090 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3091 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3092 request.AddAttribute(
3093 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3094 Port* port = GetPort(&ch);
3095 ASSERT_NE(nullptr, port);
3096 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3097 &request, kIceUfrag[1], false);
3098 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3099 ASSERT_NE(nullptr, conn);
3100
3101 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003102 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003103 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3104 EXPECT_EQ(0, conn->num_pings_sent());
3105
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003106 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003107 // the first ping is sent as soon as possible, within one simulated clock
3108 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003109 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003110 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3111}
3112
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003113TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003114 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3115 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003116 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003117 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003118 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3119 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003120
deadbeef14f97f52016-06-22 17:14:15 -07003121 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3122 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003123 ASSERT_TRUE(conn1 != nullptr);
3124 ASSERT_TRUE(conn2 != nullptr);
3125
guoweis36f01372016-03-02 18:02:40 -08003126 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3127 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003128 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003129 ASSERT_TRUE(conn1->writable());
3130 conn1->ReceivedPing();
3131
3132 // Ping received, but the connection is already writable, so no
3133 // "triggered check" and conn2 is pinged before conn1 because it has
3134 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003135 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003136}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003137
honghaiz079a7a12016-06-22 16:26:29 -07003138TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003139 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3140 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003141 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003142 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003143 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003144
deadbeef14f97f52016-06-22 17:14:15 -07003145 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003146 ASSERT_TRUE(conn1 != nullptr);
3147
3148 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3149 conn1->Prune(); // A pruned connection may still be pingable.
3150 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3151 conn1->FailAndPrune();
3152 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3153}
3154
Honghai Zhang1590c392016-05-24 13:15:02 -07003155TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003156 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3157 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003158 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003159 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003160 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3161 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003162 ASSERT_TRUE(conn1 != nullptr);
3163 // Pruning the connection reduces the set of active connections and changes
3164 // the channel state.
3165 conn1->Prune();
deadbeef14f97f52016-06-22 17:14:15 -07003166 EXPECT_EQ_WAIT(STATE_FAILED, channel_state(), kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003167}
3168
honghaiza54a0802015-12-16 18:37:23 -08003169// Test adding remote candidates with different ufrags. If a remote candidate
3170// is added with an old ufrag, it will be discarded. If it is added with a
3171// ufrag that was not seen before, it will be used to create connections
3172// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003173// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003174// ufrag, its pwd and generation will be set properly.
3175TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003176 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3177 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003178 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003179 ch.MaybeStartGathering();
3180 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003181 ch.AddRemoteCandidate(
3182 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3183 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003184 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003185 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003186 EXPECT_EQ(kIceUfrag[2], candidate.username());
3187 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003188 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003189
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003190 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003191 // This should set the ICE pwd in the remote candidate of |conn1|, making
3192 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003193 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003194 EXPECT_EQ(kIceUfrag[2], candidate.username());
3195 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003196 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003197
3198 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003199 ch.AddRemoteCandidate(
3200 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003201 rtc::Thread::Current()->ProcessMessages(500);
3202 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3203
3204 // Add a candidate with the current ufrag, its pwd and generation will be
3205 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003206 ch.AddRemoteCandidate(
3207 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3208 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003209 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
3210 3000);
deadbeef14f97f52016-06-22 17:14:15 -07003211 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003212 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3213 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003214
3215 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003216 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003217 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3218 candidate.username() == kIceUfrag[2]);
3219 if (candidate.username() == kIceUfrag[1]) {
3220 EXPECT_EQ(kIcePwd[1], candidate.password());
3221 } else if (candidate.username() == kIceUfrag[2]) {
3222 EXPECT_EQ(kIcePwd[2], candidate.password());
3223 }
3224 }
honghaiza54a0802015-12-16 18:37:23 -08003225}
3226
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003227TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003228 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3229 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003230 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003231 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003232
3233 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003234 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3235 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003236 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003237 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003238
3239 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003240 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003241 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3242 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003243 ASSERT_TRUE(conn2 != nullptr);
3244 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003245 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003246
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003247 // Wait for conn1 to be pruned.
3248 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
3249 // Destroy the connection to test SignalUnknownAddress.
3250 conn1->Destroy();
3251 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr, 1000);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003252
3253 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003254 IceMessage request;
3255 request.SetType(STUN_BINDING_REQUEST);
3256 request.AddAttribute(
3257 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3258 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3259 request.AddAttribute(
3260 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003261 EXPECT_NE(prflx_priority, remote_priority);
3262
deadbeef14f97f52016-06-22 17:14:15 -07003263 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003264 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003265 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3266 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003267 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3268 ASSERT_TRUE(conn1 != nullptr);
3269 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3270
3271 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003272 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3273 &request, kIceUfrag[1], false);
3274 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003275 ASSERT_TRUE(conn3 != nullptr);
3276 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3277}
Peter Thatcher54360512015-07-08 11:08:35 -07003278
3279TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
deadbeef14f97f52016-06-22 17:14:15 -07003280 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3281 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003282 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003283 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003284 // small.
3285 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003286 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003287 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Peter Thatcher54360512015-07-08 11:08:35 -07003288 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003289 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003290 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003291 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3292 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Peter Thatcher54360512015-07-08 11:08:35 -07003293 ASSERT_TRUE(conn1 != nullptr);
3294
3295 conn1->ReceivedPing();
3296 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Peter Thatcher54360512015-07-08 11:08:35 -07003297 EXPECT_TRUE_WAIT(ch.receiving(), 1000);
3298 EXPECT_TRUE_WAIT(!ch.receiving(), 1000);
3299}
honghaiz5a3acd82015-08-20 15:53:17 -07003300
Honghai Zhang572b0942016-06-23 12:26:57 -07003301// The controlled side will select a connection as the "selected connection"
3302// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003303// point the controlled side will select that connection as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003304// "selected connection". Plus, SignalSelectedCandidatePair will be fired if the
3305// selected connection changes and SignalReadyToSend will be fired if the new
3306// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003307TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003308 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3309 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003310 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003311 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003312 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003313 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3314 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003315 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003316 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003317 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003318 int last_packet_id = 0;
3319 const char* data = "ABCDEFGH";
3320 int len = static_cast<int>(strlen(data));
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003321 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003322 EXPECT_EQ(-1, last_sent_packet_id());
3323
3324 // A connection needs to be writable before it is selected for transmission.
3325 conn1->ReceivedPingResponse(LOW_RTT, "id");
3326 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
3327 EXPECT_EQ(conn1, last_selected_candidate_pair());
3328 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
3329
honghaiz5a3acd82015-08-20 15:53:17 -07003330 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003331 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003332 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3333 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003334 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003335 conn2->ReceivedPingResponse(LOW_RTT, "id");
3336 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003337 EXPECT_EQ(conn2, last_selected_candidate_pair());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003338 EXPECT_TRUE(channel_ready_to_send());
3339 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003340
3341 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003342 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003343 // its priority is lower.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003344 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003345 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3346 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003347 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003348 // Because it has a lower priority, the selected connection is still conn2.
3349 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003350 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003351 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003352 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003353 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003354 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07003355 EXPECT_EQ(conn3, last_selected_candidate_pair());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003356 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003357 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003358
Honghai Zhang572b0942016-06-23 12:26:57 -07003359 // Even if another higher priority candidate arrives, it will not be set as
3360 // the selected connection because the selected connection is nominated by
3361 // the controlling side.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003362 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003363 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3364 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003365 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003366 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003367 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003368 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003369 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003370 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003371 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003372 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003373 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003374 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003375 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003376 EXPECT_EQ(conn4, last_selected_candidate_pair());
3377 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003378 // SignalReadyToSend is fired again because conn4 is writable.
3379 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003380}
3381
Honghai Zhang572b0942016-06-23 12:26:57 -07003382// The controlled side will select a connection as the "selected connection"
3383// based on requests from an unknown address before the controlling side
3384// nominates a connection, and will nominate a connection from an unknown
3385// address if the request contains the use_candidate attribute. Plus, it will
3386// also sends back a ping response and set the ICE pwd in the remote candidate
3387// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003388TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003389 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3390 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003391 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003392 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003393 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003394 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003395 IceMessage request;
3396 request.SetType(STUN_BINDING_REQUEST);
3397 request.AddAttribute(
3398 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3399 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3400 request.AddAttribute(
3401 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3402 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
3403 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3404 &request, kIceUfrag[1], false);
3405 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003406 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003407 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003408 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003409 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003410 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003411 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003412
3413 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003414 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3415 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003416 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003417 // Because it has a lower priority, the selected connection is still conn1.
3418 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003419 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003420 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003421 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3422 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003423 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003424
Honghai Zhang572b0942016-06-23 12:26:57 -07003425 // Another request with unknown address, it will not be set as the selected
3426 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003427 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003428 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3429 &request, kIceUfrag[1], false);
3430 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003431 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003432 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003433 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003434 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003435 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003436
3437 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003438 // selected as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003439 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3440 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3441 &request, kIceUfrag[1], false);
3442 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003443 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003444 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003445 // conn4 is not the selected connection yet because it is not writable.
3446 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003447 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003448 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003449
3450 // Test that the request from an unknown address contains a ufrag from an old
3451 // generation.
3452 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003453 ch.SetRemoteIceParameters(kIceParams[2]);
3454 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003455 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3456 &request, kIceUfrag[2], false);
3457 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003458 ASSERT_TRUE(conn5 != nullptr);
3459 EXPECT_TRUE(port->sent_binding_response());
3460 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003461}
3462
Honghai Zhang572b0942016-06-23 12:26:57 -07003463// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003464// based on media received until the controlling side nominates a connection,
3465// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003466// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003467TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003468 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3469 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003470 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003471 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003472 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003473 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3474 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003475 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003476 conn1->ReceivedPingResponse(LOW_RTT, "id");
3477 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003478
Honghai Zhang572b0942016-06-23 12:26:57 -07003479 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003480 // switch to conn2 because the controlled side must mirror the media path
3481 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003482 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3483 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003484 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003485 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003486 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003487 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003488 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003489
3490 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003491 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003492 IceMessage request;
3493 request.SetType(STUN_BINDING_REQUEST);
honghaiz5a3acd82015-08-20 15:53:17 -07003494 request.AddAttribute(
deadbeef14f97f52016-06-22 17:14:15 -07003495 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3496 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3497 request.AddAttribute(
3498 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3499 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3500 Port* port = GetPort(&ch);
3501 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3502 &request, kIceUfrag[1], false);
3503 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003504 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003505 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003506 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003507 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003508
Honghai Zhang572b0942016-06-23 12:26:57 -07003509 // Now another data packet will not switch the selected connection because the
3510 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003511 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003512 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz5a3acd82015-08-20 15:53:17 -07003513 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003514 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3515}
3516
3517TEST_F(P2PTransportChannelPingTest,
3518 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3519 rtc::ScopedFakeClock clock;
3520
3521 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3522 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3523 PrepareChannel(&ch);
3524 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003525 ch.MaybeStartGathering();
3526 // The connections have decreasing priority.
3527 Connection* conn1 =
3528 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
3529 ASSERT_TRUE(conn1 != nullptr);
3530 Connection* conn2 =
3531 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
3532 ASSERT_TRUE(conn2 != nullptr);
3533
3534 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003535 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003536 EXPECT_EQ(conn1, last_selected_candidate_pair());
3537
3538 // conn2 receives data; it becomes selected.
3539 // Advance the clock by 1ms so that the last data receiving timestamp of
3540 // conn2 is larger.
3541 SIMULATED_WAIT(false, 1, clock);
3542 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003543 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003544 EXPECT_EQ(conn2, last_selected_candidate_pair());
3545
3546 // conn1 also receives data; it becomes selected due to priority again.
3547 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003548 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003549 EXPECT_EQ(conn1, last_selected_candidate_pair());
3550
Honghai Zhange05bcc22016-08-16 18:19:14 -07003551 // conn2 received data more recently; it is selected now because it
3552 // received data more recently.
3553 SIMULATED_WAIT(false, 1, clock);
3554 // Need to become writable again because it was pruned.
3555 conn2->ReceivedPingResponse(LOW_RTT, "id");
3556 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3557 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3558 EXPECT_EQ(conn2, last_selected_candidate_pair());
3559
Honghai Zhang572b0942016-06-23 12:26:57 -07003560 // Make sure sorting won't reselect candidate pair.
3561 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003562 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003563}
3564
3565TEST_F(P2PTransportChannelPingTest,
3566 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3567 rtc::ScopedFakeClock clock;
3568
3569 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3570 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3571 PrepareChannel(&ch);
3572 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003573 ch.MaybeStartGathering();
3574 // The connections have decreasing priority.
3575 Connection* conn1 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003576 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003577 ASSERT_TRUE(conn1 != nullptr);
3578 Connection* conn2 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003579 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003580 ASSERT_TRUE(conn2 != nullptr);
3581
3582 // conn1 received data; it is the selected connection.
3583 // Advance the clock to have a non-zero last-data-receiving time.
3584 SIMULATED_WAIT(false, 1, clock);
3585 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003586 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003587 EXPECT_EQ(conn1, last_selected_candidate_pair());
3588
3589 // conn2 is nominated; it becomes the selected connection.
3590 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003591 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003592 EXPECT_EQ(conn2, last_selected_candidate_pair());
3593
Honghai Zhange05bcc22016-08-16 18:19:14 -07003594 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07003595 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003596 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003597 EXPECT_EQ(conn1, last_selected_candidate_pair());
3598
Honghai Zhang572b0942016-06-23 12:26:57 -07003599 // Make sure sorting won't reselect candidate pair.
3600 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003601 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003602}
3603
3604TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003605 TestControlledAgentSelectsConnectionWithHigherNomination) {
3606 rtc::ScopedFakeClock clock;
3607
3608 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3609 P2PTransportChannel ch("test", 1, &pa);
3610 PrepareChannel(&ch);
3611 ch.SetIceRole(ICEROLE_CONTROLLED);
3612 ch.MaybeStartGathering();
3613 // The connections have decreasing priority.
3614 Connection* conn1 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003615 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003616 ASSERT_TRUE(conn1 != nullptr);
3617 Connection* conn2 =
Honghai Zhange05bcc22016-08-16 18:19:14 -07003618 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003619 ASSERT_TRUE(conn2 != nullptr);
3620
3621 // conn1 is the selected connection because it has a higher priority,
3622 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3623 kDefaultTimeout, clock);
3624 reset_selected_candidate_pair_switches();
3625
3626 // conn2 is nominated; it becomes selected.
3627 NominateConnection(conn2);
3628 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3629 EXPECT_EQ(conn2, last_selected_candidate_pair());
3630
3631 // conn1 is selected because of its priority.
3632 NominateConnection(conn1);
3633 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3634 EXPECT_EQ(conn1, last_selected_candidate_pair());
3635
3636 // conn2 gets higher remote nomination; it is selected again.
3637 NominateConnection(conn2, 2U);
3638 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3639 EXPECT_EQ(conn2, last_selected_candidate_pair());
3640
3641 // Make sure sorting won't reselect candidate pair.
3642 SIMULATED_WAIT(false, 100, clock);
3643 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3644}
3645
3646TEST_F(P2PTransportChannelPingTest,
3647 TestControlledAgentIgnoresSmallerNomination) {
3648 rtc::ScopedFakeClock clock;
3649 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3650 P2PTransportChannel ch("test", 1, &pa);
3651 PrepareChannel(&ch);
3652 ch.SetIceRole(ICEROLE_CONTROLLED);
3653 ch.MaybeStartGathering();
3654 Connection* conn =
3655 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3656 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
3657 EXPECT_EQ(2U, conn->remote_nomination());
3658 // Smaller nomination is ignored.
3659 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
3660 EXPECT_EQ(2U, conn->remote_nomination());
3661}
3662
3663TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07003664 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3665 rtc::ScopedFakeClock clock;
3666
3667 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3668 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3669 PrepareChannel(&ch);
3670 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003671 ch.MaybeStartGathering();
3672 // The connections have decreasing priority.
3673 Connection* conn1 =
3674 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3675 ASSERT_TRUE(conn1 != nullptr);
3676 Connection* conn2 =
3677 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3678 ASSERT_TRUE(conn2 != nullptr);
3679
3680 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003681 // There is no selected connection because no connection is writable.
3682 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003683
3684 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003685 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003686 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003687 kDefaultTimeout, clock);
3688 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(),
3689 kDefaultTimeout, clock);
3690
3691 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003692 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07003693 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003694 kDefaultTimeout, clock);
3695 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3696 kDefaultTimeout, clock);
3697
3698 // Make sure sorting won't reselect candidate pair.
3699 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003700 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07003701}
honghaiz89374372015-09-24 13:14:47 -07003702
honghaiz36f50e82016-06-01 15:57:03 -07003703// Test that if a new remote candidate has the same address and port with
3704// an old one, it will be used to create a new connection.
3705TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07003706 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3707 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07003708 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07003709 ch.MaybeStartGathering();
3710 const std::string host_address = "1.1.1.1";
3711 const int port_num = 1;
3712
3713 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003714 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
3715 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07003716 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003717 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003718 ASSERT_TRUE(conn1 != nullptr);
3719 EXPECT_EQ(0u, conn1->remote_candidate().generation());
3720
3721 // Simply adding the same candidate again won't create a new connection.
3722 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003723 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003724 EXPECT_EQ(conn1, conn2);
3725
3726 // Update the ufrag of the candidate and add it again.
3727 candidate.set_username(kIceUfrag[2]);
3728 ch.AddRemoteCandidate(candidate);
3729 conn2 = GetConnectionTo(&ch, host_address, port_num);
3730 EXPECT_NE(conn1, conn2);
3731 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
3732 EXPECT_EQ(1u, conn2->remote_candidate().generation());
3733
3734 // Verify that a ping with the new ufrag can be received on the new
3735 // connection.
3736 EXPECT_EQ(0, conn2->last_ping_received());
3737 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
3738 EXPECT_TRUE(conn2->last_ping_received() > 0);
3739}
3740
Honghai Zhang572b0942016-06-23 12:26:57 -07003741// When the current selected connection is strong, lower-priority connections
3742// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07003743TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07003744 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003745 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3746 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07003747 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003748 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07003749 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003750 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3751 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07003752 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003753 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003754 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07003755
3756 // When a higher-priority, nominated candidate comes in, the connections with
3757 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07003758 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003759 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07003760 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003761 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
3762 NominateConnection(conn2);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003763 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), 3000, clock);
honghaiz89374372015-09-24 13:14:47 -07003764
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003765 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07003766 // Wait until conn2 becomes not receiving.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003767 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), 3000, clock);
honghaiz89374372015-09-24 13:14:47 -07003768
deadbeef14f97f52016-06-22 17:14:15 -07003769 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003770 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07003771 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003772 // The selected connection should still be conn2. Even through conn3 has lower
3773 // priority and is not receiving/writable, it is not pruned because the
3774 // selected connection is not receiving.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003775 SIMULATED_WAIT(conn3->pruned(), 1000, clock);
honghaiz89374372015-09-24 13:14:47 -07003776 EXPECT_FALSE(conn3->pruned());
3777}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003778
Honghai Zhang572b0942016-06-23 12:26:57 -07003779TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
3780 rtc::ScopedFakeClock clock;
3781 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3782 P2PTransportChannel ch("test channel", 1, &pa);
3783 PrepareChannel(&ch);
3784 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003785 ch.MaybeStartGathering();
3786 Connection* conn1 =
3787 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 100, true);
3788 ASSERT_TRUE(conn1 != nullptr);
3789 Connection* conn2 =
3790 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 200, false);
3791 ASSERT_TRUE(conn2 != nullptr);
3792 // Even if conn1 is writable, nominated, receiving data, it should not prune
3793 // conn2.
3794 NominateConnection(conn1);
3795 SIMULATED_WAIT(false, 1, clock);
3796 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3797 SIMULATED_WAIT(conn2->pruned(), 100, clock);
3798 EXPECT_FALSE(conn2->pruned());
3799}
3800
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003801// Test that GetState returns the state correctly.
3802TEST_F(P2PTransportChannelPingTest, TestGetState) {
deadbeef14f97f52016-06-22 17:14:15 -07003803 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3804 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003805 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003806 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003807 EXPECT_EQ(TransportChannelState::STATE_INIT, ch.GetState());
3808 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3809 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3810 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3811 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003812 ASSERT_TRUE(conn1 != nullptr);
3813 ASSERT_TRUE(conn2 != nullptr);
3814 // Now there are two connections, so the transport channel is connecting.
deadbeef14f97f52016-06-22 17:14:15 -07003815 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003816 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003817 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003818 EXPECT_TRUE_WAIT(conn2->pruned(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003819 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003820 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08003821 // Need to wait until the channel state is updated.
deadbeef14f97f52016-06-22 17:14:15 -07003822 EXPECT_EQ_WAIT(TransportChannelState::STATE_FAILED, ch.GetState(), 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003823}
3824
3825// Test that when a low-priority connection is pruned, it is not deleted
3826// right away, and it can become active and be pruned again.
3827TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07003828 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003829 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3830 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003831 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07003832 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
3833 config.receiving_switching_delay = rtc::Optional<int>(800);
3834 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003835 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003836 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003837 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003838 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003839 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003840 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07003841 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
3842 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003843
3844 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07003845 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003846 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07003847 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003848 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003849 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003850 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003851 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003852 // |conn2| should not send a ping yet.
deadbeef14f97f52016-06-22 17:14:15 -07003853 EXPECT_EQ(Connection::STATE_WAITING, conn2->state());
3854 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003855 // Wait for |conn1| becoming not receiving.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003856 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), 3000, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003857 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07003858 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003859 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003860 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_INPROGRESS, conn2->state(),
3861 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003862 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003863 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
3864 clock);
deadbeef14f97f52016-06-22 17:14:15 -07003865 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003866
3867 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003868 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003869 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
3870 clock);
3871 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07003872 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003873}
honghaiz77d0d6e2015-10-27 11:34:45 -07003874
3875// Test that if all connections in a channel has timed out on writing, they
3876// will all be deleted. We use Prune to simulate write_time_out.
3877TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
deadbeef14f97f52016-06-22 17:14:15 -07003878 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3879 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07003880 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07003881 ch.MaybeStartGathering();
3882 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07003883 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3884 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz77d0d6e2015-10-27 11:34:45 -07003885 ASSERT_TRUE(conn1 != nullptr);
3886 conn1->ReceivedPing(); // Becomes receiving
3887 conn1->Prune();
3888 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3889
3890 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07003891 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3892 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz77d0d6e2015-10-27 11:34:45 -07003893 ASSERT_TRUE(conn2 != nullptr);
3894 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07003895 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
3896 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz77d0d6e2015-10-27 11:34:45 -07003897 ASSERT_TRUE(conn3 != nullptr);
3898 conn3->ReceivedPing(); // Becomes receiving
3899 // Now prune both conn2 and conn3; they will be deleted soon.
3900 conn2->Prune();
3901 conn3->Prune();
3902 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3903}
honghaiz9b669572015-11-04 12:07:44 -08003904
Honghai Zhang5a246372016-05-02 17:28:35 -07003905// Tests that after a port allocator session is started, it will be stopped
3906// when a new connection becomes writable and receiving. Also tests that if a
3907// connection belonging to an old session becomes writable, it won't stop
3908// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08003909TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07003910 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3911 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08003912 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003913 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08003914 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003915 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3916 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08003917 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003918 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003919 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3920
Honghai Zhang5a246372016-05-02 17:28:35 -07003921 // Start a new session. Even though conn1, which belongs to an older
3922 // session, becomes unwritable and writable again, it should not stop the
3923 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003924 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08003925 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07003926 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003927 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07003928 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
3929
3930 // But if a new connection created from the new session becomes writable,
3931 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07003932 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
3933 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08003934 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003935 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003936 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3937}
guoweis36f01372016-03-02 18:02:40 -08003938
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003939// Test that the ICE role is updated even on ports that has been removed.
3940// These ports may still have connections that need a correct role, in case that
3941// the connections on it may still receive stun pings.
3942TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07003943 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3944 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003945 // Starts with ICEROLE_CONTROLLING.
3946 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003947 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07003948 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07003949 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003950 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003951
deadbeef14f97f52016-06-22 17:14:15 -07003952 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003953 ASSERT_TRUE(conn != nullptr);
3954
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003955 // Make a fake signal to remove the ports in the p2ptransportchannel. then
3956 // change the ICE role and expect it to be updated.
3957 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07003958 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07003959 ch.SetIceRole(ICEROLE_CONTROLLED);
3960 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003961}
3962
3963// Test that the ICE role is updated even on ports with inactive networks.
3964// These ports may still have connections that need a correct role, for the
3965// pings sent by those connections until they're replaced by newer-generation
3966// connections.
3967TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07003968 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3969 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003970 // Starts with ICEROLE_CONTROLLING.
3971 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07003972 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003973 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003974
deadbeef14f97f52016-06-22 17:14:15 -07003975 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003976 ASSERT_TRUE(conn != nullptr);
3977
3978 // Do an ICE restart, change the role, and expect the old port to have its
3979 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003980 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07003981 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003982 ch.SetIceRole(ICEROLE_CONTROLLED);
3983 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003984}
3985
3986// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07003987// will be destroyed. The port will only be destroyed after it is marked as
3988// "pruned."
3989TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07003990 rtc::ScopedFakeClock fake_clock;
3991
deadbeef14f97f52016-06-22 17:14:15 -07003992 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3993 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003994 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003995 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07003996 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003997 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003998
deadbeef14f97f52016-06-22 17:14:15 -07003999 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004000 ASSERT_TRUE(conn != nullptr);
4001
4002 // Simulate 2 minutes going by. This should be enough time for the port to
4003 // time out.
4004 for (int second = 0; second < 120; ++second) {
4005 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
4006 }
4007 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004008 // Port will not be removed because it is not pruned yet.
4009 PortInterface* port = GetPort(&ch);
4010 ASSERT_NE(nullptr, port);
4011
4012 // If the session prunes all ports, the port will be destroyed.
4013 ch.allocator_session()->PruneAllPorts();
4014 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
4015 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004016}
4017
guoweis36f01372016-03-02 18:02:40 -08004018class P2PTransportChannelMostLikelyToWorkFirstTest
4019 : public P2PTransportChannelPingTest {
4020 public:
4021 P2PTransportChannelMostLikelyToWorkFirstTest()
4022 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4023 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004024 allocator_.reset(
4025 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4026 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004027 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4028 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004029 allocator_->set_step_delay(kMinimumStepDelay);
4030 }
4031
deadbeef14f97f52016-06-22 17:14:15 -07004032 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004033 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004034 int stable_writable_connection_ping_interval) {
deadbeef14f97f52016-06-22 17:14:15 -07004035 channel_.reset(new P2PTransportChannel("checks", 1, nullptr, allocator()));
4036 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004037 config.prioritize_most_likely_candidate_pairs =
4038 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004039 config.stable_writable_connection_ping_interval =
4040 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004041 channel_->SetIceConfig(config);
4042 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004043 channel_->MaybeStartGathering();
4044 return *channel_.get();
4045 }
4046
deadbeef14f97f52016-06-22 17:14:15 -07004047 BasicPortAllocator* allocator() { return allocator_.get(); }
4048 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004049
4050 // This verifies the next pingable connection has the expected candidates'
4051 // types and, for relay local candidate, the expected relay protocol and ping
4052 // it.
4053 void VerifyNextPingableConnection(
4054 const std::string& local_candidate_type,
4055 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004056 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4057 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004058 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004059 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004060 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4061 }
4062 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4063 }
4064
guoweis36f01372016-03-02 18:02:40 -08004065 private:
deadbeef14f97f52016-06-22 17:14:15 -07004066 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004067 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004068 TestTurnServer turn_server_;
4069 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004070};
4071
4072// Test that Relay/Relay connections will be pinged first when no other
4073// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004074// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004075TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4076 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08004077 const int max_strong_interval = 100;
deadbeef14f97f52016-06-22 17:14:15 -07004078 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
guoweis36f01372016-03-02 18:02:40 -08004079 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07004080 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4081 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004082
deadbeef14f97f52016-06-22 17:14:15 -07004083 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4084 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004085
4086 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
4087
4088 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004089 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4090 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4091 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004092
4093 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004094 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4095 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4096 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004097 conn2->ReceivedPing();
4098 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4099
Honghai Zhang572b0942016-06-23 12:26:57 -07004100 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004101 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4102 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4103 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004104 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004105 ASSERT_TRUE(conn3->writable());
4106 conn3->ReceivedPing();
4107
honghaiz524ecc22016-05-25 12:48:31 -07004108 /*
4109
4110 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4111 the flakiness. The following test becomes flaky because we now ping the
4112 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004113 times. The selected connection may have been pinged before
4114 |max_strong_interval|, so it may not be the next connection to be pinged as
4115 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004116
Honghai Zhang572b0942016-06-23 12:26:57 -07004117 // Verify that conn3 will be the "selected connection" since it is readable
4118 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004119 // pingable connection.
Honghai Zhang572b0942016-06-23 12:26:57 -07004120 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), 5000);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004121 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004122 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004123 ASSERT_TRUE(conn3->writable());
4124 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004125
4126 */
guoweis36f01372016-03-02 18:02:40 -08004127}
4128
4129// Test that Relay/Relay connections will be pinged first when everything has
4130// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4131// in the first round.
4132TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4133 TestRelayRelayFirstWhenEverythingPinged) {
deadbeef14f97f52016-06-22 17:14:15 -07004134 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08004135 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07004136 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4137 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004138
deadbeef14f97f52016-06-22 17:14:15 -07004139 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08004140 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
4141
4142 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004143 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4144 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004145
4146 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004147 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004148 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
4149
4150 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004151 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004152
4153 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004154 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004155
4156 // Now, every connection has been pinged once. The next one should be
4157 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004158 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004159}
4160
4161// Test that when we receive a new remote candidate, they will be tried first
4162// before we re-ping Relay/Relay connections again.
4163TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4164 TestNoStarvationOnNonRelayConnection) {
deadbeef14f97f52016-06-22 17:14:15 -07004165 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08004166 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07004167 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4168 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004169
deadbeef14f97f52016-06-22 17:14:15 -07004170 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08004171 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
4172
4173 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004174 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004175
4176 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004177 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004178
4179 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004180 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004181 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
4182
4183 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004184 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004185
4186 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004187 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004188
4189 // Now, every connection has been pinged once. The next one should be
4190 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004191 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004192}
4193
4194// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4195// followed by the rest.
4196TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4197 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004198 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
4199 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08004200 config.credentials = kRelayCredentials;
deadbeef14f97f52016-06-22 17:14:15 -07004201 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP, false));
guoweis36f01372016-03-02 18:02:40 -08004202 allocator()->AddTurnServer(config);
4203
deadbeef14f97f52016-06-22 17:14:15 -07004204 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08004205 EXPECT_TRUE_WAIT(ch.ports().size() == 3, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07004206 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4207 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4208 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004209
4210 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004211 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08004212 EXPECT_TRUE_WAIT(ch.connections().size() == 3, 5000);
4213
4214 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004215 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004216
4217 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004218 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4219 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004220
4221 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004222 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004223}
deadbeef14f97f52016-06-22 17:14:15 -07004224
4225} // namespace cricket {