blob: d3332ebd0fd2313c10c2c3d29bd3a8a0fab1abbf [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
11#include "webrtc/p2p/base/p2ptransportchannel.h"
12#include "webrtc/p2p/base/testrelayserver.h"
13#include "webrtc/p2p/base/teststunserver.h"
14#include "webrtc/p2p/base/testturnserver.h"
15#include "webrtc/p2p/client/basicportallocator.h"
Peter Thatcher1fe120a2015-06-10 11:33:17 -070016#include "webrtc/p2p/client/fakeportallocator.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017#include "webrtc/base/dscp.h"
18#include "webrtc/base/fakenetwork.h"
19#include "webrtc/base/firewallsocketserver.h"
20#include "webrtc/base/gunit.h"
21#include "webrtc/base/helpers.h"
22#include "webrtc/base/logging.h"
23#include "webrtc/base/natserver.h"
24#include "webrtc/base/natsocketfactory.h"
25#include "webrtc/base/physicalsocketserver.h"
26#include "webrtc/base/proxyserver.h"
27#include "webrtc/base/socketaddress.h"
28#include "webrtc/base/ssladapter.h"
29#include "webrtc/base/thread.h"
30#include "webrtc/base/virtualsocketserver.h"
31
32using cricket::kDefaultPortAllocatorFlags;
33using cricket::kMinimumStepDelay;
34using cricket::kDefaultStepDelay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000035using cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET;
36using cricket::ServerAddresses;
37using rtc::SocketAddress;
38
39static const int kDefaultTimeout = 1000;
40static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
41 cricket::PORTALLOCATOR_DISABLE_RELAY |
42 cricket::PORTALLOCATOR_DISABLE_TCP;
43// Addresses on the public internet.
44static const SocketAddress kPublicAddrs[2] =
45 { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
46// IPv6 Addresses on the public internet.
47static const SocketAddress kIPv6PublicAddrs[2] = {
48 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
49 SocketAddress("2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)
50};
51// For configuring multihomed clients.
52static const SocketAddress kAlternateAddrs[2] =
53 { SocketAddress("11.11.11.101", 0), SocketAddress("22.22.22.202", 0) };
54// Addresses for HTTP proxy servers.
55static const SocketAddress kHttpsProxyAddrs[2] =
56 { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
57// Addresses for SOCKS proxy servers.
58static const SocketAddress kSocksProxyAddrs[2] =
59 { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
60// Internal addresses for NAT boxes.
61static const SocketAddress kNatAddrs[2] =
62 { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
63// Private addresses inside the NAT private networks.
64static const SocketAddress kPrivateAddrs[2] =
65 { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
66// For cascaded NATs, the internal addresses of the inner NAT boxes.
67static const SocketAddress kCascadedNatAddrs[2] =
68 { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
69// For cascaded NATs, private addresses inside the inner private networks.
70static const SocketAddress kCascadedPrivateAddrs[2] =
71 { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
72// The address of the public STUN server.
73static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
74// The addresses for the public relay server.
75static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
76static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
77static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
78static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
79static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
80static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
81// The addresses for the public turn server.
82static const SocketAddress kTurnUdpIntAddr("99.99.99.4",
83 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -080084static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
85 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000086static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
87static const cricket::RelayCredentials kRelayCredentials("test", "test");
88
89// Based on ICE_UFRAG_LENGTH
90static const char* kIceUfrag[4] = {"TESTICEUFRAG0000", "TESTICEUFRAG0001",
91 "TESTICEUFRAG0002", "TESTICEUFRAG0003"};
92// Based on ICE_PWD_LENGTH
93static const char* kIcePwd[4] = {"TESTICEPWD00000000000000",
94 "TESTICEPWD00000000000001",
95 "TESTICEPWD00000000000002",
96 "TESTICEPWD00000000000003"};
97
Peter Boström0c4e06b2015-10-07 12:23:21 +020098static const uint64_t kTiebreaker1 = 11111;
99static const uint64_t kTiebreaker2 = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000100
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700101enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000102
Honghai Zhang049fbb12016-03-07 11:13:07 -0800103static cricket::IceConfig CreateIceConfig(int receiving_timeout,
Honghai Zhang381b4212015-12-04 12:24:03 -0800104 bool gather_continually,
105 int backup_ping_interval = -1) {
honghaiz1f429e32015-09-28 07:57:34 -0700106 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800107 config.receiving_timeout = receiving_timeout;
honghaiz1f429e32015-09-28 07:57:34 -0700108 config.gather_continually = gather_continually;
Honghai Zhang381b4212015-12-04 12:24:03 -0800109 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700110 return config;
111}
112
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113// This test simulates 2 P2P endpoints that want to establish connectivity
114// with each other over various network topologies and conditions, which can be
115// specified in each individial test.
116// A virtual network (via VirtualSocketServer) along with virtual firewalls and
117// NATs (via Firewall/NATSocketServer) are used to simulate the various network
118// conditions. We can configure the IP addresses of the endpoints,
119// block various types of connectivity, or add arbitrary levels of NAT.
120// We also run a STUN server and a relay server on the virtual network to allow
121// our typical P2P mechanisms to do their thing.
122// For each case, we expect the P2P stack to eventually settle on a specific
123// form of connectivity to the other side. The test checks that the P2P
124// negotiation successfully establishes connectivity within a certain time,
125// and that the result is what we expect.
126// Note that this class is a base class for use by other tests, who will provide
127// specialized test behavior.
128class P2PTransportChannelTestBase : public testing::Test,
129 public rtc::MessageHandler,
130 public sigslot::has_slots<> {
131 public:
132 P2PTransportChannelTestBase()
133 : main_(rtc::Thread::Current()),
134 pss_(new rtc::PhysicalSocketServer),
135 vss_(new rtc::VirtualSocketServer(pss_.get())),
136 nss_(new rtc::NATSocketServer(vss_.get())),
137 ss_(new rtc::FirewallSocketServer(nss_.get())),
138 ss_scope_(ss_.get()),
139 stun_server_(cricket::TestStunServer::Create(main_, kStunAddr)),
140 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
141 relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
142 kRelayTcpIntAddr, kRelayTcpExtAddr,
143 kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
144 socks_server1_(ss_.get(), kSocksProxyAddrs[0],
145 ss_.get(), kSocksProxyAddrs[0]),
146 socks_server2_(ss_.get(), kSocksProxyAddrs[1],
147 ss_.get(), kSocksProxyAddrs[1]),
148 clear_remote_candidates_ufrag_pwd_(false),
149 force_relay_(false) {
150 ep1_.role_ = cricket::ICEROLE_CONTROLLING;
151 ep2_.role_ = cricket::ICEROLE_CONTROLLED;
152
153 ServerAddresses stun_servers;
154 stun_servers.insert(kStunAddr);
155 ep1_.allocator_.reset(new cricket::BasicPortAllocator(
156 &ep1_.network_manager_,
157 stun_servers, kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
158 ep2_.allocator_.reset(new cricket::BasicPortAllocator(
159 &ep2_.network_manager_,
160 stun_servers, kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
161 }
162
163 protected:
164 enum Config {
165 OPEN, // Open to the Internet
166 NAT_FULL_CONE, // NAT, no filtering
167 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
168 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
169 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
170 NAT_DOUBLE_CONE, // Double NAT, both cone
171 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
172 BLOCK_UDP, // Firewall, UDP in/out blocked
173 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
174 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
175 PROXY_HTTPS, // All traffic through HTTPS proxy
176 PROXY_SOCKS, // All traffic through SOCKS proxy
177 NUM_CONFIGS
178 };
179
180 struct Result {
181 Result(const std::string& lt, const std::string& lp,
182 const std::string& rt, const std::string& rp,
183 const std::string& lt2, const std::string& lp2,
184 const std::string& rt2, const std::string& rp2, int wait)
185 : local_type(lt), local_proto(lp), remote_type(rt), remote_proto(rp),
186 local_type2(lt2), local_proto2(lp2), remote_type2(rt2),
187 remote_proto2(rp2), connect_wait(wait) {
188 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700189
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190 std::string local_type;
191 std::string local_proto;
192 std::string remote_type;
193 std::string remote_proto;
194 std::string local_type2;
195 std::string local_proto2;
196 std::string remote_type2;
197 std::string remote_proto2;
198 int connect_wait;
199 };
200
201 struct ChannelData {
202 bool CheckData(const char* data, int len) {
203 bool ret = false;
204 if (!ch_packets_.empty()) {
205 std::string packet = ch_packets_.front();
206 ret = (packet == std::string(data, len));
207 ch_packets_.pop_front();
208 }
209 return ret;
210 }
211
212 std::string name_; // TODO - Currently not used.
213 std::list<std::string> ch_packets_;
214 rtc::scoped_ptr<cricket::P2PTransportChannel> ch_;
215 };
216
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700217 struct CandidatesData : public rtc::MessageData {
218 CandidatesData(cricket::TransportChannel* ch, const cricket::Candidate& c)
219 : channel(ch), candidates(1, c) {}
220 CandidatesData(cricket::TransportChannel* ch,
221 const std::vector<cricket::Candidate>& cc)
222 : channel(ch), candidates(cc) {}
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000223 cricket::TransportChannel* channel;
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700224 cricket::Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000225 };
226
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000228 Endpoint()
229 : role_(cricket::ICEROLE_UNKNOWN),
230 tiebreaker_(0),
231 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700232 save_candidates_(false) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000233 bool HasChannel(cricket::TransportChannel* ch) {
234 return (ch == cd1_.ch_.get() || ch == cd2_.ch_.get());
235 }
236 ChannelData* GetChannelData(cricket::TransportChannel* ch) {
237 if (!HasChannel(ch)) return NULL;
238 if (cd1_.ch_.get() == ch)
239 return &cd1_;
240 else
241 return &cd2_;
242 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000243
244 void SetIceRole(cricket::IceRole role) { role_ = role; }
245 cricket::IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200246 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
247 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000248 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
249 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200250 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000251 allocator_->set_step_delay(delay);
252 }
253 void SetAllowTcpListen(bool allow_tcp_listen) {
254 allocator_->set_allow_tcp_listen(allow_tcp_listen);
255 }
256
257 rtc::FakeNetworkManager network_manager_;
258 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
259 ChannelData cd1_;
260 ChannelData cd2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261 cricket::IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200262 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000263 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000264 bool save_candidates_;
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700265 std::vector<CandidatesData*> saved_candidates_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 };
267
268 ChannelData* GetChannelData(cricket::TransportChannel* channel) {
269 if (ep1_.HasChannel(channel))
270 return ep1_.GetChannelData(channel);
271 else
272 return ep2_.GetChannelData(channel);
273 }
274
275 void CreateChannels(int num) {
276 std::string ice_ufrag_ep1_cd1_ch = kIceUfrag[0];
277 std::string ice_pwd_ep1_cd1_ch = kIcePwd[0];
278 std::string ice_ufrag_ep2_cd1_ch = kIceUfrag[1];
279 std::string ice_pwd_ep2_cd1_ch = kIcePwd[1];
280 ep1_.cd1_.ch_.reset(CreateChannel(
281 0, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
282 ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch,
283 ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch));
284 ep2_.cd1_.ch_.reset(CreateChannel(
285 1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
286 ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch,
287 ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch));
288 if (num == 2) {
289 std::string ice_ufrag_ep1_cd2_ch = kIceUfrag[2];
290 std::string ice_pwd_ep1_cd2_ch = kIcePwd[2];
291 std::string ice_ufrag_ep2_cd2_ch = kIceUfrag[3];
292 std::string ice_pwd_ep2_cd2_ch = kIcePwd[3];
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000293 ep1_.cd2_.ch_.reset(CreateChannel(
294 0, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
295 ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch,
296 ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch));
297 ep2_.cd2_.ch_.reset(CreateChannel(
298 1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
299 ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch,
300 ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch));
301 }
302 }
303 cricket::P2PTransportChannel* CreateChannel(
304 int endpoint,
305 int component,
306 const std::string& local_ice_ufrag,
307 const std::string& local_ice_pwd,
308 const std::string& remote_ice_ufrag,
309 const std::string& remote_ice_pwd) {
310 cricket::P2PTransportChannel* channel = new cricket::P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800311 "test content name", component, GetAllocator(endpoint));
deadbeefcbecd352015-09-23 11:50:27 -0700312 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700313 this, &P2PTransportChannelTestBase::OnCandidateGathered);
314 channel->SignalCandidatesRemoved.connect(
315 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000316 channel->SignalReadPacket.connect(
317 this, &P2PTransportChannelTestBase::OnReadPacket);
318 channel->SignalRoleConflict.connect(
319 this, &P2PTransportChannelTestBase::OnRoleConflict);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000320 channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd);
321 if (clear_remote_candidates_ufrag_pwd_) {
322 // This only needs to be set if we're clearing them from the
323 // candidates. Some unit tests rely on this not being set.
324 channel->SetRemoteIceCredentials(remote_ice_ufrag, remote_ice_pwd);
325 }
326 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
327 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
328 channel->Connect();
deadbeefcbecd352015-09-23 11:50:27 -0700329 channel->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330 return channel;
331 }
332 void DestroyChannels() {
333 ep1_.cd1_.ch_.reset();
334 ep2_.cd1_.ch_.reset();
335 ep1_.cd2_.ch_.reset();
336 ep2_.cd2_.ch_.reset();
337 }
338 cricket::P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
339 cricket::P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
340 cricket::P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
341 cricket::P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
342
343 // Common results.
344 static const Result kLocalUdpToLocalUdp;
345 static const Result kLocalUdpToStunUdp;
346 static const Result kLocalUdpToPrflxUdp;
347 static const Result kPrflxUdpToLocalUdp;
348 static const Result kStunUdpToLocalUdp;
349 static const Result kStunUdpToStunUdp;
350 static const Result kPrflxUdpToStunUdp;
351 static const Result kLocalUdpToRelayUdp;
352 static const Result kPrflxUdpToRelayUdp;
353 static const Result kLocalTcpToLocalTcp;
354 static const Result kLocalTcpToPrflxTcp;
355 static const Result kPrflxTcpToLocalTcp;
356
357 rtc::NATSocketServer* nat() { return nss_.get(); }
358 rtc::FirewallSocketServer* fw() { return ss_.get(); }
359
360 Endpoint* GetEndpoint(int endpoint) {
361 if (endpoint == 0) {
362 return &ep1_;
363 } else if (endpoint == 1) {
364 return &ep2_;
365 } else {
366 return NULL;
367 }
368 }
369 cricket::PortAllocator* GetAllocator(int endpoint) {
370 return GetEndpoint(endpoint)->allocator_.get();
371 }
372 void AddAddress(int endpoint, const SocketAddress& addr) {
373 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
374 }
honghaize1a0c942016-02-16 14:54:56 -0800375 void AddAddress(int endpoint,
376 const SocketAddress& addr,
377 const std::string& ifname,
378 rtc::AdapterType adapter_type) {
379 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
380 adapter_type);
381 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000382 void RemoveAddress(int endpoint, const SocketAddress& addr) {
383 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
384 }
385 void SetProxy(int endpoint, rtc::ProxyType type) {
386 rtc::ProxyInfo info;
387 info.type = type;
388 info.address = (type == rtc::PROXY_HTTPS) ?
389 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
390 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
391 }
392 void SetAllocatorFlags(int endpoint, int flags) {
393 GetAllocator(endpoint)->set_flags(flags);
394 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000395 void SetIceRole(int endpoint, cricket::IceRole role) {
396 GetEndpoint(endpoint)->SetIceRole(role);
397 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200398 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000399 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
400 }
401 bool GetRoleConflict(int endpoint) {
402 return GetEndpoint(endpoint)->role_conflict();
403 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200404 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000405 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
406 }
407 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
408 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
409 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700410 bool IsLocalToPrflxOrTheReverse(const Result& expected) {
deadbeefcbecd352015-09-23 11:50:27 -0700411 return (
412 (expected.local_type == "local" && expected.remote_type == "prflx") ||
413 (expected.local_type == "prflx" && expected.remote_type == "local"));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700414 }
415
416 // Return true if the approprite parts of the expected Result, based
417 // on the local and remote candidate of ep1_ch1, match. This can be
418 // used in an EXPECT_TRUE_WAIT.
419 bool CheckCandidate1(const Result& expected) {
420 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
421 const std::string& local_proto = LocalCandidate(ep1_ch1())->protocol();
422 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
423 const std::string& remote_proto = RemoteCandidate(ep1_ch1())->protocol();
424 return ((local_proto == expected.local_proto &&
425 remote_proto == expected.remote_proto) &&
426 ((local_type == expected.local_type &&
427 remote_type == expected.remote_type) ||
428 // Sometimes we expect local -> prflx or prflx -> local
429 // and instead get prflx -> local or local -> prflx, and
430 // that's OK.
431 (IsLocalToPrflxOrTheReverse(expected) &&
432 local_type == expected.remote_type &&
433 remote_type == expected.local_type)));
434 }
435
436 // EXPECT_EQ on the approprite parts of the expected Result, based
437 // on the local and remote candidate of ep1_ch1. This is like
438 // CheckCandidate1, except that it will provide more detail about
439 // what didn't match.
440 void ExpectCandidate1(const Result& expected) {
441 if (CheckCandidate1(expected)) {
442 return;
443 }
444
445 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
446 const std::string& local_proto = LocalCandidate(ep1_ch1())->protocol();
447 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
448 const std::string& remote_proto = RemoteCandidate(ep1_ch1())->protocol();
449 EXPECT_EQ(expected.local_type, local_type);
450 EXPECT_EQ(expected.remote_type, remote_type);
451 EXPECT_EQ(expected.local_proto, local_proto);
452 EXPECT_EQ(expected.remote_proto, remote_proto);
453 }
454
455 // Return true if the approprite parts of the expected Result, based
456 // on the local and remote candidate of ep2_ch1, match. This can be
457 // used in an EXPECT_TRUE_WAIT.
458 bool CheckCandidate2(const Result& expected) {
459 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
460 // const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
461 const std::string& local_proto = LocalCandidate(ep2_ch1())->protocol();
462 const std::string& remote_proto = RemoteCandidate(ep2_ch1())->protocol();
463 // Removed remote_type comparision aginst best connection remote
464 // candidate. This is done to handle remote type discrepancy from
465 // local to stun based on the test type.
466 // For example in case of Open -> NAT, ep2 channels will have LULU
467 // and in other cases like NAT -> NAT it will be LUSU. To avoid these
468 // mismatches and we are doing comparision in different way.
469 // i.e. when don't match its remote type is either local or stun.
470 // TODO(ronghuawu): Refine the test criteria.
471 // https://code.google.com/p/webrtc/issues/detail?id=1953
472 return ((local_proto == expected.local_proto2 &&
473 remote_proto == expected.remote_proto2) &&
474 (local_type == expected.local_type2 ||
475 // Sometimes we expect local -> prflx or prflx -> local
476 // and instead get prflx -> local or local -> prflx, and
477 // that's OK.
478 (IsLocalToPrflxOrTheReverse(expected) &&
479 local_type == expected.remote_type2)));
480 }
481
482 // EXPECT_EQ on the approprite parts of the expected Result, based
483 // on the local and remote candidate of ep2_ch1. This is like
484 // CheckCandidate2, except that it will provide more detail about
485 // what didn't match.
486 void ExpectCandidate2(const Result& expected) {
487 if (CheckCandidate2(expected)) {
488 return;
489 }
490
491 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
492 const std::string& local_proto = LocalCandidate(ep2_ch1())->protocol();
493 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
494 EXPECT_EQ(expected.local_proto2, local_proto);
495 EXPECT_EQ(expected.remote_proto2, remote_type);
496 EXPECT_EQ(expected.local_type2, local_type);
497 if (remote_type != expected.remote_type2) {
498 EXPECT_TRUE(expected.remote_type2 == cricket::LOCAL_PORT_TYPE ||
499 expected.remote_type2 == cricket::STUN_PORT_TYPE);
500 EXPECT_TRUE(remote_type == cricket::LOCAL_PORT_TYPE ||
501 remote_type == cricket::STUN_PORT_TYPE ||
502 remote_type == cricket::PRFLX_PORT_TYPE);
503 }
504 }
505
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000506 void Test(const Result& expected) {
honghaiz34b11eb2016-03-16 08:55:44 -0700507 int64_t connect_start = rtc::Time64();
508 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000509
510 // Create the channels and wait for them to connect.
511 CreateChannels(1);
512 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL &&
513 ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700514 ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000515 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700516 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000517 ep2_ch1()->writable(),
518 expected.connect_wait,
519 1000);
honghaiz34b11eb2016-03-16 08:55:44 -0700520 connect_time = rtc::Time64() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000521 if (connect_time < expected.connect_wait) {
522 LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
523 } else {
524 LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
525 << expected.connect_wait << " ms)";
526 }
527
528 // Allow a few turns of the crank for the best connections to emerge.
529 // This may take up to 2 seconds.
530 if (ep1_ch1()->best_connection() &&
531 ep2_ch1()->best_connection()) {
honghaiz34b11eb2016-03-16 08:55:44 -0700532 int64_t converge_start = rtc::Time64();
533 int64_t converge_time;
534 int64_t converge_wait = 2000;
deadbeefcbecd352015-09-23 11:50:27 -0700535 EXPECT_TRUE_WAIT_MARGIN(CheckCandidate1(expected), converge_wait,
536 converge_wait);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000537 // Also do EXPECT_EQ on each part so that failures are more verbose.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700538 ExpectCandidate1(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000539
540 // Verifying remote channel best connection information. This is done
541 // only for the RFC 5245 as controlled agent will use USE-CANDIDATE
542 // from controlling (ep1) agent. We can easily predict from EP1 result
543 // matrix.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000544
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700545 // Checking for best connection candidates information at remote.
546 EXPECT_TRUE_WAIT(CheckCandidate2(expected), kDefaultTimeout);
547 // For verbose
548 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000549
honghaiz34b11eb2016-03-16 08:55:44 -0700550 converge_time = rtc::Time64() - converge_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000551 if (converge_time < converge_wait) {
552 LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
553 } else {
554 LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
555 << converge_wait << " ms)";
556 }
557 }
558 // Try sending some data to other end.
559 TestSendRecv(1);
560
561 // Destroy the channels, and wait for them to be fully cleaned up.
562 DestroyChannels();
563 }
564
565 void TestSendRecv(int channels) {
566 for (int i = 0; i < 10; ++i) {
567 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
568 int len = static_cast<int>(strlen(data));
569 // local_channel1 <==> remote_channel1
570 EXPECT_EQ_WAIT(len, SendData(ep1_ch1(), data, len), 1000);
571 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch1(), data, len), 1000);
572 EXPECT_EQ_WAIT(len, SendData(ep2_ch1(), data, len), 1000);
573 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch1(), data, len), 1000);
574 if (channels == 2 && ep1_ch2() && ep2_ch2()) {
575 // local_channel2 <==> remote_channel2
576 EXPECT_EQ_WAIT(len, SendData(ep1_ch2(), data, len), 1000);
577 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch2(), data, len), 1000);
578 EXPECT_EQ_WAIT(len, SendData(ep2_ch2(), data, len), 1000);
579 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch2(), data, len), 1000);
580 }
581 }
582 }
583
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700584 // This test waits for the transport to become receiving and writable on both
deadbeefcbecd352015-09-23 11:50:27 -0700585 // end points. Once they are, the end points set new local ice credentials and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000586 // restart the ice gathering. Finally it waits for the transport to select a
587 // new connection using the newly generated ice candidates.
588 // Before calling this function the end points must be configured.
589 void TestHandleIceUfragPasswordChanged() {
590 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
591 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700592 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
593 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000594 1000, 1000);
595
596 const cricket::Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
597 const cricket::Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
598 const cricket::Candidate* old_remote_candidate1 =
599 RemoteCandidate(ep1_ch1());
600 const cricket::Candidate* old_remote_candidate2 =
601 RemoteCandidate(ep2_ch1());
602
603 ep1_ch1()->SetIceCredentials(kIceUfrag[2], kIcePwd[2]);
604 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700605 ep1_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000606 ep2_ch1()->SetIceCredentials(kIceUfrag[3], kIcePwd[3]);
607 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700608 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000609
610 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep1_ch1())->generation() !=
611 old_local_candidate1->generation(),
612 1000, 1000);
613 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep2_ch1())->generation() !=
614 old_local_candidate2->generation(),
615 1000, 1000);
616 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep1_ch1())->generation() !=
617 old_remote_candidate1->generation(),
618 1000, 1000);
619 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep2_ch1())->generation() !=
620 old_remote_candidate2->generation(),
621 1000, 1000);
622 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
623 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
624 }
625
626 void TestSignalRoleConflict() {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000627 SetIceTiebreaker(0, kTiebreaker1); // Default EP1 is in controlling state.
628
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000629 SetIceRole(1, cricket::ICEROLE_CONTROLLING);
630 SetIceTiebreaker(1, kTiebreaker2);
631
632 // Creating channels with both channels role set to CONTROLLING.
633 CreateChannels(1);
634 // Since both the channels initiated with controlling state and channel2
635 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
636 EXPECT_TRUE_WAIT(GetRoleConflict(0), 1000);
637 EXPECT_FALSE(GetRoleConflict(1));
638
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700639 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000640 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700641 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000642 ep2_ch1()->writable(),
643 1000);
644
645 EXPECT_TRUE(ep1_ch1()->best_connection() &&
646 ep2_ch1()->best_connection());
647
648 TestSendRecv(1);
649 }
650
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000651 // We pass the candidates directly to the other side.
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700652 void OnCandidateGathered(cricket::TransportChannelImpl* ch,
653 const cricket::Candidate& c) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000654 if (force_relay_ && c.type() != cricket::RELAY_PORT_TYPE)
655 return;
656
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000657 if (GetEndpoint(ch)->save_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700658 GetEndpoint(ch)->saved_candidates_.push_back(new CandidatesData(ch, c));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000659 } else {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700660 main_->Post(this, MSG_ADD_CANDIDATES, new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000661 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000662 }
663
664 void PauseCandidates(int endpoint) {
665 GetEndpoint(endpoint)->save_candidates_ = true;
666 }
667
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700668 void OnCandidatesRemoved(cricket::TransportChannelImpl* ch,
669 const std::vector<cricket::Candidate>& candidates) {
670 // Candidate removals are not paused.
671 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
672 main_->Post(this, MSG_REMOVE_CANDIDATES, candidates_data);
673 }
674
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800675 // Tcp candidate verification has to be done when they are generated.
676 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
677 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700678 for (auto& candidate : data->candidates) {
679 EXPECT_EQ(candidate.protocol(), cricket::TCP_PROTOCOL_NAME);
680 EXPECT_EQ(candidate.tcptype(), tcptype);
681 if (candidate.tcptype() == cricket::TCPTYPE_ACTIVE_STR) {
682 EXPECT_EQ(candidate.address().port(), cricket::DISCARD_PORT);
683 } else if (candidate.tcptype() == cricket::TCPTYPE_PASSIVE_STR) {
684 EXPECT_NE(candidate.address().port(), cricket::DISCARD_PORT);
685 } else {
686 FAIL() << "Unknown tcptype: " << candidate.tcptype();
687 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800688 }
689 }
690 }
691
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000692 void ResumeCandidates(int endpoint) {
693 Endpoint* ed = GetEndpoint(endpoint);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700694 std::vector<CandidatesData*>::iterator it = ed->saved_candidates_.begin();
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000695 for (; it != ed->saved_candidates_.end(); ++it) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700696 main_->Post(this, MSG_ADD_CANDIDATES, *it);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000697 }
698 ed->saved_candidates_.clear();
699 ed->save_candidates_ = false;
700 }
701
702 void OnMessage(rtc::Message* msg) {
703 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700704 case MSG_ADD_CANDIDATES: {
705 rtc::scoped_ptr<CandidatesData> data(
706 static_cast<CandidatesData*>(msg->pdata));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000707 cricket::P2PTransportChannel* rch = GetRemoteChannel(data->channel);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700708 for (auto& c : data->candidates) {
709 if (clear_remote_candidates_ufrag_pwd_) {
710 c.set_username("");
711 c.set_password("");
712 }
713 LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
714 << rch->component() << "): " << c.ToString();
715 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000716 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700717 break;
718 }
719 case MSG_REMOVE_CANDIDATES: {
720 rtc::scoped_ptr<CandidatesData> data(
721 static_cast<CandidatesData*>(msg->pdata));
722 cricket::P2PTransportChannel* rch = GetRemoteChannel(data->channel);
723 for (cricket::Candidate& c : data->candidates) {
724 LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
725 rch->RemoveRemoteCandidate(c);
726 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000727 break;
728 }
729 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000730 }
731 void OnReadPacket(cricket::TransportChannel* channel, const char* data,
732 size_t len, const rtc::PacketTime& packet_time,
733 int flags) {
734 std::list<std::string>& packets = GetPacketList(channel);
735 packets.push_front(std::string(data, len));
736 }
737 void OnRoleConflict(cricket::TransportChannelImpl* channel) {
738 GetEndpoint(channel)->OnRoleConflict(true);
739 cricket::IceRole new_role =
740 GetEndpoint(channel)->ice_role() == cricket::ICEROLE_CONTROLLING ?
741 cricket::ICEROLE_CONTROLLED : cricket::ICEROLE_CONTROLLING;
742 channel->SetIceRole(new_role);
743 }
744 int SendData(cricket::TransportChannel* channel,
745 const char* data, size_t len) {
746 rtc::PacketOptions options;
747 return channel->SendPacket(data, len, options, 0);
748 }
749 bool CheckDataOnChannel(cricket::TransportChannel* channel,
750 const char* data, int len) {
751 return GetChannelData(channel)->CheckData(data, len);
752 }
753 static const cricket::Candidate* LocalCandidate(
754 cricket::P2PTransportChannel* ch) {
755 return (ch && ch->best_connection()) ?
756 &ch->best_connection()->local_candidate() : NULL;
757 }
758 static const cricket::Candidate* RemoteCandidate(
759 cricket::P2PTransportChannel* ch) {
760 return (ch && ch->best_connection()) ?
761 &ch->best_connection()->remote_candidate() : NULL;
762 }
763 Endpoint* GetEndpoint(cricket::TransportChannel* ch) {
764 if (ep1_.HasChannel(ch)) {
765 return &ep1_;
766 } else if (ep2_.HasChannel(ch)) {
767 return &ep2_;
768 } else {
769 return NULL;
770 }
771 }
772 cricket::P2PTransportChannel* GetRemoteChannel(
773 cricket::TransportChannel* ch) {
774 if (ch == ep1_ch1())
775 return ep2_ch1();
776 else if (ch == ep1_ch2())
777 return ep2_ch2();
778 else if (ch == ep2_ch1())
779 return ep1_ch1();
780 else if (ch == ep2_ch2())
781 return ep1_ch2();
782 else
783 return NULL;
784 }
785 std::list<std::string>& GetPacketList(cricket::TransportChannel* ch) {
786 return GetChannelData(ch)->ch_packets_;
787 }
788
789 void set_clear_remote_candidates_ufrag_pwd(bool clear) {
790 clear_remote_candidates_ufrag_pwd_ = clear;
791 }
792
793 void set_force_relay(bool relay) {
794 force_relay_ = relay;
795 }
796
797 private:
798 rtc::Thread* main_;
799 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
800 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
801 rtc::scoped_ptr<rtc::NATSocketServer> nss_;
802 rtc::scoped_ptr<rtc::FirewallSocketServer> ss_;
803 rtc::SocketServerScope ss_scope_;
804 rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
805 cricket::TestTurnServer turn_server_;
806 cricket::TestRelayServer relay_server_;
807 rtc::SocksProxyServer socks_server1_;
808 rtc::SocksProxyServer socks_server2_;
809 Endpoint ep1_;
810 Endpoint ep2_;
811 bool clear_remote_candidates_ufrag_pwd_;
812 bool force_relay_;
813};
814
815// The tests have only a few outcomes, which we predefine.
816const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
817 kLocalUdpToLocalUdp("local", "udp", "local", "udp",
818 "local", "udp", "local", "udp", 1000);
819const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
820 kLocalUdpToStunUdp("local", "udp", "stun", "udp",
821 "local", "udp", "stun", "udp", 1000);
822const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
823 kLocalUdpToPrflxUdp("local", "udp", "prflx", "udp",
824 "prflx", "udp", "local", "udp", 1000);
825const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
826 kPrflxUdpToLocalUdp("prflx", "udp", "local", "udp",
827 "local", "udp", "prflx", "udp", 1000);
828const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
829 kStunUdpToLocalUdp("stun", "udp", "local", "udp",
830 "local", "udp", "stun", "udp", 1000);
831const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
832 kStunUdpToStunUdp("stun", "udp", "stun", "udp",
833 "stun", "udp", "stun", "udp", 1000);
834const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
835 kPrflxUdpToStunUdp("prflx", "udp", "stun", "udp",
836 "local", "udp", "prflx", "udp", 1000);
837const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
838 kLocalUdpToRelayUdp("local", "udp", "relay", "udp",
839 "relay", "udp", "local", "udp", 2000);
840const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
841 kPrflxUdpToRelayUdp("prflx", "udp", "relay", "udp",
842 "relay", "udp", "prflx", "udp", 2000);
843const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
844 kLocalTcpToLocalTcp("local", "tcp", "local", "tcp",
845 "local", "tcp", "local", "tcp", 3000);
846const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
847 kLocalTcpToPrflxTcp("local", "tcp", "prflx", "tcp",
848 "prflx", "tcp", "local", "tcp", 3000);
849const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
850 kPrflxTcpToLocalTcp("prflx", "tcp", "local", "tcp",
851 "local", "tcp", "prflx", "tcp", 3000);
852
853// Test the matrix of all the connectivity types we expect to see in the wild.
854// Just test every combination of the configs in the Config enum.
855class P2PTransportChannelTest : public P2PTransportChannelTestBase {
856 protected:
857 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
858 static const Result* kMatrixSharedUfrag[NUM_CONFIGS][NUM_CONFIGS];
859 static const Result* kMatrixSharedSocketAsGice[NUM_CONFIGS][NUM_CONFIGS];
860 static const Result* kMatrixSharedSocketAsIce[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700861 void ConfigureEndpoints(Config config1,
862 Config config2,
863 int allocator_flags1,
864 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000865 ServerAddresses stun_servers;
866 stun_servers.insert(kStunAddr);
867 GetEndpoint(0)->allocator_.reset(
868 new cricket::BasicPortAllocator(&(GetEndpoint(0)->network_manager_),
869 stun_servers,
870 rtc::SocketAddress(), rtc::SocketAddress(),
871 rtc::SocketAddress()));
872 GetEndpoint(1)->allocator_.reset(
873 new cricket::BasicPortAllocator(&(GetEndpoint(1)->network_manager_),
874 stun_servers,
875 rtc::SocketAddress(), rtc::SocketAddress(),
876 rtc::SocketAddress()));
877
deadbeef653b8e02015-11-11 12:55:10 -0800878 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
879 turn_server.credentials = kRelayCredentials;
880 turn_server.ports.push_back(
deadbeefcbecd352015-09-23 11:50:27 -0700881 cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
deadbeef653b8e02015-11-11 12:55:10 -0800882 GetEndpoint(0)->allocator_->AddTurnServer(turn_server);
883 GetEndpoint(1)->allocator_->AddTurnServer(turn_server);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000884
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700885 int delay = kMinimumStepDelay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000886 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000887 SetAllocatorFlags(0, allocator_flags1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700888 SetAllocationStepDelay(0, delay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000889 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000890 SetAllocatorFlags(1, allocator_flags2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700891 SetAllocationStepDelay(1, delay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000892
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700893 set_clear_remote_candidates_ufrag_pwd(true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000894 }
895 void ConfigureEndpoint(int endpoint, Config config) {
896 switch (config) {
897 case OPEN:
898 AddAddress(endpoint, kPublicAddrs[endpoint]);
899 break;
900 case NAT_FULL_CONE:
901 case NAT_ADDR_RESTRICTED:
902 case NAT_PORT_RESTRICTED:
903 case NAT_SYMMETRIC:
904 AddAddress(endpoint, kPrivateAddrs[endpoint]);
905 // Add a single NAT of the desired type
906 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
907 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
908 AddClient(kPrivateAddrs[endpoint]);
909 break;
910 case NAT_DOUBLE_CONE:
911 case NAT_SYMMETRIC_THEN_CONE:
912 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
913 // Add a two cascaded NATs of the desired types
914 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
915 (config == NAT_DOUBLE_CONE) ?
916 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
917 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
918 rtc::NAT_OPEN_CONE)->
919 AddClient(kCascadedPrivateAddrs[endpoint]);
920 break;
921 case BLOCK_UDP:
922 case BLOCK_UDP_AND_INCOMING_TCP:
923 case BLOCK_ALL_BUT_OUTGOING_HTTP:
924 case PROXY_HTTPS:
925 case PROXY_SOCKS:
926 AddAddress(endpoint, kPublicAddrs[endpoint]);
927 // Block all UDP
928 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
929 kPublicAddrs[endpoint]);
930 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
931 // Block TCP inbound to the endpoint
932 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
933 kPublicAddrs[endpoint]);
934 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
935 // Block all TCP to/from the endpoint except 80/443 out
936 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
937 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
938 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
939 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
940 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
941 kPublicAddrs[endpoint]);
942 } else if (config == PROXY_HTTPS) {
943 // Block all TCP to/from the endpoint except to the proxy server
944 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
945 kHttpsProxyAddrs[endpoint]);
946 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
947 kPublicAddrs[endpoint]);
948 SetProxy(endpoint, rtc::PROXY_HTTPS);
949 } else if (config == PROXY_SOCKS) {
950 // Block all TCP to/from the endpoint except to the proxy server
951 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
952 kSocksProxyAddrs[endpoint]);
953 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
954 kPublicAddrs[endpoint]);
955 SetProxy(endpoint, rtc::PROXY_SOCKS5);
956 }
957 break;
958 default:
959 break;
960 }
961 }
962};
963
964// Shorthands for use in the test matrix.
965#define LULU &kLocalUdpToLocalUdp
966#define LUSU &kLocalUdpToStunUdp
967#define LUPU &kLocalUdpToPrflxUdp
968#define PULU &kPrflxUdpToLocalUdp
969#define SULU &kStunUdpToLocalUdp
970#define SUSU &kStunUdpToStunUdp
971#define PUSU &kPrflxUdpToStunUdp
972#define LURU &kLocalUdpToRelayUdp
973#define PURU &kPrflxUdpToRelayUdp
974#define LTLT &kLocalTcpToLocalTcp
975#define LTPT &kLocalTcpToPrflxTcp
976#define PTLT &kPrflxTcpToLocalTcp
977// TODO: Enable these once TestRelayServer can accept external TCP.
978#define LTRT NULL
979#define LSRS NULL
980
981// Test matrix. Originator behavior defined by rows, receiever by columns.
982
983// Currently the p2ptransportchannel.cc (specifically the
984// P2PTransportChannel::OnUnknownAddress) operates in 2 modes depend on the
985// remote candidates - ufrag per port or shared ufrag.
986// For example, if the remote candidates have the shared ufrag, for the unknown
987// address reaches the OnUnknownAddress, we will try to find the matched
988// remote candidate based on the address and protocol, if not found, a new
989// remote candidate will be created for this address. But if the remote
990// candidates have different ufrags, we will try to find the matched remote
991// candidate by comparing the ufrag. If not found, an error will be returned.
992// Because currently the shared ufrag feature is under the experiment and will
993// be rolled out gradually. We want to test the different combinations of peers
994// with/without the shared ufrag enabled. And those different combinations have
995// different expectation of the best connection. For example in the OpenToCONE
996// case, an unknown address will be updated to a "host" remote candidate if the
997// remote peer uses different ufrag per port. But in the shared ufrag case,
998// a "stun" (should be peer-reflexive eventually) candidate will be created for
999// that. So the expected best candidate will be LUSU instead of LULU.
1000// With all these, we have to keep 2 test matrixes for the tests:
1001// kMatrix - for the tests that the remote peer uses different ufrag per port.
1002// kMatrixSharedUfrag - for the tests that remote peer uses shared ufrag.
1003// The different between the two matrixes are on:
1004// OPToCONE, OPTo2CON,
1005// COToCONE, COToADDR, COToPORT, COToSYMM, COTo2CON, COToSCON,
1006// ADToCONE, ADToADDR, ADTo2CON,
1007// POToADDR,
1008// SYToADDR,
1009// 2CToCONE, 2CToADDR, 2CToPORT, 2CToSYMM, 2CTo2CON, 2CToSCON,
1010// SCToADDR,
1011
1012// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
1013// TODO: Fix NULLs caused by no HTTP proxy support.
1014// TODO: Rearrange rows/columns from best to worst.
1015// TODO(ronghuawu): Keep only one test matrix once the shared ufrag is enabled.
1016const P2PTransportChannelTest::Result*
1017 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
1018// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1019/*OP*/ {LULU, LULU, LULU, LULU, LULU, LULU, LULU, LTLT, LTLT, LSRS, NULL, LTLT},
1020/*CO*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
1021/*AD*/ {LULU, LULU, LULU, SUSU, SUSU, LULU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
1022/*PO*/ {LULU, LUSU, LUSU, SUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1023/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1024/*2C*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
1025/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1026/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
1027/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
1028/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1029/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1030/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
1031};
1032const P2PTransportChannelTest::Result*
1033 P2PTransportChannelTest::kMatrixSharedUfrag[NUM_CONFIGS][NUM_CONFIGS] = {
1034// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1035/*OP*/ {LULU, LUSU, LULU, LULU, LULU, LUSU, LULU, LTLT, LTLT, LSRS, NULL, LTLT},
1036/*CO*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
1037/*AD*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
1038/*PO*/ {LULU, LUSU, LUSU, SUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1039/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1040/*2C*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
1041/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1042/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
1043/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
1044/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1045/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1046/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
1047};
1048const P2PTransportChannelTest::Result*
1049 P2PTransportChannelTest::kMatrixSharedSocketAsGice
1050 [NUM_CONFIGS][NUM_CONFIGS] = {
1051// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1052/*OP*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, LTLT, LTLT, LSRS, NULL, LTLT},
1053/*CO*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
1054/*AD*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
1055/*PO*/ {LULU, LUSU, LUSU, LUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1056/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1057/*2C*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
1058/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1059/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
1060/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
1061/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1062/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1063/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
1064};
1065const P2PTransportChannelTest::Result*
1066 P2PTransportChannelTest::kMatrixSharedSocketAsIce
1067 [NUM_CONFIGS][NUM_CONFIGS] = {
1068// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001069/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, PTLT, LTPT, LSRS, NULL, LTPT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001070/*CO*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1071/*AD*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1072/*PO*/ {LULU, LUSU, LUSU, LUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1073/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1074/*2C*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1075/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1076/*!U*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTPT, LSRS, NULL, LTRT},
1077/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1078/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1079/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1080/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
1081};
1082
1083// The actual tests that exercise all the various configurations.
1084// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001085#define P2P_TEST_DECLARATION(x, y, z) \
1086 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1087 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1088 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
1089 if (kMatrixSharedSocketAsIce[x][y] != NULL) \
1090 Test(*kMatrixSharedSocketAsIce[x][y]); \
1091 else \
1092 LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001093 }
1094
1095#define P2P_TEST(x, y) \
1096 P2P_TEST_DECLARATION(x, y,)
1097
1098#define FLAKY_P2P_TEST(x, y) \
1099 P2P_TEST_DECLARATION(x, y, DISABLED_)
1100
1101// TODO(holmer): Disabled due to randomly failing on webrtc buildbots.
1102// Issue: webrtc/2383
1103#define P2P_TEST_SET(x) \
1104 P2P_TEST(x, OPEN) \
1105 FLAKY_P2P_TEST(x, NAT_FULL_CONE) \
1106 FLAKY_P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1107 FLAKY_P2P_TEST(x, NAT_PORT_RESTRICTED) \
1108 P2P_TEST(x, NAT_SYMMETRIC) \
1109 FLAKY_P2P_TEST(x, NAT_DOUBLE_CONE) \
1110 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1111 P2P_TEST(x, BLOCK_UDP) \
1112 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1113 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1114 P2P_TEST(x, PROXY_HTTPS) \
1115 P2P_TEST(x, PROXY_SOCKS)
1116
1117#define FLAKY_P2P_TEST_SET(x) \
1118 P2P_TEST(x, OPEN) \
1119 P2P_TEST(x, NAT_FULL_CONE) \
1120 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1121 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1122 P2P_TEST(x, NAT_SYMMETRIC) \
1123 P2P_TEST(x, NAT_DOUBLE_CONE) \
1124 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1125 P2P_TEST(x, BLOCK_UDP) \
1126 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1127 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1128 P2P_TEST(x, PROXY_HTTPS) \
1129 P2P_TEST(x, PROXY_SOCKS)
1130
1131P2P_TEST_SET(OPEN)
1132P2P_TEST_SET(NAT_FULL_CONE)
1133P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1134P2P_TEST_SET(NAT_PORT_RESTRICTED)
1135P2P_TEST_SET(NAT_SYMMETRIC)
1136P2P_TEST_SET(NAT_DOUBLE_CONE)
1137P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1138P2P_TEST_SET(BLOCK_UDP)
1139P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
1140P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1141P2P_TEST_SET(PROXY_HTTPS)
1142P2P_TEST_SET(PROXY_SOCKS)
1143
1144// Test that we restart candidate allocation when local ufrag&pwd changed.
1145// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001146TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001147 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001148 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001149 CreateChannels(1);
1150 TestHandleIceUfragPasswordChanged();
1151 DestroyChannels();
1152}
1153
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001154// Test the operation of GetStats.
1155TEST_F(P2PTransportChannelTest, GetStats) {
deadbeefcbecd352015-09-23 11:50:27 -07001156 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001157 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001158 CreateChannels(1);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001159 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1160 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001161 1000, 1000);
1162 TestSendRecv(1);
1163 cricket::ConnectionInfos infos;
1164 ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001165 ASSERT_TRUE(infos.size() >= 1);
1166 cricket::ConnectionInfo* best_conn_info = nullptr;
1167 for (cricket::ConnectionInfo& info : infos) {
1168 if (info.best_connection) {
1169 best_conn_info = &info;
1170 break;
1171 }
1172 }
1173 ASSERT_TRUE(best_conn_info != nullptr);
1174 EXPECT_TRUE(best_conn_info->new_connection);
1175 EXPECT_TRUE(best_conn_info->receiving);
1176 EXPECT_TRUE(best_conn_info->writable);
1177 EXPECT_FALSE(best_conn_info->timeout);
1178 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1179 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1180 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1181 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
1182 EXPECT_GT(best_conn_info->rtt, 0U);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001183 DestroyChannels();
1184}
1185
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001186// Test that we properly create a connection on a STUN ping from unknown address
1187// when the signaling is slow.
1188TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001189 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001190 kDefaultPortAllocatorFlags);
Peter Thatcher7351f462015-04-02 16:39:16 -07001191 // Emulate no remote credentials coming in.
1192 set_clear_remote_candidates_ufrag_pwd(false);
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +00001193 CreateChannels(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001194 // Only have remote credentials come in for ep2, not ep1.
1195 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001196
1197 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1198 // candidate.
1199 PauseCandidates(1);
1200
1201 // The caller should have the best connection connected to the peer reflexive
1202 // candidate.
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +00001203 const cricket::Connection* best_connection = NULL;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001204 WAIT((best_connection = ep1_ch1()->best_connection()) != NULL, 2000);
1205 EXPECT_EQ("prflx", ep1_ch1()->best_connection()->remote_candidate().type());
1206
Peter Thatcher7351f462015-04-02 16:39:16 -07001207 // Because we don't have a remote pwd, we don't ping yet.
1208 EXPECT_EQ(kIceUfrag[1],
1209 ep1_ch1()->best_connection()->remote_candidate().username());
1210 EXPECT_EQ("", ep1_ch1()->best_connection()->remote_candidate().password());
1211 EXPECT_TRUE(nullptr == ep1_ch1()->FindNextPingableConnection());
1212
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001213 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
1214 ResumeCandidates(1);
1215
Peter Thatcher7351f462015-04-02 16:39:16 -07001216 EXPECT_EQ(kIcePwd[1],
1217 ep1_ch1()->best_connection()->remote_candidate().password());
1218 EXPECT_TRUE(nullptr != ep1_ch1()->FindNextPingableConnection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001219
Peter Thatcher7351f462015-04-02 16:39:16 -07001220 WAIT(ep2_ch1()->best_connection() != NULL, 2000);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001221 // Verify ep1's best connection is updated to use the 'local' candidate.
1222 EXPECT_EQ_WAIT(
1223 "local",
1224 ep1_ch1()->best_connection()->remote_candidate().type(),
1225 2000);
1226 EXPECT_EQ(best_connection, ep1_ch1()->best_connection());
1227 DestroyChannels();
1228}
1229
1230// Test that we properly create a connection on a STUN ping from unknown address
1231// when the signaling is slow and the end points are behind NAT.
1232TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001233 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001234 kDefaultPortAllocatorFlags);
Peter Thatcher7351f462015-04-02 16:39:16 -07001235 // Emulate no remote credentials coming in.
1236 set_clear_remote_candidates_ufrag_pwd(false);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001237 CreateChannels(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001238 // Only have remote credentials come in for ep2, not ep1.
1239 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001240 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1241 // candidate.
1242 PauseCandidates(1);
1243
1244 // The caller should have the best connection connected to the peer reflexive
1245 // candidate.
1246 WAIT(ep1_ch1()->best_connection() != NULL, 2000);
1247 EXPECT_EQ("prflx", ep1_ch1()->best_connection()->remote_candidate().type());
1248
Peter Thatcher7351f462015-04-02 16:39:16 -07001249 // Because we don't have a remote pwd, we don't ping yet.
1250 EXPECT_EQ(kIceUfrag[1],
1251 ep1_ch1()->best_connection()->remote_candidate().username());
1252 EXPECT_EQ("", ep1_ch1()->best_connection()->remote_candidate().password());
1253 EXPECT_TRUE(nullptr == ep1_ch1()->FindNextPingableConnection());
1254
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001255 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
1256 ResumeCandidates(1);
1257
Peter Thatcher7351f462015-04-02 16:39:16 -07001258 EXPECT_EQ(kIcePwd[1],
1259 ep1_ch1()->best_connection()->remote_candidate().password());
1260 EXPECT_TRUE(nullptr != ep1_ch1()->FindNextPingableConnection());
1261
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001262 const cricket::Connection* best_connection = NULL;
1263 WAIT((best_connection = ep2_ch1()->best_connection()) != NULL, 2000);
1264
1265 // Wait to verify the connection is not culled.
1266 WAIT(ep1_ch1()->writable(), 2000);
1267 EXPECT_EQ(ep2_ch1()->best_connection(), best_connection);
1268 EXPECT_EQ("prflx", ep1_ch1()->best_connection()->remote_candidate().type());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001269 DestroyChannels();
1270}
1271
1272// Test that if remote candidates don't have ufrag and pwd, we still work.
1273TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
1274 set_clear_remote_candidates_ufrag_pwd(true);
deadbeefcbecd352015-09-23 11:50:27 -07001275 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001276 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001277 CreateChannels(1);
1278 const cricket::Connection* best_connection = NULL;
1279 // Wait until the callee's connections are created.
1280 WAIT((best_connection = ep2_ch1()->best_connection()) != NULL, 1000);
1281 // Wait to see if they get culled; they shouldn't.
1282 WAIT(ep2_ch1()->best_connection() != best_connection, 1000);
1283 EXPECT_TRUE(ep2_ch1()->best_connection() == best_connection);
1284 DestroyChannels();
1285}
1286
1287// Test that a host behind NAT cannot be reached when incoming_only
1288// is set to true.
1289TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
deadbeefcbecd352015-09-23 11:50:27 -07001290 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001291 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001292
1293 SetAllocatorFlags(0, kOnlyLocalPorts);
1294 CreateChannels(1);
1295 ep1_ch1()->set_incoming_only(true);
1296
1297 // Pump for 1 second and verify that the channels are not connected.
1298 rtc::Thread::Current()->ProcessMessages(1000);
1299
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001300 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001301 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001302 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001303 EXPECT_FALSE(ep2_ch1()->writable());
1304
1305 DestroyChannels();
1306}
1307
1308// Test that a peer behind NAT can connect to a peer that has
1309// incoming_only flag set.
1310TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
deadbeefcbecd352015-09-23 11:50:27 -07001311 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001312 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001313
1314 SetAllocatorFlags(0, kOnlyLocalPorts);
1315 CreateChannels(1);
1316 ep1_ch1()->set_incoming_only(true);
1317
1318 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001319 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1320 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001321 1000, 1000);
1322
1323 DestroyChannels();
1324}
1325
1326TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
1327 AddAddress(0, kPublicAddrs[0]);
1328 AddAddress(1, kPublicAddrs[1]);
1329
1330 SetAllocationStepDelay(0, kMinimumStepDelay);
1331 SetAllocationStepDelay(1, kMinimumStepDelay);
1332
1333 int kOnlyLocalTcpPorts = cricket::PORTALLOCATOR_DISABLE_UDP |
1334 cricket::PORTALLOCATOR_DISABLE_STUN |
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001335 cricket::PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001336 // Disable all protocols except TCP.
1337 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1338 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1339
1340 SetAllowTcpListen(0, true); // actpass.
1341 SetAllowTcpListen(1, false); // active.
1342
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001343 // Pause candidate so we could verify the candidate properties.
1344 PauseCandidates(0);
1345 PauseCandidates(1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001346 CreateChannels(1);
1347
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001348 // Verify tcp candidates.
1349 VerifySavedTcpCandidates(0, cricket::TCPTYPE_PASSIVE_STR);
1350 VerifySavedTcpCandidates(1, cricket::TCPTYPE_ACTIVE_STR);
1351
1352 // Resume candidates.
1353 ResumeCandidates(0);
1354 ResumeCandidates(1);
1355
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001356 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1357 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001358 1000);
1359 EXPECT_TRUE(
1360 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1361 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1362 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1363
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001364 TestSendRecv(1);
1365 DestroyChannels();
1366}
1367
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001368TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001369 AddAddress(0, kPublicAddrs[0]);
1370 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001371 TestSignalRoleConflict();
1372}
1373
1374// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1375// down to ports.
1376TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
1377 AddAddress(0, kPublicAddrs[0]);
1378 AddAddress(1, kPublicAddrs[1]);
1379
1380 SetIceRole(0, cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001381 SetIceTiebreaker(0, kTiebreaker1);
1382 SetIceRole(1, cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001383 SetIceTiebreaker(1, kTiebreaker2);
1384
1385 CreateChannels(1);
1386
1387 EXPECT_EQ_WAIT(2u, ep1_ch1()->ports().size(), 1000);
1388
1389 const std::vector<cricket::PortInterface *> ports_before = ep1_ch1()->ports();
1390 for (size_t i = 0; i < ports_before.size(); ++i) {
1391 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001392 EXPECT_EQ(kTiebreaker1, ports_before[i]->IceTiebreaker());
1393 }
1394
1395 ep1_ch1()->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001396 ep1_ch1()->SetIceTiebreaker(kTiebreaker2);
1397
1398 const std::vector<cricket::PortInterface *> ports_after = ep1_ch1()->ports();
1399 for (size_t i = 0; i < ports_after.size(); ++i) {
1400 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001401 // SetIceTiebreaker after Connect() has been called will fail. So expect the
1402 // original value.
1403 EXPECT_EQ(kTiebreaker1, ports_before[i]->IceTiebreaker());
1404 }
1405
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001406 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001407 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001408 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001409 ep2_ch1()->writable(),
1410 1000);
1411
1412 EXPECT_TRUE(ep1_ch1()->best_connection() &&
1413 ep2_ch1()->best_connection());
1414
1415 TestSendRecv(1);
1416 DestroyChannels();
1417}
1418
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001419// Verify that we can set DSCP value and retrieve properly from P2PTC.
1420TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1421 AddAddress(0, kPublicAddrs[0]);
1422 AddAddress(1, kPublicAddrs[1]);
1423
1424 CreateChannels(1);
1425 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1426 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1427 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1428 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1429 GetEndpoint(0)->cd1_.ch_->SetOption(
1430 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1431 GetEndpoint(1)->cd1_.ch_->SetOption(
1432 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1433 EXPECT_EQ(rtc::DSCP_CS6,
1434 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1435 EXPECT_EQ(rtc::DSCP_CS6,
1436 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1437 GetEndpoint(0)->cd1_.ch_->SetOption(
1438 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1439 GetEndpoint(1)->cd1_.ch_->SetOption(
1440 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1441 EXPECT_EQ(rtc::DSCP_AF41,
1442 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1443 EXPECT_EQ(rtc::DSCP_AF41,
1444 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1445}
1446
1447// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001448TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001449 AddAddress(0, kIPv6PublicAddrs[0]);
1450 AddAddress(0, kPublicAddrs[0]);
1451 AddAddress(1, kIPv6PublicAddrs[1]);
1452 AddAddress(1, kPublicAddrs[1]);
1453
1454 SetAllocationStepDelay(0, kMinimumStepDelay);
1455 SetAllocationStepDelay(1, kMinimumStepDelay);
1456
1457 // Enable IPv6
1458 SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_IPV6);
1459 SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_IPV6);
1460
1461 CreateChannels(1);
1462
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001463 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1464 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001465 1000);
1466 EXPECT_TRUE(
1467 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1468 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1469 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1470
1471 TestSendRecv(1);
1472 DestroyChannels();
1473}
1474
1475// Testing forceful TURN connections.
1476TEST_F(P2PTransportChannelTest, TestForceTurn) {
deadbeefcbecd352015-09-23 11:50:27 -07001477 ConfigureEndpoints(
1478 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
1479 kDefaultPortAllocatorFlags | cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1480 kDefaultPortAllocatorFlags | cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001481 set_force_relay(true);
1482
1483 SetAllocationStepDelay(0, kMinimumStepDelay);
1484 SetAllocationStepDelay(1, kMinimumStepDelay);
1485
1486 CreateChannels(1);
1487
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001488 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1489 ep2_ch1()->receiving() && ep2_ch1()->writable(),
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001490 2000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001491
1492 EXPECT_TRUE(ep1_ch1()->best_connection() &&
1493 ep2_ch1()->best_connection());
1494
1495 EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
1496 EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
1497 EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
1498 EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
1499
1500 TestSendRecv(1);
1501 DestroyChannels();
1502}
1503
honghaiz98db68f2015-09-29 07:58:17 -07001504// Test that if continual gathering is set to true, ICE gathering state will
1505// not change to "Complete", and vice versa.
1506TEST_F(P2PTransportChannelTest, TestContinualGathering) {
1507 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1508 kDefaultPortAllocatorFlags);
1509 SetAllocationStepDelay(0, kDefaultStepDelay);
1510 SetAllocationStepDelay(1, kDefaultStepDelay);
1511 CreateChannels(1);
1512 cricket::IceConfig config = CreateIceConfig(1000, true);
1513 ep1_ch1()->SetIceConfig(config);
1514 // By default, ep2 does not gather continually.
1515
1516 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1517 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1518 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1519 1000, 1000);
1520 WAIT(cricket::IceGatheringState::kIceGatheringComplete ==
1521 ep1_ch1()->gathering_state(),
1522 1000);
1523 EXPECT_EQ(cricket::IceGatheringState::kIceGatheringGathering,
1524 ep1_ch1()->gathering_state());
1525 // By now, ep2 should have completed gathering.
1526 EXPECT_EQ(cricket::IceGatheringState::kIceGatheringComplete,
1527 ep2_ch1()->gathering_state());
1528
1529 DestroyChannels();
1530}
1531
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001532// Test what happens when we have 2 users behind the same NAT. This can lead
1533// to interesting behavior because the STUN server will only give out the
1534// address of the outermost NAT.
1535class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
1536 protected:
1537 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
1538 ASSERT(nat_type >= NAT_FULL_CONE && nat_type <= NAT_SYMMETRIC);
1539 rtc::NATSocketServer::Translator* outer_nat =
1540 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
1541 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
1542 ConfigureEndpoint(outer_nat, 0, config1);
1543 ConfigureEndpoint(outer_nat, 1, config2);
1544 }
1545 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
1546 int endpoint, Config config) {
1547 ASSERT(config <= NAT_SYMMETRIC);
1548 if (config == OPEN) {
1549 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1550 nat->AddClient(kPrivateAddrs[endpoint]);
1551 } else {
1552 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1553 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1554 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
1555 kCascadedPrivateAddrs[endpoint]);
1556 }
1557 }
1558};
1559
1560TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
1561 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001562 Test(P2PTransportChannelTestBase::Result(
deadbeefcbecd352015-09-23 11:50:27 -07001563 "prflx", "udp", "stun", "udp", "stun", "udp", "prflx", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001564}
1565
1566// Test what happens when we have multiple available pathways.
1567// In the future we will try different RTTs and configs for the different
1568// interfaces, so that we can simulate a user with Ethernet and VPN networks.
1569class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
1570};
1571
1572// Test that we can establish connectivity when both peers are multihomed.
1573TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
1574 AddAddress(0, kPublicAddrs[0]);
1575 AddAddress(0, kAlternateAddrs[0]);
1576 AddAddress(1, kPublicAddrs[1]);
1577 AddAddress(1, kAlternateAddrs[1]);
1578 Test(kLocalUdpToLocalUdp);
1579}
1580
1581// Test that we can quickly switch links if an interface goes down.
honghaiza58ea782015-09-24 08:13:36 -07001582// The controlled side has two interfaces and one will die.
1583TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001584 AddAddress(0, kPublicAddrs[0]);
1585 // Adding alternate address will make sure |kPublicAddrs| has the higher
1586 // priority than others. This is due to FakeNetwork::AddInterface method.
1587 AddAddress(1, kAlternateAddrs[1]);
1588 AddAddress(1, kPublicAddrs[1]);
1589
1590 // Use only local ports for simplicity.
1591 SetAllocatorFlags(0, kOnlyLocalPorts);
1592 SetAllocatorFlags(1, kOnlyLocalPorts);
1593
1594 // Create channels and let them go writable, as usual.
1595 CreateChannels(1);
honghaiza58ea782015-09-24 08:13:36 -07001596
honghaiza4845ef2015-11-13 09:52:56 -08001597 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1598 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1599 1000, 1000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001600 EXPECT_TRUE(
1601 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1602 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1603 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1604
honghaiza4845ef2015-11-13 09:52:56 -08001605 // Make the receiving timeout shorter for testing.
1606 cricket::IceConfig config = CreateIceConfig(1000, false);
1607 ep1_ch1()->SetIceConfig(config);
1608 ep2_ch1()->SetIceConfig(config);
1609
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001610 // Blackhole any traffic to or from the public addrs.
1611 LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07001612 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
1613 // The best connections will switch, so keep references to them.
1614 const cricket::Connection* best_connection1 = ep1_ch1()->best_connection();
1615 const cricket::Connection* best_connection2 = ep2_ch1()->best_connection();
1616 // We should detect loss of receiving within 1 second or so.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001617 EXPECT_TRUE_WAIT(
honghaiza58ea782015-09-24 08:13:36 -07001618 !best_connection1->receiving() && !best_connection2->receiving(), 3000);
1619
1620 // We should switch over to use the alternate addr immediately on both sides
1621 // when we are not receiving.
1622 EXPECT_TRUE_WAIT(
1623 ep1_ch1()->best_connection()->receiving() &&
1624 ep2_ch1()->best_connection()->receiving(), 1000);
1625 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
1626 EXPECT_TRUE(
1627 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1628 EXPECT_TRUE(
1629 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1630
1631 DestroyChannels();
1632}
1633
1634// Test that we can quickly switch links if an interface goes down.
1635// The controlling side has two interfaces and one will die.
1636TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
1637 // Adding alternate address will make sure |kPublicAddrs| has the higher
1638 // priority than others. This is due to FakeNetwork::AddInterface method.
1639 AddAddress(0, kAlternateAddrs[0]);
1640 AddAddress(0, kPublicAddrs[0]);
1641 AddAddress(1, kPublicAddrs[1]);
1642
1643 // Use only local ports for simplicity.
1644 SetAllocatorFlags(0, kOnlyLocalPorts);
1645 SetAllocatorFlags(1, kOnlyLocalPorts);
1646
1647 // Create channels and let them go writable, as usual.
1648 CreateChannels(1);
honghaiza4845ef2015-11-13 09:52:56 -08001649 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1650 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1651 1000, 1000);
honghaiza58ea782015-09-24 08:13:36 -07001652 EXPECT_TRUE(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001653 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1654 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
honghaiza58ea782015-09-24 08:13:36 -07001655 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1656
honghaiza4845ef2015-11-13 09:52:56 -08001657 // Make the receiving timeout shorter for testing.
1658 cricket::IceConfig config = CreateIceConfig(1000, false);
1659 ep1_ch1()->SetIceConfig(config);
1660 ep2_ch1()->SetIceConfig(config);
1661
honghaiza58ea782015-09-24 08:13:36 -07001662 // Blackhole any traffic to or from the public addrs.
1663 LOG(LS_INFO) << "Failing over...";
1664 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1665 // The best connections will switch, so keep references to them.
1666 const cricket::Connection* best_connection1 = ep1_ch1()->best_connection();
1667 const cricket::Connection* best_connection2 = ep2_ch1()->best_connection();
1668 // We should detect loss of receiving within 1 second or so.
1669 EXPECT_TRUE_WAIT(
1670 !best_connection1->receiving() && !best_connection2->receiving(), 3000);
1671
1672 // We should switch over to use the alternate addr immediately on both sides
1673 // when we are not receiving.
1674 EXPECT_TRUE_WAIT(
1675 ep1_ch1()->best_connection()->receiving() &&
1676 ep2_ch1()->best_connection()->receiving(), 1000);
1677 EXPECT_TRUE(
1678 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
1679 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1680 EXPECT_TRUE(
1681 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001682
1683 DestroyChannels();
1684}
1685
honghaize1a0c942016-02-16 14:54:56 -08001686// Tests that a Wifi-Wifi connection has the highest precedence.
1687TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
1688 // The interface names are chosen so that |cellular| would have higher
1689 // candidate priority if it is not for the network type.
1690 auto& wifi = kAlternateAddrs;
1691 auto& cellular = kPublicAddrs;
1692 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
1693 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
1694 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
1695 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
1696
1697 // Use only local ports for simplicity.
1698 SetAllocatorFlags(0, kOnlyLocalPorts);
1699 SetAllocatorFlags(1, kOnlyLocalPorts);
1700
1701 // Create channels and let them go writable, as usual.
1702 CreateChannels(1);
1703
1704 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1705 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1706 1000, 1000);
1707 // Need to wait to make sure the connections on both networks are writable.
1708 EXPECT_TRUE_WAIT(ep1_ch1()->best_connection() &&
1709 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
1710 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
1711 1000);
1712 EXPECT_TRUE_WAIT(ep2_ch1()->best_connection() &&
1713 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
1714 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
1715 1000);
1716}
1717
1718// Tests that a Wifi-Cellular connection has higher precedence than
1719// a Cellular-Cellular connection.
1720TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
1721 // The interface names are chosen so that |cellular| would have higher
1722 // candidate priority if it is not for the network type.
1723 auto& wifi = kAlternateAddrs;
1724 auto& cellular = kPublicAddrs;
1725 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
1726 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
1727 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
1728
1729 // Use only local ports for simplicity.
1730 SetAllocatorFlags(0, kOnlyLocalPorts);
1731 SetAllocatorFlags(1, kOnlyLocalPorts);
1732
1733 // Create channels and let them go writable, as usual.
1734 CreateChannels(1);
1735
1736 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1737 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1738 1000, 1000);
1739 // Need to wait to make sure the connections on both networks are writable.
1740 EXPECT_TRUE_WAIT(ep1_ch1()->best_connection() &&
1741 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
1742 1000);
1743 EXPECT_TRUE_WAIT(ep2_ch1()->best_connection() &&
1744 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
1745 1000);
1746}
1747
Honghai Zhang381b4212015-12-04 12:24:03 -08001748// Test that the backup connection is pinged at a rate no faster than
1749// what was configured.
1750TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
1751 AddAddress(0, kPublicAddrs[0]);
1752 // Adding alternate address will make sure |kPublicAddrs| has the higher
1753 // priority than others. This is due to FakeNetwork::AddInterface method.
1754 AddAddress(1, kAlternateAddrs[1]);
1755 AddAddress(1, kPublicAddrs[1]);
1756
1757 // Use only local ports for simplicity.
1758 SetAllocatorFlags(0, kOnlyLocalPorts);
1759 SetAllocatorFlags(1, kOnlyLocalPorts);
1760
1761 // Create channels and let them go writable, as usual.
1762 CreateChannels(1);
1763 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1764 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1765 1000, 1000);
1766 int backup_ping_interval = 2000;
1767 ep2_ch1()->SetIceConfig(CreateIceConfig(2000, false, backup_ping_interval));
1768 // After the state becomes COMPLETED, the backup connection will be pinged
1769 // once every |backup_ping_interval| milliseconds.
1770 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == cricket::STATE_COMPLETED, 1000);
1771 const std::vector<cricket::Connection*>& connections =
1772 ep2_ch1()->connections();
1773 ASSERT_EQ(2U, connections.size());
1774 cricket::Connection* backup_conn = connections[1];
1775 EXPECT_TRUE_WAIT(backup_conn->writable(), 3000);
honghaiz34b11eb2016-03-16 08:55:44 -07001776 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08001777 EXPECT_TRUE_WAIT(
1778 last_ping_response_ms < backup_conn->last_ping_response_received(), 5000);
1779 int time_elapsed =
1780 backup_conn->last_ping_response_received() - last_ping_response_ms;
1781 LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
1782 EXPECT_GE(time_elapsed, backup_ping_interval);
1783}
1784
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001785TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
1786 AddAddress(0, kAlternateAddrs[0]);
1787 AddAddress(0, kPublicAddrs[0]);
1788 AddAddress(1, kPublicAddrs[1]);
1789 // Create channels and let them go writable, as usual.
1790 CreateChannels(1);
1791
1792 // Both transport channels will reach STATE_COMPLETED quickly.
1793 EXPECT_EQ_WAIT(cricket::TransportChannelState::STATE_COMPLETED,
1794 ep1_ch1()->GetState(), 1000);
1795 EXPECT_EQ_WAIT(cricket::TransportChannelState::STATE_COMPLETED,
1796 ep2_ch1()->GetState(), 1000);
1797}
1798
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001799// Tests that when a network interface becomes inactive, if and only if
1800// Continual Gathering is enabled, the ports associated with that network
1801// will be removed from the port list of the channel, and the respective
1802// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08001803TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
1804 AddAddress(0, kPublicAddrs[0]);
1805 AddAddress(1, kPublicAddrs[1]);
1806 // Create channels and let them go writable, as usual.
1807 CreateChannels(1);
1808 ep1_ch1()->SetIceConfig(CreateIceConfig(2000, true));
1809 ep2_ch1()->SetIceConfig(CreateIceConfig(2000, false));
1810
1811 SetAllocatorFlags(0, kOnlyLocalPorts);
1812 SetAllocatorFlags(1, kOnlyLocalPorts);
1813 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1814 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1815 1000, 1000);
1816 // More than one port has been created.
1817 EXPECT_LE(1U, ep1_ch1()->ports().size());
1818 // Endpoint 1 enabled continual gathering; the port will be removed
1819 // when the interface is removed.
1820 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001821 EXPECT_TRUE(ep1_ch1()->ports().empty());
1822 // The remote candidates will be removed eventually.
1823 EXPECT_TRUE_WAIT(ep2_ch1()->remote_candidates().empty(), 1000);
honghaize3c6c822016-02-17 13:00:28 -08001824
1825 size_t num_ports = ep2_ch1()->ports().size();
1826 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001827 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
honghaize3c6c822016-02-17 13:00:28 -08001828 // Endpoint 2 did not enable continual gathering; the port will not be removed
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001829 // when the interface is removed and neither the remote candidates on the
1830 // other participant.
honghaize3c6c822016-02-17 13:00:28 -08001831 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001832 rtc::Thread::Current()->ProcessMessages(500);
honghaize3c6c822016-02-17 13:00:28 -08001833 EXPECT_EQ(num_ports, ep2_ch1()->ports().size());
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001834 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
honghaize3c6c822016-02-17 13:00:28 -08001835}
1836
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001837/*
1838
1839TODO(pthatcher): Once have a way to handle network interfaces changes
1840without signalling an ICE restart, put a test like this back. In the
1841mean time, this test only worked for GICE. With ICE, it's currently
1842not possible without an ICE restart.
1843
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001844// Test that we can switch links in a coordinated fashion.
1845TEST_F(P2PTransportChannelMultihomedTest, TestDrain) {
1846 AddAddress(0, kPublicAddrs[0]);
1847 AddAddress(1, kPublicAddrs[1]);
1848 // Use only local ports for simplicity.
1849 SetAllocatorFlags(0, kOnlyLocalPorts);
1850 SetAllocatorFlags(1, kOnlyLocalPorts);
1851
1852 // Create channels and let them go writable, as usual.
1853 CreateChannels(1);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001854 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1855 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001856 1000);
1857 EXPECT_TRUE(
1858 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1859 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1860 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1861
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001862
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001863 // Remove the public interface, add the alternate interface, and allocate
deadbeefcbecd352015-09-23 11:50:27 -07001864 // a new generation of candidates for the new interface (via
1865 // MaybeStartGathering()).
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001866 LOG(LS_INFO) << "Draining...";
1867 AddAddress(1, kAlternateAddrs[1]);
1868 RemoveAddress(1, kPublicAddrs[1]);
deadbeefcbecd352015-09-23 11:50:27 -07001869 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001870
1871 // We should switch over to use the alternate address after
1872 // an exchange of pings.
1873 EXPECT_TRUE_WAIT(
1874 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
1875 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1876 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
1877 3000);
1878
1879 DestroyChannels();
1880}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001881
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001882*/
1883
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001884// A collection of tests which tests a single P2PTransportChannel by sending
1885// pings.
1886class P2PTransportChannelPingTest : public testing::Test,
1887 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001888 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001889 P2PTransportChannelPingTest()
1890 : pss_(new rtc::PhysicalSocketServer),
1891 vss_(new rtc::VirtualSocketServer(pss_.get())),
1892 ss_scope_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001893
1894 protected:
1895 void PrepareChannel(cricket::P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001896 ch->SetIceRole(cricket::ICEROLE_CONTROLLING);
1897 ch->SetIceCredentials(kIceUfrag[0], kIcePwd[0]);
1898 ch->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
1899 }
1900
guoweis36f01372016-03-02 18:02:40 -08001901 cricket::Candidate CreateHostCandidate(const std::string& ip,
1902 int port,
1903 int priority,
1904 const std::string& ufrag = "") {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001905 cricket::Candidate c;
1906 c.set_address(rtc::SocketAddress(ip, port));
1907 c.set_component(1);
1908 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
1909 c.set_priority(priority);
honghaiza54a0802015-12-16 18:37:23 -08001910 c.set_username(ufrag);
guoweis36f01372016-03-02 18:02:40 -08001911 c.set_type(cricket::LOCAL_PORT_TYPE);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001912 return c;
1913 }
1914
1915 cricket::Connection* WaitForConnectionTo(cricket::P2PTransportChannel* ch,
1916 const std::string& ip,
1917 int port_num) {
1918 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr, 3000);
1919 return GetConnectionTo(ch, ip, port_num);
1920 }
1921
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001922 cricket::Port* GetPort(cricket::P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001923 if (ch->ports().empty()) {
1924 return nullptr;
1925 }
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001926 return static_cast<cricket::Port*>(ch->ports()[0]);
1927 }
1928
1929 cricket::Connection* GetConnectionTo(cricket::P2PTransportChannel* ch,
1930 const std::string& ip,
1931 int port_num) {
1932 cricket::Port* port = GetPort(ch);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001933 if (!port) {
1934 return nullptr;
1935 }
1936 return port->GetConnection(rtc::SocketAddress(ip, port_num));
1937 }
1938
guoweis36f01372016-03-02 18:02:40 -08001939 cricket::Connection* FindNextPingableConnectionAndPingIt(
1940 cricket::P2PTransportChannel* ch) {
1941 cricket::Connection* conn = ch->FindNextPingableConnection();
1942 if (conn) {
1943 ch->MarkConnectionPinged(conn);
1944 }
1945 return conn;
1946 }
1947
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001948 private:
1949 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1950 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1951 rtc::SocketServerScope ss_scope_;
1952};
1953
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001954TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001955 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08001956 cricket::P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001957 PrepareChannel(&ch);
1958 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07001959 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08001960 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
1961 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001962
1963 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
1964 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
1965 ASSERT_TRUE(conn1 != nullptr);
1966 ASSERT_TRUE(conn2 != nullptr);
1967
1968 // Before a triggered check, the first connection to ping is the
1969 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08001970 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001971
1972 // Receiving a ping causes a triggered check which should make conn1
1973 // be pinged first instead of conn2, even though conn2 has a higher
1974 // priority.
1975 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08001976 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001977}
1978
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07001979TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001980 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08001981 cricket::P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001982 PrepareChannel(&ch);
1983 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07001984 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08001985 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
1986 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001987
1988 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
1989 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
1990 ASSERT_TRUE(conn1 != nullptr);
1991 ASSERT_TRUE(conn2 != nullptr);
1992
guoweis36f01372016-03-02 18:02:40 -08001993 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
1994 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07001995 conn1->ReceivedPingResponse();
1996 ASSERT_TRUE(conn1->writable());
1997 conn1->ReceivedPing();
1998
1999 // Ping received, but the connection is already writable, so no
2000 // "triggered check" and conn2 is pinged before conn1 because it has
2001 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08002002 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002003}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002004
honghaiza54a0802015-12-16 18:37:23 -08002005// Test adding remote candidates with different ufrags. If a remote candidate
2006// is added with an old ufrag, it will be discarded. If it is added with a
2007// ufrag that was not seen before, it will be used to create connections
2008// although the ICE pwd in the remote candidate will be set when the ICE
2009// credentials arrive. If a remote candidate is added with the current ICE
2010// ufrag, its pwd and generation will be set properly.
2011TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
2012 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002013 cricket::P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08002014 PrepareChannel(&ch);
2015 ch.Connect();
2016 ch.MaybeStartGathering();
2017 // Add a candidate with a future ufrag.
guoweis36f01372016-03-02 18:02:40 -08002018 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1, kIceUfrag[2]));
honghaiza54a0802015-12-16 18:37:23 -08002019 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2020 ASSERT_TRUE(conn1 != nullptr);
2021 const cricket::Candidate& candidate = conn1->remote_candidate();
2022 EXPECT_EQ(kIceUfrag[2], candidate.username());
2023 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08002024 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08002025
2026 // Set the remote credentials with the "future" ufrag.
2027 // This should set the ICE pwd in the remote candidate of |conn1|, making
2028 // it pingable.
2029 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
2030 EXPECT_EQ(kIceUfrag[2], candidate.username());
2031 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08002032 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08002033
2034 // Add a candidate with an old ufrag. No connection will be created.
guoweis36f01372016-03-02 18:02:40 -08002035 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08002036 rtc::Thread::Current()->ProcessMessages(500);
2037 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
2038
2039 // Add a candidate with the current ufrag, its pwd and generation will be
2040 // assigned, even if the generation is not set.
guoweis36f01372016-03-02 18:02:40 -08002041 ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 0, kIceUfrag[2]));
honghaiza54a0802015-12-16 18:37:23 -08002042 cricket::Connection* conn3 = nullptr;
2043 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
2044 3000);
2045 const cricket::Candidate& new_candidate = conn3->remote_candidate();
2046 EXPECT_EQ(kIcePwd[2], new_candidate.password());
2047 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08002048
2049 // Check that the pwd of all remote candidates are properly assigned.
2050 for (const cricket::RemoteCandidate& candidate : ch.remote_candidates()) {
2051 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
2052 candidate.username() == kIceUfrag[2]);
2053 if (candidate.username() == kIceUfrag[1]) {
2054 EXPECT_EQ(kIcePwd[1], candidate.password());
2055 } else if (candidate.username() == kIceUfrag[2]) {
2056 EXPECT_EQ(kIcePwd[2], candidate.password());
2057 }
2058 }
honghaiza54a0802015-12-16 18:37:23 -08002059}
2060
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002061TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
2062 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002063 cricket::P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002064 PrepareChannel(&ch);
2065 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07002066 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002067
2068 // Create conn1 and keep track of original candidate priority.
guoweis36f01372016-03-02 18:02:40 -08002069 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002070 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2071 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02002072 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002073
2074 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07002075 // receiving/writable. This will prune conn1.
guoweis36f01372016-03-02 18:02:40 -08002076 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002077 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2078 ASSERT_TRUE(conn2 != nullptr);
2079 conn2->ReceivedPing();
2080 conn2->ReceivedPingResponse();
2081
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002082 // Wait for conn1 to be pruned.
2083 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
2084 // Destroy the connection to test SignalUnknownAddress.
2085 conn1->Destroy();
2086 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr, 1000);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002087
2088 // Create a minimal STUN message with prflx priority.
2089 cricket::IceMessage request;
2090 request.SetType(cricket::STUN_BINDING_REQUEST);
2091 request.AddAttribute(new cricket::StunByteStringAttribute(
2092 cricket::STUN_ATTR_USERNAME, kIceUfrag[1]));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002093 uint32_t prflx_priority = cricket::ICE_TYPE_PREFERENCE_PRFLX << 24;
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002094 request.AddAttribute(new cricket::StunUInt32Attribute(
2095 cricket::STUN_ATTR_PRIORITY, prflx_priority));
2096 EXPECT_NE(prflx_priority, remote_priority);
2097
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002098 cricket::Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002099 // conn1 should be resurrected with original priority.
2100 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1),
2101 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2102 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2103 ASSERT_TRUE(conn1 != nullptr);
2104 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
2105
2106 // conn3, a real prflx connection, should have prflx priority.
2107 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1),
2108 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2109 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
2110 ASSERT_TRUE(conn3 != nullptr);
2111 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
2112}
Peter Thatcher54360512015-07-08 11:08:35 -07002113
2114TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
2115 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002116 cricket::P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07002117 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08002118 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07002119 // small.
2120 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002121 EXPECT_LE(200, ch.check_receiving_interval());
honghaiz1f429e32015-09-28 07:57:34 -07002122 ch.SetIceConfig(CreateIceConfig(500, false));
Peter Thatcher54360512015-07-08 11:08:35 -07002123 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002124 EXPECT_EQ(50, ch.check_receiving_interval());
Peter Thatcher54360512015-07-08 11:08:35 -07002125 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07002126 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002127 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
Peter Thatcher54360512015-07-08 11:08:35 -07002128 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2129 ASSERT_TRUE(conn1 != nullptr);
2130
2131 conn1->ReceivedPing();
2132 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
torbjornga0892572015-12-16 18:38:31 -08002133 EXPECT_TRUE_WAIT(ch.best_connection() != nullptr, 1000);
Peter Thatcher54360512015-07-08 11:08:35 -07002134 EXPECT_TRUE_WAIT(ch.receiving(), 1000);
2135 EXPECT_TRUE_WAIT(!ch.receiving(), 1000);
2136}
honghaiz5a3acd82015-08-20 15:53:17 -07002137
2138// The controlled side will select a connection as the "best connection" based
2139// on priority until the controlling side nominates a connection, at which
2140// point the controlled side will select that connection as the
2141// "best connection".
2142TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
2143 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002144 cricket::P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07002145 PrepareChannel(&ch);
2146 ch.SetIceRole(cricket::ICEROLE_CONTROLLED);
2147 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07002148 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002149 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
honghaiz5a3acd82015-08-20 15:53:17 -07002150 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2151 ASSERT_TRUE(conn1 != nullptr);
2152 EXPECT_EQ(conn1, ch.best_connection());
2153
2154 // When a higher priority candidate comes in, the new connection is chosen
2155 // as the best connection.
guoweis36f01372016-03-02 18:02:40 -08002156 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 10));
honghaiz5a3acd82015-08-20 15:53:17 -07002157 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07002158 ASSERT_TRUE(conn2 != nullptr);
honghaiz5a3acd82015-08-20 15:53:17 -07002159 EXPECT_EQ(conn2, ch.best_connection());
2160
2161 // If a stun request with use-candidate attribute arrives, the receiving
2162 // connection will be set as the best connection, even though
2163 // its priority is lower.
guoweis36f01372016-03-02 18:02:40 -08002164 ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 1));
honghaiz5a3acd82015-08-20 15:53:17 -07002165 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
2166 ASSERT_TRUE(conn3 != nullptr);
2167 // Because it has a lower priority, the best connection is still conn2.
2168 EXPECT_EQ(conn2, ch.best_connection());
2169 conn3->ReceivedPingResponse(); // Become writable.
2170 // But if it is nominated via use_candidate, it is chosen as the best
2171 // connection.
2172 conn3->set_nominated(true);
2173 conn3->SignalNominated(conn3);
2174 EXPECT_EQ(conn3, ch.best_connection());
2175
2176 // Even if another higher priority candidate arrives,
2177 // it will not be set as the best connection because the best connection
2178 // is nominated by the controlling side.
guoweis36f01372016-03-02 18:02:40 -08002179 ch.AddRemoteCandidate(CreateHostCandidate("4.4.4.4", 4, 100));
honghaiz5a3acd82015-08-20 15:53:17 -07002180 cricket::Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
2181 ASSERT_TRUE(conn4 != nullptr);
2182 EXPECT_EQ(conn3, ch.best_connection());
2183 // But if it is nominated via use_candidate and writable, it will be set as
2184 // the best connection.
2185 conn4->set_nominated(true);
2186 conn4->SignalNominated(conn4);
2187 // Not switched yet because conn4 is not writable.
2188 EXPECT_EQ(conn3, ch.best_connection());
2189 // The best connection switches after conn4 becomes writable.
2190 conn4->ReceivedPingResponse();
2191 EXPECT_EQ(conn4, ch.best_connection());
2192}
2193
2194// The controlled side will select a connection as the "best connection" based
2195// on requests from an unknown address before the controlling side nominates
2196// a connection, and will nominate a connection from an unknown address if the
honghaiz9b5ee9c2015-11-11 13:19:17 -08002197// request contains the use_candidate attribute. Plus, it will also sends back
honghaiz112fe432015-12-30 13:32:47 -08002198// a ping response and set the ICE pwd in the remote candidate appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07002199TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
2200 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002201 cricket::P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07002202 PrepareChannel(&ch);
2203 ch.SetIceRole(cricket::ICEROLE_CONTROLLED);
2204 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07002205 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07002206 // A minimal STUN message with prflx priority.
2207 cricket::IceMessage request;
2208 request.SetType(cricket::STUN_BINDING_REQUEST);
2209 request.AddAttribute(new cricket::StunByteStringAttribute(
2210 cricket::STUN_ATTR_USERNAME, kIceUfrag[1]));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002211 uint32_t prflx_priority = cricket::ICE_TYPE_PREFERENCE_PRFLX << 24;
honghaiz5a3acd82015-08-20 15:53:17 -07002212 request.AddAttribute(new cricket::StunUInt32Attribute(
2213 cricket::STUN_ATTR_PRIORITY, prflx_priority));
honghaiz9b5ee9c2015-11-11 13:19:17 -08002214 cricket::TestUDPPort* port = static_cast<cricket::TestUDPPort*>(GetPort(&ch));
honghaiz5a3acd82015-08-20 15:53:17 -07002215 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1),
2216 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2217 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2218 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08002219 EXPECT_TRUE(port->sent_binding_response());
honghaiz5a3acd82015-08-20 15:53:17 -07002220 EXPECT_EQ(conn1, ch.best_connection());
2221 conn1->ReceivedPingResponse();
2222 EXPECT_EQ(conn1, ch.best_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08002223 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07002224
2225 // Another connection is nominated via use_candidate.
guoweis36f01372016-03-02 18:02:40 -08002226 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1));
honghaiz5a3acd82015-08-20 15:53:17 -07002227 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2228 ASSERT_TRUE(conn2 != nullptr);
2229 // Because it has a lower priority, the best connection is still conn1.
2230 EXPECT_EQ(conn1, ch.best_connection());
2231 // When it is nominated via use_candidate and writable, it is chosen as the
2232 // best connection.
2233 conn2->ReceivedPingResponse(); // Become writable.
2234 conn2->set_nominated(true);
2235 conn2->SignalNominated(conn2);
2236 EXPECT_EQ(conn2, ch.best_connection());
2237
2238 // Another request with unknown address, it will not be set as the best
2239 // connection because the best connection was nominated by the controlling
2240 // side.
2241 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3),
2242 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2243 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
2244 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08002245 EXPECT_TRUE(port->sent_binding_response());
honghaiz5a3acd82015-08-20 15:53:17 -07002246 conn3->ReceivedPingResponse(); // Become writable.
2247 EXPECT_EQ(conn2, ch.best_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08002248 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07002249
2250 // However if the request contains use_candidate attribute, it will be
2251 // selected as the best connection.
2252 request.AddAttribute(
2253 new cricket::StunByteStringAttribute(cricket::STUN_ATTR_USE_CANDIDATE));
2254 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4),
2255 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2256 cricket::Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
2257 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08002258 EXPECT_TRUE(port->sent_binding_response());
honghaiz5a3acd82015-08-20 15:53:17 -07002259 // conn4 is not the best connection yet because it is not writable.
2260 EXPECT_EQ(conn2, ch.best_connection());
2261 conn4->ReceivedPingResponse(); // Become writable.
2262 EXPECT_EQ(conn4, ch.best_connection());
honghaiz112fe432015-12-30 13:32:47 -08002263
2264 // Test that the request from an unknown address contains a ufrag from an old
2265 // generation.
2266 port->set_sent_binding_response(false);
2267 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
2268 ch.SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
2269 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5),
2270 cricket::PROTO_UDP, &request, kIceUfrag[2], false);
2271 cricket::Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
2272 ASSERT_TRUE(conn5 != nullptr);
2273 EXPECT_TRUE(port->sent_binding_response());
2274 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07002275}
2276
2277// The controlled side will select a connection as the "best connection"
2278// based on media received until the controlling side nominates a connection,
2279// at which point the controlled side will select that connection as
2280// the "best connection".
2281TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
2282 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002283 cricket::P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07002284 PrepareChannel(&ch);
2285 ch.SetIceRole(cricket::ICEROLE_CONTROLLED);
2286 ch.Connect();
deadbeefcbecd352015-09-23 11:50:27 -07002287 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002288 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 10));
honghaiz5a3acd82015-08-20 15:53:17 -07002289 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2290 ASSERT_TRUE(conn1 != nullptr);
2291 EXPECT_EQ(conn1, ch.best_connection());
2292
2293 // If a data packet is received on conn2, the best connection should
2294 // switch to conn2 because the controlled side must mirror the media path
2295 // chosen by the controlling side.
guoweis36f01372016-03-02 18:02:40 -08002296 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1));
honghaiz5a3acd82015-08-20 15:53:17 -07002297 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2298 ASSERT_TRUE(conn2 != nullptr);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07002299 conn2->ReceivedPing(); // Start receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07002300 // Do not switch because it is not writable.
2301 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
2302 EXPECT_EQ(conn1, ch.best_connection());
2303
2304 conn2->ReceivedPingResponse(); // Become writable.
2305 // Switch because it is writable.
2306 conn2->OnReadPacket("DEF", 3, rtc::CreatePacketTime(0));
2307 EXPECT_EQ(conn2, ch.best_connection());
2308
2309 // Now another STUN message with an unknown address and use_candidate will
2310 // nominate the best connection.
2311 cricket::IceMessage request;
2312 request.SetType(cricket::STUN_BINDING_REQUEST);
2313 request.AddAttribute(new cricket::StunByteStringAttribute(
2314 cricket::STUN_ATTR_USERNAME, kIceUfrag[1]));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002315 uint32_t prflx_priority = cricket::ICE_TYPE_PREFERENCE_PRFLX << 24;
honghaiz5a3acd82015-08-20 15:53:17 -07002316 request.AddAttribute(new cricket::StunUInt32Attribute(
2317 cricket::STUN_ATTR_PRIORITY, prflx_priority));
2318 request.AddAttribute(
2319 new cricket::StunByteStringAttribute(cricket::STUN_ATTR_USE_CANDIDATE));
2320 cricket::Port* port = GetPort(&ch);
2321 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3),
2322 cricket::PROTO_UDP, &request, kIceUfrag[1], false);
2323 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
2324 ASSERT_TRUE(conn3 != nullptr);
2325 EXPECT_EQ(conn2, ch.best_connection()); // Not writable yet.
2326 conn3->ReceivedPingResponse(); // Become writable.
2327 EXPECT_EQ(conn3, ch.best_connection());
2328
2329 // Now another data packet will not switch the best connection because the
2330 // best connection was nominated by the controlling side.
2331 conn2->ReceivedPing();
2332 conn2->ReceivedPingResponse();
2333 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
2334 EXPECT_EQ(conn3, ch.best_connection());
2335}
honghaiz89374372015-09-24 13:14:47 -07002336
2337// When the current best connection is strong, lower-priority connections will
2338// be pruned. Otherwise, lower-priority connections are kept.
2339TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
2340 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002341 cricket::P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07002342 PrepareChannel(&ch);
2343 ch.SetIceRole(cricket::ICEROLE_CONTROLLED);
2344 ch.Connect();
2345 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002346 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
honghaiz89374372015-09-24 13:14:47 -07002347 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2348 ASSERT_TRUE(conn1 != nullptr);
2349 EXPECT_EQ(conn1, ch.best_connection());
2350 conn1->ReceivedPingResponse(); // Becomes writable and receiving
2351
2352 // When a higher-priority, nominated candidate comes in, the connections with
2353 // lower-priority are pruned.
guoweis36f01372016-03-02 18:02:40 -08002354 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 10));
honghaiz89374372015-09-24 13:14:47 -07002355 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2356 ASSERT_TRUE(conn2 != nullptr);
2357 conn2->ReceivedPingResponse(); // Becomes writable and receiving
2358 conn2->set_nominated(true);
2359 conn2->SignalNominated(conn2);
2360 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
2361
honghaiz1f429e32015-09-28 07:57:34 -07002362 ch.SetIceConfig(CreateIceConfig(500, false));
honghaiz89374372015-09-24 13:14:47 -07002363 // Wait until conn2 becomes not receiving.
2364 EXPECT_TRUE_WAIT(!conn2->receiving(), 3000);
2365
guoweis36f01372016-03-02 18:02:40 -08002366 ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 1));
honghaiz89374372015-09-24 13:14:47 -07002367 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
2368 ASSERT_TRUE(conn3 != nullptr);
2369 // The best connection should still be conn2. Even through conn3 has lower
2370 // priority and is not receiving/writable, it is not pruned because the best
2371 // connection is not receiving.
2372 WAIT(conn3->pruned(), 1000);
2373 EXPECT_FALSE(conn3->pruned());
2374}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002375
2376// Test that GetState returns the state correctly.
2377TEST_F(P2PTransportChannelPingTest, TestGetState) {
2378 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002379 cricket::P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002380 PrepareChannel(&ch);
2381 ch.Connect();
2382 ch.MaybeStartGathering();
2383 EXPECT_EQ(cricket::TransportChannelState::STATE_INIT, ch.GetState());
guoweis36f01372016-03-02 18:02:40 -08002384 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100));
2385 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002386 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2387 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2388 ASSERT_TRUE(conn1 != nullptr);
2389 ASSERT_TRUE(conn2 != nullptr);
2390 // Now there are two connections, so the transport channel is connecting.
2391 EXPECT_EQ(cricket::TransportChannelState::STATE_CONNECTING, ch.GetState());
2392 // |conn1| becomes writable and receiving; it then should prune |conn2|.
2393 conn1->ReceivedPingResponse();
2394 EXPECT_TRUE_WAIT(conn2->pruned(), 1000);
2395 EXPECT_EQ(cricket::TransportChannelState::STATE_COMPLETED, ch.GetState());
2396 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08002397 // Need to wait until the channel state is updated.
2398 EXPECT_EQ_WAIT(cricket::TransportChannelState::STATE_FAILED, ch.GetState(),
2399 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002400}
2401
2402// Test that when a low-priority connection is pruned, it is not deleted
2403// right away, and it can become active and be pruned again.
2404TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
2405 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002406 cricket::P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002407 PrepareChannel(&ch);
2408 ch.SetIceConfig(CreateIceConfig(1000, false));
2409 ch.Connect();
2410 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002411 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002412 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2413 ASSERT_TRUE(conn1 != nullptr);
2414 EXPECT_EQ(conn1, ch.best_connection());
2415 conn1->ReceivedPingResponse(); // Becomes writable and receiving
2416
2417 // Add a low-priority connection |conn2|, which will be pruned, but it will
2418 // not be deleted right away. Once the current best connection becomes not
2419 // receiving, |conn2| will start to ping and upon receiving the ping response,
2420 // it will become the best connection.
guoweis36f01372016-03-02 18:02:40 -08002421 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002422 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2423 ASSERT_TRUE(conn2 != nullptr);
2424 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
2425 // |conn2| should not send a ping yet.
2426 EXPECT_EQ(cricket::Connection::STATE_WAITING, conn2->state());
2427 EXPECT_EQ(cricket::TransportChannelState::STATE_COMPLETED, ch.GetState());
2428 // Wait for |conn1| becoming not receiving.
2429 EXPECT_TRUE_WAIT(!conn1->receiving(), 3000);
2430 // Make sure conn2 is not deleted.
2431 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2432 ASSERT_TRUE(conn2 != nullptr);
2433 EXPECT_EQ_WAIT(cricket::Connection::STATE_INPROGRESS, conn2->state(), 1000);
2434 conn2->ReceivedPingResponse();
2435 EXPECT_EQ_WAIT(conn2, ch.best_connection(), 1000);
2436 EXPECT_EQ(cricket::TransportChannelState::STATE_CONNECTING, ch.GetState());
2437
2438 // When |conn1| comes back again, |conn2| will be pruned again.
2439 conn1->ReceivedPingResponse();
2440 EXPECT_EQ_WAIT(conn1, ch.best_connection(), 1000);
2441 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
2442 EXPECT_EQ(cricket::TransportChannelState::STATE_COMPLETED, ch.GetState());
2443}
honghaiz77d0d6e2015-10-27 11:34:45 -07002444
2445// Test that if all connections in a channel has timed out on writing, they
2446// will all be deleted. We use Prune to simulate write_time_out.
2447TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
2448 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002449 cricket::P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07002450 PrepareChannel(&ch);
2451 ch.Connect();
2452 ch.MaybeStartGathering();
2453 // Have one connection only but later becomes write-time-out.
guoweis36f01372016-03-02 18:02:40 -08002454 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100));
honghaiz77d0d6e2015-10-27 11:34:45 -07002455 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2456 ASSERT_TRUE(conn1 != nullptr);
2457 conn1->ReceivedPing(); // Becomes receiving
2458 conn1->Prune();
2459 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
2460
2461 // Have two connections but both become write-time-out later.
guoweis36f01372016-03-02 18:02:40 -08002462 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1));
honghaiz77d0d6e2015-10-27 11:34:45 -07002463 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2464 ASSERT_TRUE(conn2 != nullptr);
2465 conn2->ReceivedPing(); // Becomes receiving
guoweis36f01372016-03-02 18:02:40 -08002466 ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 2));
honghaiz77d0d6e2015-10-27 11:34:45 -07002467 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
2468 ASSERT_TRUE(conn3 != nullptr);
2469 conn3->ReceivedPing(); // Becomes receiving
2470 // Now prune both conn2 and conn3; they will be deleted soon.
2471 conn2->Prune();
2472 conn3->Prune();
2473 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
2474}
honghaiz9b669572015-11-04 12:07:44 -08002475
2476// Test that after a port allocator session is started, it will be stopped
2477// when a new connection becomes writable and receiving. Also test that this
2478// holds even if the transport channel did not lose the writability.
2479TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
2480 cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr);
mikescarlettb9dd7c52016-02-19 20:43:45 -08002481 cricket::P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08002482 PrepareChannel(&ch);
2483 ch.SetIceConfig(CreateIceConfig(2000, false));
2484 ch.Connect();
2485 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002486 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100));
honghaiz9b669572015-11-04 12:07:44 -08002487 cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2488 ASSERT_TRUE(conn1 != nullptr);
2489 conn1->ReceivedPingResponse(); // Becomes writable and receiving
2490 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
2491
2492 // Restart gathering even if the transport channel is still writable.
2493 // It should stop getting ports after a new connection becomes strongly
2494 // connected.
2495 ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]);
2496 ch.MaybeStartGathering();
guoweis36f01372016-03-02 18:02:40 -08002497 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 100));
honghaiz9b669572015-11-04 12:07:44 -08002498 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2499 ASSERT_TRUE(conn2 != nullptr);
2500 conn2->ReceivedPingResponse(); // Becomes writable and receiving
2501 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
2502}
guoweis36f01372016-03-02 18:02:40 -08002503
2504class P2PTransportChannelMostLikelyToWorkFirstTest
2505 : public P2PTransportChannelPingTest {
2506 public:
2507 P2PTransportChannelMostLikelyToWorkFirstTest()
2508 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
2509 network_manager_.AddInterface(kPublicAddrs[0]);
2510 allocator_.reset(new cricket::BasicPortAllocator(
2511 &network_manager_, ServerAddresses(), rtc::SocketAddress(),
2512 rtc::SocketAddress(), rtc::SocketAddress()));
2513 allocator_->set_flags(allocator_->flags() |
2514 cricket::PORTALLOCATOR_DISABLE_STUN |
2515 cricket::PORTALLOCATOR_DISABLE_TCP);
2516 cricket::RelayServerConfig config(cricket::RELAY_TURN);
2517 config.credentials = kRelayCredentials;
2518 config.ports.push_back(
2519 cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
2520 allocator_->AddTurnServer(config);
2521 allocator_->set_step_delay(kMinimumStepDelay);
2522 }
2523
2524 cricket::P2PTransportChannel& StartTransportChannel(
2525 bool prioritize_most_likely_to_work,
Honghai Zhang049fbb12016-03-07 11:13:07 -08002526 int max_strong_interval) {
guoweis36f01372016-03-02 18:02:40 -08002527 channel_.reset(
2528 new cricket::P2PTransportChannel("checks", 1, nullptr, allocator()));
2529 cricket::IceConfig config = channel_->config();
2530 config.prioritize_most_likely_candidate_pairs =
2531 prioritize_most_likely_to_work;
Honghai Zhang049fbb12016-03-07 11:13:07 -08002532 config.max_strong_interval = max_strong_interval;
guoweis36f01372016-03-02 18:02:40 -08002533 channel_->SetIceConfig(config);
2534 PrepareChannel(channel_.get());
2535 channel_->Connect();
2536 channel_->MaybeStartGathering();
2537 return *channel_.get();
2538 }
2539
2540 cricket::BasicPortAllocator* allocator() { return allocator_.get(); }
2541 cricket::TestTurnServer* turn_server() { return &turn_server_; }
2542
2543 // This verifies the next pingable connection has the expected candidates'
2544 // types and, for relay local candidate, the expected relay protocol and ping
2545 // it.
2546 void VerifyNextPingableConnection(
2547 const std::string& local_candidate_type,
2548 const std::string& remote_candidate_type,
2549 const std::string& relay_protocol_type = cricket::UDP_PROTOCOL_NAME) {
2550 cricket::Connection* conn =
2551 FindNextPingableConnectionAndPingIt(channel_.get());
2552 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
2553 if (conn->local_candidate().type() == cricket::RELAY_PORT_TYPE) {
2554 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
2555 }
2556 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
2557 }
2558
2559 cricket::Candidate CreateRelayCandidate(const std::string& ip,
2560 int port,
2561 int priority,
2562 const std::string& ufrag = "") {
2563 cricket::Candidate c = CreateHostCandidate(ip, port, priority, ufrag);
2564 c.set_type(cricket::RELAY_PORT_TYPE);
2565 return c;
2566 }
2567
2568 private:
2569 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
2570 rtc::FakeNetworkManager network_manager_;
2571 cricket::TestTurnServer turn_server_;
2572 rtc::scoped_ptr<cricket::P2PTransportChannel> channel_;
2573};
2574
2575// Test that Relay/Relay connections will be pinged first when no other
2576// connections have been pinged yet, unless we need to ping a trigger check or
2577// we have a best connection.
2578TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
2579 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08002580 const int max_strong_interval = 100;
guoweis36f01372016-03-02 18:02:40 -08002581 cricket::P2PTransportChannel& ch =
Honghai Zhang049fbb12016-03-07 11:13:07 -08002582 StartTransportChannel(true, max_strong_interval);
guoweis36f01372016-03-02 18:02:40 -08002583 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
2584 EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE);
2585 EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE);
2586
2587 ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1));
2588 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2));
2589
2590 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
2591
2592 // Relay/Relay should be the first pingable connection.
2593 cricket::Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
2594 EXPECT_EQ(conn->local_candidate().type(), cricket::RELAY_PORT_TYPE);
2595 EXPECT_EQ(conn->remote_candidate().type(), cricket::RELAY_PORT_TYPE);
2596
2597 // Unless that we have a trigger check waiting to be pinged.
2598 cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
2599 EXPECT_EQ(conn2->local_candidate().type(), cricket::LOCAL_PORT_TYPE);
2600 EXPECT_EQ(conn2->remote_candidate().type(), cricket::LOCAL_PORT_TYPE);
2601 conn2->ReceivedPing();
2602 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
2603
2604 // Make conn3 the best connection.
2605 cricket::Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2606 EXPECT_EQ(conn3->local_candidate().type(), cricket::LOCAL_PORT_TYPE);
2607 EXPECT_EQ(conn3->remote_candidate().type(), cricket::RELAY_PORT_TYPE);
2608 conn3->ReceivedPingResponse();
2609 ASSERT_TRUE(conn3->writable());
2610 conn3->ReceivedPing();
2611
2612 // Verify that conn3 will be the "best connection" since it is readable and
Honghai Zhang049fbb12016-03-07 11:13:07 -08002613 // writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
2614 // pingable connection.
guoweis36f01372016-03-02 18:02:40 -08002615 EXPECT_TRUE_WAIT(conn3 == ch.best_connection(), 5000);
Honghai Zhang049fbb12016-03-07 11:13:07 -08002616 WAIT(false, max_strong_interval + 100);
guoweis36f01372016-03-02 18:02:40 -08002617 conn3->ReceivedPingResponse();
2618 ASSERT_TRUE(conn3->writable());
2619 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
2620}
2621
2622// Test that Relay/Relay connections will be pinged first when everything has
2623// been pinged even if the Relay/Relay connection wasn't the first to be pinged
2624// in the first round.
2625TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
2626 TestRelayRelayFirstWhenEverythingPinged) {
2627 cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100);
2628 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
2629 EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE);
2630 EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE);
2631
2632 ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1));
2633 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
2634
2635 // Initially, only have Local/Local and Local/Relay.
2636 VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE,
2637 cricket::LOCAL_PORT_TYPE);
2638 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2639 cricket::LOCAL_PORT_TYPE);
2640
2641 // Remote Relay candidate arrives.
2642 ch.AddRemoteCandidate(CreateRelayCandidate("2.2.2.2", 2, 2));
2643 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
2644
2645 // Relay/Relay should be the first since it hasn't been pinged before.
2646 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2647 cricket::RELAY_PORT_TYPE);
2648
2649 // Local/Relay is the final one.
2650 VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE,
2651 cricket::RELAY_PORT_TYPE);
2652
2653 // Now, every connection has been pinged once. The next one should be
2654 // Relay/Relay.
2655 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2656 cricket::RELAY_PORT_TYPE);
2657}
2658
2659// Test that when we receive a new remote candidate, they will be tried first
2660// before we re-ping Relay/Relay connections again.
2661TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
2662 TestNoStarvationOnNonRelayConnection) {
2663 cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100);
2664 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
2665 EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE);
2666 EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE);
2667
2668 ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1));
2669 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
2670
2671 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
2672 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2673 cricket::RELAY_PORT_TYPE);
2674
2675 // Next, ping Local/Relay.
2676 VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE,
2677 cricket::RELAY_PORT_TYPE);
2678
2679 // Remote Local candidate arrives.
2680 ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2));
2681 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
2682
2683 // Local/Local should be the first since it hasn't been pinged before.
2684 VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE,
2685 cricket::LOCAL_PORT_TYPE);
2686
2687 // Relay/Local is the final one.
2688 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2689 cricket::LOCAL_PORT_TYPE);
2690
2691 // Now, every connection has been pinged once. The next one should be
2692 // Relay/Relay.
2693 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2694 cricket::RELAY_PORT_TYPE);
2695}
2696
2697// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
2698// followed by the rest.
2699TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
2700 // Add a Tcp Turn server.
2701 turn_server()->AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
2702 cricket::RelayServerConfig config(cricket::RELAY_TURN);
2703 config.credentials = kRelayCredentials;
2704 config.ports.push_back(
2705 cricket::ProtocolAddress(kTurnTcpIntAddr, cricket::PROTO_TCP, false));
2706 allocator()->AddTurnServer(config);
2707
2708 cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100);
2709 EXPECT_TRUE_WAIT(ch.ports().size() == 3, 5000);
2710 EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE);
2711 EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE);
2712 EXPECT_EQ(ch.ports()[2]->Type(), cricket::RELAY_PORT_TYPE);
2713
2714 // Remote Relay candidate arrives.
2715 ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1));
2716 EXPECT_TRUE_WAIT(ch.connections().size() == 3, 5000);
2717
2718 // UDP Relay/Relay should be pinged first.
2719 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2720 cricket::RELAY_PORT_TYPE);
2721
2722 // TCP Relay/Relay is the next.
2723 VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE,
2724 cricket::RELAY_PORT_TYPE,
2725 cricket::TCP_PROTOCOL_NAME);
2726
2727 // Finally, Local/Relay will be pinged.
2728 VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE,
2729 cricket::RELAY_PORT_TYPE);
2730}