blob: b10562105966078f5c464a1e8d3656529b59c211 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2009 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Taylor Brandstettera1c30352016-05-13 08:15:11 -070011#include <algorithm>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
13
Taylor Brandstettera1c30352016-05-13 08:15:11 -070014#include "webrtc/p2p/base/fakeportallocator.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000015#include "webrtc/p2p/base/p2ptransportchannel.h"
16#include "webrtc/p2p/base/testrelayserver.h"
17#include "webrtc/p2p/base/teststunserver.h"
18#include "webrtc/p2p/base/testturnserver.h"
19#include "webrtc/p2p/client/basicportallocator.h"
20#include "webrtc/base/dscp.h"
deadbeefdfc42442016-06-21 14:19:48 -070021#include "webrtc/base/fakeclock.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000022#include "webrtc/base/fakenetwork.h"
23#include "webrtc/base/firewallsocketserver.h"
24#include "webrtc/base/gunit.h"
25#include "webrtc/base/helpers.h"
26#include "webrtc/base/logging.h"
27#include "webrtc/base/natserver.h"
28#include "webrtc/base/natsocketfactory.h"
29#include "webrtc/base/physicalsocketserver.h"
30#include "webrtc/base/proxyserver.h"
31#include "webrtc/base/socketaddress.h"
32#include "webrtc/base/ssladapter.h"
33#include "webrtc/base/thread.h"
34#include "webrtc/base/virtualsocketserver.h"
35
deadbeef14f97f52016-06-22 17:14:15 -070036namespace {
37
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000038using rtc::SocketAddress;
39
deadbeef14f97f52016-06-22 17:14:15 -070040// Default timeout for tests in this file.
41// Should be large enough for slow buildbots to run the tests reliably.
42static const int kDefaultTimeout = 10000;
43
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
45 cricket::PORTALLOCATOR_DISABLE_RELAY |
46 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070047static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000048// Addresses on the public internet.
49static const SocketAddress kPublicAddrs[2] =
50 { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
51// IPv6 Addresses on the public internet.
52static const SocketAddress kIPv6PublicAddrs[2] = {
53 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
54 SocketAddress("2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)
55};
56// For configuring multihomed clients.
57static const SocketAddress kAlternateAddrs[2] =
58 { SocketAddress("11.11.11.101", 0), SocketAddress("22.22.22.202", 0) };
59// Addresses for HTTP proxy servers.
60static const SocketAddress kHttpsProxyAddrs[2] =
61 { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
62// Addresses for SOCKS proxy servers.
63static const SocketAddress kSocksProxyAddrs[2] =
64 { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
65// Internal addresses for NAT boxes.
66static const SocketAddress kNatAddrs[2] =
67 { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
68// Private addresses inside the NAT private networks.
69static const SocketAddress kPrivateAddrs[2] =
70 { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
71// For cascaded NATs, the internal addresses of the inner NAT boxes.
72static const SocketAddress kCascadedNatAddrs[2] =
73 { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
74// For cascaded NATs, private addresses inside the inner private networks.
75static const SocketAddress kCascadedPrivateAddrs[2] =
76 { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
77// The address of the public STUN server.
78static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
79// The addresses for the public relay server.
80static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
81static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
82static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
83static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
84static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
85static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
86// The addresses for the public turn server.
87static const SocketAddress kTurnUdpIntAddr("99.99.99.4",
88 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -080089static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
90 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000091static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
92static const cricket::RelayCredentials kRelayCredentials("test", "test");
93
94// Based on ICE_UFRAG_LENGTH
zhihuang6d0d4bf2016-05-24 10:13:32 -070095static const char* kIceUfrag[4] = {"UF00", "UF01",
96 "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097// Based on ICE_PWD_LENGTH
98static const char* kIcePwd[4] = {"TESTICEPWD00000000000000",
99 "TESTICEPWD00000000000001",
100 "TESTICEPWD00000000000002",
101 "TESTICEPWD00000000000003"};
102
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700103static const uint64_t kLowTiebreaker = 11111;
104static const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700106enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000107
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700108cricket::IceConfig CreateIceConfig(
109 int receiving_timeout,
110 cricket::ContinualGatheringPolicy continual_gathering_policy,
111 int backup_ping_interval = -1) {
honghaiz1f429e32015-09-28 07:57:34 -0700112 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800113 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700114 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800115 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700116 return config;
117}
118
deadbeef14f97f52016-06-22 17:14:15 -0700119cricket::Candidate CreateUdpCandidate(const std::string& type,
120 const std::string& ip,
121 int port,
122 int priority,
123 const std::string& ufrag = "") {
124 cricket::Candidate c;
125 c.set_address(rtc::SocketAddress(ip, port));
126 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
127 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
128 c.set_priority(priority);
129 c.set_username(ufrag);
130 c.set_type(type);
131 return c;
132}
133
134} // namespace {
135
136namespace cricket {
137
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138// This test simulates 2 P2P endpoints that want to establish connectivity
139// with each other over various network topologies and conditions, which can be
140// specified in each individial test.
141// A virtual network (via VirtualSocketServer) along with virtual firewalls and
142// NATs (via Firewall/NATSocketServer) are used to simulate the various network
143// conditions. We can configure the IP addresses of the endpoints,
144// block various types of connectivity, or add arbitrary levels of NAT.
145// We also run a STUN server and a relay server on the virtual network to allow
146// our typical P2P mechanisms to do their thing.
147// For each case, we expect the P2P stack to eventually settle on a specific
148// form of connectivity to the other side. The test checks that the P2P
149// negotiation successfully establishes connectivity within a certain time,
150// and that the result is what we expect.
151// Note that this class is a base class for use by other tests, who will provide
152// specialized test behavior.
153class P2PTransportChannelTestBase : public testing::Test,
154 public rtc::MessageHandler,
155 public sigslot::has_slots<> {
156 public:
157 P2PTransportChannelTestBase()
158 : main_(rtc::Thread::Current()),
159 pss_(new rtc::PhysicalSocketServer),
160 vss_(new rtc::VirtualSocketServer(pss_.get())),
161 nss_(new rtc::NATSocketServer(vss_.get())),
162 ss_(new rtc::FirewallSocketServer(nss_.get())),
163 ss_scope_(ss_.get()),
deadbeef14f97f52016-06-22 17:14:15 -0700164 stun_server_(TestStunServer::Create(main_, kStunAddr)),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeef14f97f52016-06-22 17:14:15 -0700166 relay_server_(main_,
167 kRelayUdpIntAddr,
168 kRelayUdpExtAddr,
169 kRelayTcpIntAddr,
170 kRelayTcpExtAddr,
171 kRelaySslTcpIntAddr,
172 kRelaySslTcpExtAddr),
173 socks_server1_(ss_.get(),
174 kSocksProxyAddrs[0],
175 ss_.get(),
176 kSocksProxyAddrs[0]),
177 socks_server2_(ss_.get(),
178 kSocksProxyAddrs[1],
179 ss_.get(),
180 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000181 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700182 ep1_.role_ = ICEROLE_CONTROLLING;
183 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184
185 ServerAddresses stun_servers;
186 stun_servers.insert(kStunAddr);
deadbeef14f97f52016-06-22 17:14:15 -0700187 ep1_.allocator_.reset(new BasicPortAllocator(
188 &ep1_.network_manager_, stun_servers, kRelayUdpIntAddr,
189 kRelayTcpIntAddr, kRelaySslTcpIntAddr));
190 ep2_.allocator_.reset(new BasicPortAllocator(
191 &ep2_.network_manager_, stun_servers, kRelayUdpIntAddr,
192 kRelayTcpIntAddr, kRelaySslTcpIntAddr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 }
194
195 protected:
196 enum Config {
197 OPEN, // Open to the Internet
198 NAT_FULL_CONE, // NAT, no filtering
199 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
200 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
201 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
202 NAT_DOUBLE_CONE, // Double NAT, both cone
203 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
204 BLOCK_UDP, // Firewall, UDP in/out blocked
205 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
206 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
207 PROXY_HTTPS, // All traffic through HTTPS proxy
208 PROXY_SOCKS, // All traffic through SOCKS proxy
209 NUM_CONFIGS
210 };
211
212 struct Result {
213 Result(const std::string& lt, const std::string& lp,
214 const std::string& rt, const std::string& rp,
215 const std::string& lt2, const std::string& lp2,
216 const std::string& rt2, const std::string& rp2, int wait)
217 : local_type(lt), local_proto(lp), remote_type(rt), remote_proto(rp),
218 local_type2(lt2), local_proto2(lp2), remote_type2(rt2),
219 remote_proto2(rp2), connect_wait(wait) {
220 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700221
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222 std::string local_type;
223 std::string local_proto;
224 std::string remote_type;
225 std::string remote_proto;
226 std::string local_type2;
227 std::string local_proto2;
228 std::string remote_type2;
229 std::string remote_proto2;
230 int connect_wait;
231 };
232
233 struct ChannelData {
234 bool CheckData(const char* data, int len) {
235 bool ret = false;
236 if (!ch_packets_.empty()) {
237 std::string packet = ch_packets_.front();
238 ret = (packet == std::string(data, len));
239 ch_packets_.pop_front();
240 }
241 return ret;
242 }
243
244 std::string name_; // TODO - Currently not used.
245 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700246 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000247 };
248
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700249 struct CandidatesData : public rtc::MessageData {
deadbeef14f97f52016-06-22 17:14:15 -0700250 CandidatesData(TransportChannel* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700251 : channel(ch), candidates(1, c) {}
deadbeef14f97f52016-06-22 17:14:15 -0700252 CandidatesData(TransportChannel* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700253 : channel(ch), candidates(cc) {}
deadbeef14f97f52016-06-22 17:14:15 -0700254 TransportChannel* channel;
255 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000256 };
257
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000258 struct Endpoint {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000259 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700260 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000261 tiebreaker_(0),
262 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700263 save_candidates_(false) {}
deadbeef14f97f52016-06-22 17:14:15 -0700264 bool HasChannel(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000265 return (ch == cd1_.ch_.get() || ch == cd2_.ch_.get());
266 }
deadbeef14f97f52016-06-22 17:14:15 -0700267 ChannelData* GetChannelData(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000268 if (!HasChannel(ch)) return NULL;
269 if (cd1_.ch_.get() == ch)
270 return &cd1_;
271 else
272 return &cd2_;
273 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000274
deadbeef14f97f52016-06-22 17:14:15 -0700275 void SetIceRole(IceRole role) { role_ = role; }
276 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200277 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
278 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
280 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200281 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000282 allocator_->set_step_delay(delay);
283 }
284 void SetAllowTcpListen(bool allow_tcp_listen) {
285 allocator_->set_allow_tcp_listen(allow_tcp_listen);
286 }
287
288 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -0700289 std::unique_ptr<BasicPortAllocator> allocator_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000290 ChannelData cd1_;
291 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700292 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200293 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000294 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000295 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700296 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700297 bool ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000298 };
299
deadbeef14f97f52016-06-22 17:14:15 -0700300 ChannelData* GetChannelData(TransportChannel* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 if (ep1_.HasChannel(channel))
302 return ep1_.GetChannelData(channel);
303 else
304 return ep2_.GetChannelData(channel);
305 }
306
307 void CreateChannels(int num) {
308 std::string ice_ufrag_ep1_cd1_ch = kIceUfrag[0];
309 std::string ice_pwd_ep1_cd1_ch = kIcePwd[0];
310 std::string ice_ufrag_ep2_cd1_ch = kIceUfrag[1];
311 std::string ice_pwd_ep2_cd1_ch = kIcePwd[1];
312 ep1_.cd1_.ch_.reset(CreateChannel(
deadbeef14f97f52016-06-22 17:14:15 -0700313 0, ICE_CANDIDATE_COMPONENT_DEFAULT, ice_ufrag_ep1_cd1_ch,
314 ice_pwd_ep1_cd1_ch, ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000315 ep2_.cd1_.ch_.reset(CreateChannel(
deadbeef14f97f52016-06-22 17:14:15 -0700316 1, ICE_CANDIDATE_COMPONENT_DEFAULT, ice_ufrag_ep2_cd1_ch,
317 ice_pwd_ep2_cd1_ch, ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch));
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700318 ep1_.cd1_.ch_->MaybeStartGathering();
319 ep2_.cd1_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000320 if (num == 2) {
321 std::string ice_ufrag_ep1_cd2_ch = kIceUfrag[2];
322 std::string ice_pwd_ep1_cd2_ch = kIcePwd[2];
323 std::string ice_ufrag_ep2_cd2_ch = kIceUfrag[3];
324 std::string ice_pwd_ep2_cd2_ch = kIcePwd[3];
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000325 ep1_.cd2_.ch_.reset(CreateChannel(
deadbeef14f97f52016-06-22 17:14:15 -0700326 0, ICE_CANDIDATE_COMPONENT_DEFAULT, ice_ufrag_ep1_cd2_ch,
327 ice_pwd_ep1_cd2_ch, ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000328 ep2_.cd2_.ch_.reset(CreateChannel(
deadbeef14f97f52016-06-22 17:14:15 -0700329 1, ICE_CANDIDATE_COMPONENT_DEFAULT, ice_ufrag_ep2_cd2_ch,
330 ice_pwd_ep2_cd2_ch, ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch));
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700331 ep1_.cd2_.ch_->MaybeStartGathering();
332 ep2_.cd2_.ch_->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000333 }
334 }
deadbeef14f97f52016-06-22 17:14:15 -0700335 P2PTransportChannel* CreateChannel(int endpoint,
336 int component,
337 const std::string& local_ice_ufrag,
338 const std::string& local_ice_pwd,
339 const std::string& remote_ice_ufrag,
340 const std::string& remote_ice_pwd) {
341 P2PTransportChannel* channel = new P2PTransportChannel(
mikescarlettb9dd7c52016-02-19 20:43:45 -0800342 "test content name", component, GetAllocator(endpoint));
deadbeef14f97f52016-06-22 17:14:15 -0700343 channel->SignalReadyToSend.connect(
344 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700345 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700346 this, &P2PTransportChannelTestBase::OnCandidateGathered);
347 channel->SignalCandidatesRemoved.connect(
348 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000349 channel->SignalReadPacket.connect(
350 this, &P2PTransportChannelTestBase::OnReadPacket);
351 channel->SignalRoleConflict.connect(
352 this, &P2PTransportChannelTestBase::OnRoleConflict);
honghaiz9ad0db52016-07-14 19:30:28 -0700353 channel->SignalSelectedCandidatePairChanged.connect(
354 this, &P2PTransportChannelTestBase::OnSelectedCandidatePairChanged);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000355 channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd);
deadbeef0af180b2016-06-21 13:15:32 -0700356 if (remote_ice_credential_source_ == FROM_SETICECREDENTIALS) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000357 channel->SetRemoteIceCredentials(remote_ice_ufrag, remote_ice_pwd);
358 }
359 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
360 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000361 return channel;
362 }
363 void DestroyChannels() {
364 ep1_.cd1_.ch_.reset();
365 ep2_.cd1_.ch_.reset();
366 ep1_.cd2_.ch_.reset();
367 ep2_.cd2_.ch_.reset();
368 }
deadbeef14f97f52016-06-22 17:14:15 -0700369 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
370 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
371 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
372 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000373
Taylor Brandstetteref184702016-06-23 17:35:47 -0700374 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700375 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700376
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000377 // Common results.
378 static const Result kLocalUdpToLocalUdp;
379 static const Result kLocalUdpToStunUdp;
380 static const Result kLocalUdpToPrflxUdp;
381 static const Result kPrflxUdpToLocalUdp;
382 static const Result kStunUdpToLocalUdp;
383 static const Result kStunUdpToStunUdp;
384 static const Result kPrflxUdpToStunUdp;
385 static const Result kLocalUdpToRelayUdp;
386 static const Result kPrflxUdpToRelayUdp;
387 static const Result kLocalTcpToLocalTcp;
388 static const Result kLocalTcpToPrflxTcp;
389 static const Result kPrflxTcpToLocalTcp;
390
391 rtc::NATSocketServer* nat() { return nss_.get(); }
392 rtc::FirewallSocketServer* fw() { return ss_.get(); }
393
394 Endpoint* GetEndpoint(int endpoint) {
395 if (endpoint == 0) {
396 return &ep1_;
397 } else if (endpoint == 1) {
398 return &ep2_;
399 } else {
400 return NULL;
401 }
402 }
deadbeef14f97f52016-06-22 17:14:15 -0700403 PortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000404 return GetEndpoint(endpoint)->allocator_.get();
405 }
406 void AddAddress(int endpoint, const SocketAddress& addr) {
407 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
408 }
honghaize1a0c942016-02-16 14:54:56 -0800409 void AddAddress(int endpoint,
410 const SocketAddress& addr,
411 const std::string& ifname,
412 rtc::AdapterType adapter_type) {
413 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
414 adapter_type);
415 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000416 void RemoveAddress(int endpoint, const SocketAddress& addr) {
417 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700418 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000419 }
420 void SetProxy(int endpoint, rtc::ProxyType type) {
421 rtc::ProxyInfo info;
422 info.type = type;
423 info.address = (type == rtc::PROXY_HTTPS) ?
424 kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
425 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
426 }
427 void SetAllocatorFlags(int endpoint, int flags) {
428 GetAllocator(endpoint)->set_flags(flags);
429 }
deadbeef14f97f52016-06-22 17:14:15 -0700430 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000431 GetEndpoint(endpoint)->SetIceRole(role);
432 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200433 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000434 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
435 }
436 bool GetRoleConflict(int endpoint) {
437 return GetEndpoint(endpoint)->role_conflict();
438 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200439 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000440 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
441 }
442 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
443 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
444 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700445 bool IsLocalToPrflxOrTheReverse(const Result& expected) {
deadbeefcbecd352015-09-23 11:50:27 -0700446 return (
447 (expected.local_type == "local" && expected.remote_type == "prflx") ||
448 (expected.local_type == "prflx" && expected.remote_type == "local"));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700449 }
450
451 // Return true if the approprite parts of the expected Result, based
452 // on the local and remote candidate of ep1_ch1, match. This can be
453 // used in an EXPECT_TRUE_WAIT.
454 bool CheckCandidate1(const Result& expected) {
455 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
456 const std::string& local_proto = LocalCandidate(ep1_ch1())->protocol();
457 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
458 const std::string& remote_proto = RemoteCandidate(ep1_ch1())->protocol();
459 return ((local_proto == expected.local_proto &&
460 remote_proto == expected.remote_proto) &&
461 ((local_type == expected.local_type &&
462 remote_type == expected.remote_type) ||
463 // Sometimes we expect local -> prflx or prflx -> local
464 // and instead get prflx -> local or local -> prflx, and
465 // that's OK.
466 (IsLocalToPrflxOrTheReverse(expected) &&
467 local_type == expected.remote_type &&
468 remote_type == expected.local_type)));
469 }
470
471 // EXPECT_EQ on the approprite parts of the expected Result, based
472 // on the local and remote candidate of ep1_ch1. This is like
473 // CheckCandidate1, except that it will provide more detail about
474 // what didn't match.
475 void ExpectCandidate1(const Result& expected) {
476 if (CheckCandidate1(expected)) {
477 return;
478 }
479
480 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
481 const std::string& local_proto = LocalCandidate(ep1_ch1())->protocol();
482 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
483 const std::string& remote_proto = RemoteCandidate(ep1_ch1())->protocol();
484 EXPECT_EQ(expected.local_type, local_type);
485 EXPECT_EQ(expected.remote_type, remote_type);
486 EXPECT_EQ(expected.local_proto, local_proto);
487 EXPECT_EQ(expected.remote_proto, remote_proto);
488 }
489
490 // Return true if the approprite parts of the expected Result, based
491 // on the local and remote candidate of ep2_ch1, match. This can be
492 // used in an EXPECT_TRUE_WAIT.
493 bool CheckCandidate2(const Result& expected) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700494 const std::string& local_proto = LocalCandidate(ep2_ch1())->protocol();
495 const std::string& remote_proto = RemoteCandidate(ep2_ch1())->protocol();
Honghai Zhang572b0942016-06-23 12:26:57 -0700496 // Removed remote_type comparision aginst selected connection remote
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700497 // candidate. This is done to handle remote type discrepancy from
498 // local to stun based on the test type.
499 // For example in case of Open -> NAT, ep2 channels will have LULU
500 // and in other cases like NAT -> NAT it will be LUSU. To avoid these
501 // mismatches and we are doing comparision in different way.
502 // i.e. when don't match its remote type is either local or stun.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700503 //
504 // Update(deadbeef): Also had to remove local type comparison. There
505 // is currently an issue where the local type is not updated to stun.
506 // So one side may see local<->relay while the other sees relay<->stun.
507 // This mean the other side may prioritize prflx<->relay, and won't have
508 // a local type of relay no matter how long we wait.
509 // TODO(deadbeef): Fix this!! It's causing us to have very sparse test
510 // coverage and is a very real bug.
511 //
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700512 // TODO(ronghuawu): Refine the test criteria.
513 // https://code.google.com/p/webrtc/issues/detail?id=1953
514 return ((local_proto == expected.local_proto2 &&
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700515 remote_proto == expected.remote_proto2));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700516 }
517
518 // EXPECT_EQ on the approprite parts of the expected Result, based
519 // on the local and remote candidate of ep2_ch1. This is like
520 // CheckCandidate2, except that it will provide more detail about
521 // what didn't match.
522 void ExpectCandidate2(const Result& expected) {
523 if (CheckCandidate2(expected)) {
524 return;
525 }
526
527 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
528 const std::string& local_proto = LocalCandidate(ep2_ch1())->protocol();
529 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700530 const std::string& remote_proto = RemoteCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700531 EXPECT_EQ(expected.local_type2, local_type);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700532 EXPECT_EQ(expected.remote_type2, remote_type);
533 EXPECT_EQ(expected.local_proto2, local_proto);
534 EXPECT_EQ(expected.remote_proto2, remote_proto);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700535 }
536
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000537 void Test(const Result& expected) {
nisse1bffc1d2016-05-02 08:18:55 -0700538 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700539 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000540
541 // Create the channels and wait for them to connect.
542 CreateChannels(1);
543 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL &&
544 ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700545 ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000546 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700547 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000548 ep2_ch1()->writable(),
549 expected.connect_wait,
550 1000);
nisse1bffc1d2016-05-02 08:18:55 -0700551 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000552 if (connect_time < expected.connect_wait) {
553 LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
554 } else {
555 LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
556 << expected.connect_wait << " ms)";
557 }
558
Honghai Zhang572b0942016-06-23 12:26:57 -0700559 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000560 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700561 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700562 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700563 int64_t converge_time;
564 int64_t converge_wait = 2000;
Honghai Zhang572b0942016-06-23 12:26:57 -0700565 // Verifying local and remote channel selected connection information.
566 // This is done only for the RFC 5245 as controlled agent will use
567 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
568 // EP1 result matrix.
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700569 EXPECT_TRUE_WAIT_MARGIN(
570 CheckCandidate1(expected) && CheckCandidate2(expected), converge_wait,
571 converge_wait);
572 // Also do EXPECT_EQ on each part so that failures are more verbose.
573 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700574 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000575
nisse1bffc1d2016-05-02 08:18:55 -0700576 converge_time = rtc::TimeMillis() - converge_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000577 if (converge_time < converge_wait) {
578 LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
579 } else {
580 LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
581 << converge_wait << " ms)";
582 }
583 }
584 // Try sending some data to other end.
585 TestSendRecv(1);
586
587 // Destroy the channels, and wait for them to be fully cleaned up.
588 DestroyChannels();
589 }
590
591 void TestSendRecv(int channels) {
592 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700593 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000594 int len = static_cast<int>(strlen(data));
595 // local_channel1 <==> remote_channel1
596 EXPECT_EQ_WAIT(len, SendData(ep1_ch1(), data, len), 1000);
597 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch1(), data, len), 1000);
598 EXPECT_EQ_WAIT(len, SendData(ep2_ch1(), data, len), 1000);
599 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch1(), data, len), 1000);
600 if (channels == 2 && ep1_ch2() && ep2_ch2()) {
601 // local_channel2 <==> remote_channel2
602 EXPECT_EQ_WAIT(len, SendData(ep1_ch2(), data, len), 1000);
603 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch2(), data, len), 1000);
604 EXPECT_EQ_WAIT(len, SendData(ep2_ch2(), data, len), 1000);
605 EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch2(), data, len), 1000);
606 }
607 }
608 }
609
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700610 // This test waits for the transport to become receiving and writable on both
deadbeefcbecd352015-09-23 11:50:27 -0700611 // end points. Once they are, the end points set new local ice credentials and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000612 // restart the ice gathering. Finally it waits for the transport to select a
613 // new connection using the newly generated ice candidates.
614 // Before calling this function the end points must be configured.
615 void TestHandleIceUfragPasswordChanged() {
616 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
617 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700618 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
619 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000620 1000, 1000);
621
deadbeef14f97f52016-06-22 17:14:15 -0700622 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
623 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
624 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
625 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000626
627 ep1_ch1()->SetIceCredentials(kIceUfrag[2], kIcePwd[2]);
628 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700629 ep1_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000630 ep2_ch1()->SetIceCredentials(kIceUfrag[3], kIcePwd[3]);
631 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700632 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000633
634 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep1_ch1())->generation() !=
635 old_local_candidate1->generation(),
636 1000, 1000);
637 EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep2_ch1())->generation() !=
638 old_local_candidate2->generation(),
639 1000, 1000);
640 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep1_ch1())->generation() !=
641 old_remote_candidate1->generation(),
642 1000, 1000);
643 EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep2_ch1())->generation() !=
644 old_remote_candidate2->generation(),
645 1000, 1000);
646 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
647 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
648 }
649
650 void TestSignalRoleConflict() {
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700651 SetIceTiebreaker(0,
652 kLowTiebreaker); // Default EP1 is in controlling state.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000653
deadbeef14f97f52016-06-22 17:14:15 -0700654 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700655 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000656
657 // Creating channels with both channels role set to CONTROLLING.
658 CreateChannels(1);
659 // Since both the channels initiated with controlling state and channel2
660 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
661 EXPECT_TRUE_WAIT(GetRoleConflict(0), 1000);
662 EXPECT_FALSE(GetRoleConflict(1));
663
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700664 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000665 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700666 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000667 ep2_ch1()->writable(),
668 1000);
669
Honghai Zhang572b0942016-06-23 12:26:57 -0700670 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
671 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000672
673 TestSendRecv(1);
674 }
675
deadbeef14f97f52016-06-22 17:14:15 -0700676 void OnReadyToSend(TransportChannel* ch) {
677 GetEndpoint(ch)->ready_to_send_ = true;
678 }
679
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000680 // We pass the candidates directly to the other side.
deadbeef14f97f52016-06-22 17:14:15 -0700681 void OnCandidateGathered(TransportChannelImpl* ch, const Candidate& c) {
682 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000683 return;
684
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000685 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700686 GetEndpoint(ch)->saved_candidates_.push_back(
687 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000688 } else {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700689 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
690 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000691 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000692 }
honghaiz9ad0db52016-07-14 19:30:28 -0700693 void OnSelectedCandidatePairChanged(
694 TransportChannel* transport_channel,
695 CandidatePairInterface* selected_candidate_pair,
696 int last_sent_packet_id,
697 bool ready_to_send) {
698 ++selected_candidate_pair_switches_;
699 }
700
701 int reset_selected_candidate_pair_switches() {
702 int switches = selected_candidate_pair_switches_;
703 selected_candidate_pair_switches_ = 0;
704 return switches;
705 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000706
707 void PauseCandidates(int endpoint) {
708 GetEndpoint(endpoint)->save_candidates_ = true;
709 }
710
deadbeef14f97f52016-06-22 17:14:15 -0700711 void OnCandidatesRemoved(TransportChannelImpl* ch,
712 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700713 // Candidate removals are not paused.
714 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700715 main_->Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700716 }
717
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800718 // Tcp candidate verification has to be done when they are generated.
719 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
720 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700721 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700722 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700723 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700724 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
725 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
726 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
727 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700728 } else {
729 FAIL() << "Unknown tcptype: " << candidate.tcptype();
730 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800731 }
732 }
733 }
734
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000735 void ResumeCandidates(int endpoint) {
736 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700737 for (auto& candidate : ed->saved_candidates_) {
738 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000739 }
740 ed->saved_candidates_.clear();
741 ed->save_candidates_ = false;
742 }
743
744 void OnMessage(rtc::Message* msg) {
745 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700746 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700747 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700748 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700749 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
750 if (!rch) {
751 return;
752 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700753 for (auto& c : data->candidates) {
deadbeef0af180b2016-06-21 13:15:32 -0700754 if (remote_ice_credential_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700755 c.set_username("");
756 c.set_password("");
757 }
758 LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
759 << rch->component() << "): " << c.ToString();
760 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000761 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700762 break;
763 }
764 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700765 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700766 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700767 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
768 if (!rch) {
769 return;
770 }
771 for (Candidate& c : data->candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700772 LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
773 rch->RemoveRemoteCandidate(c);
774 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000775 break;
776 }
777 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000778 }
deadbeef14f97f52016-06-22 17:14:15 -0700779 void OnReadPacket(TransportChannel* channel,
780 const char* data,
781 size_t len,
782 const rtc::PacketTime& packet_time,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000783 int flags) {
784 std::list<std::string>& packets = GetPacketList(channel);
785 packets.push_front(std::string(data, len));
786 }
deadbeef14f97f52016-06-22 17:14:15 -0700787 void OnRoleConflict(TransportChannelImpl* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000788 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700789 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
790 ? ICEROLE_CONTROLLED
791 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000792 channel->SetIceRole(new_role);
793 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700794
deadbeef14f97f52016-06-22 17:14:15 -0700795 int SendData(TransportChannel* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000796 rtc::PacketOptions options;
797 return channel->SendPacket(data, len, options, 0);
798 }
deadbeef14f97f52016-06-22 17:14:15 -0700799 bool CheckDataOnChannel(TransportChannel* channel,
800 const char* data,
801 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000802 return GetChannelData(channel)->CheckData(data, len);
803 }
deadbeef14f97f52016-06-22 17:14:15 -0700804 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700805 return (ch && ch->selected_connection())
806 ? &ch->selected_connection()->local_candidate()
807 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000808 }
deadbeef14f97f52016-06-22 17:14:15 -0700809 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700810 return (ch && ch->selected_connection())
811 ? &ch->selected_connection()->remote_candidate()
812 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000813 }
deadbeef14f97f52016-06-22 17:14:15 -0700814 Endpoint* GetEndpoint(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000815 if (ep1_.HasChannel(ch)) {
816 return &ep1_;
817 } else if (ep2_.HasChannel(ch)) {
818 return &ep2_;
819 } else {
820 return NULL;
821 }
822 }
deadbeef14f97f52016-06-22 17:14:15 -0700823 P2PTransportChannel* GetRemoteChannel(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000824 if (ch == ep1_ch1())
825 return ep2_ch1();
826 else if (ch == ep1_ch2())
827 return ep2_ch2();
828 else if (ch == ep2_ch1())
829 return ep1_ch1();
830 else if (ch == ep2_ch2())
831 return ep1_ch2();
832 else
833 return NULL;
834 }
deadbeef14f97f52016-06-22 17:14:15 -0700835 std::list<std::string>& GetPacketList(TransportChannel* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000836 return GetChannelData(ch)->ch_packets_;
837 }
838
deadbeef0af180b2016-06-21 13:15:32 -0700839 enum RemoteIceCredentialSource { FROM_CANDIDATE, FROM_SETICECREDENTIALS };
840
841 // How does the test pass ICE credentials to the P2PTransportChannel?
842 // On the candidate itself, or through SetIceCredentials?
843 // Goes through the candidate itself by default.
844 void set_remote_ice_credential_source(RemoteIceCredentialSource source) {
845 remote_ice_credential_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000846 }
847
848 void set_force_relay(bool relay) {
849 force_relay_ = relay;
850 }
851
852 private:
853 rtc::Thread* main_;
kwiberg3ec46792016-04-27 07:22:53 -0700854 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
855 std::unique_ptr<rtc::VirtualSocketServer> vss_;
856 std::unique_ptr<rtc::NATSocketServer> nss_;
857 std::unique_ptr<rtc::FirewallSocketServer> ss_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000858 rtc::SocketServerScope ss_scope_;
deadbeef14f97f52016-06-22 17:14:15 -0700859 std::unique_ptr<TestStunServer> stun_server_;
860 TestTurnServer turn_server_;
861 TestRelayServer relay_server_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000862 rtc::SocksProxyServer socks_server1_;
863 rtc::SocksProxyServer socks_server2_;
864 Endpoint ep1_;
865 Endpoint ep2_;
deadbeef0af180b2016-06-21 13:15:32 -0700866 RemoteIceCredentialSource remote_ice_credential_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000867 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700868 int selected_candidate_pair_switches_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000869};
870
871// The tests have only a few outcomes, which we predefine.
872const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
873 kLocalUdpToLocalUdp("local", "udp", "local", "udp",
874 "local", "udp", "local", "udp", 1000);
875const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
876 kLocalUdpToStunUdp("local", "udp", "stun", "udp",
877 "local", "udp", "stun", "udp", 1000);
878const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
879 kLocalUdpToPrflxUdp("local", "udp", "prflx", "udp",
880 "prflx", "udp", "local", "udp", 1000);
881const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
882 kPrflxUdpToLocalUdp("prflx", "udp", "local", "udp",
883 "local", "udp", "prflx", "udp", 1000);
884const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
885 kStunUdpToLocalUdp("stun", "udp", "local", "udp",
886 "local", "udp", "stun", "udp", 1000);
887const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
888 kStunUdpToStunUdp("stun", "udp", "stun", "udp",
889 "stun", "udp", "stun", "udp", 1000);
890const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
891 kPrflxUdpToStunUdp("prflx", "udp", "stun", "udp",
892 "local", "udp", "prflx", "udp", 1000);
893const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
894 kLocalUdpToRelayUdp("local", "udp", "relay", "udp",
895 "relay", "udp", "local", "udp", 2000);
896const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
897 kPrflxUdpToRelayUdp("prflx", "udp", "relay", "udp",
898 "relay", "udp", "prflx", "udp", 2000);
899const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
900 kLocalTcpToLocalTcp("local", "tcp", "local", "tcp",
901 "local", "tcp", "local", "tcp", 3000);
902const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
903 kLocalTcpToPrflxTcp("local", "tcp", "prflx", "tcp",
904 "prflx", "tcp", "local", "tcp", 3000);
905const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
906 kPrflxTcpToLocalTcp("prflx", "tcp", "local", "tcp",
907 "local", "tcp", "prflx", "tcp", 3000);
908
909// Test the matrix of all the connectivity types we expect to see in the wild.
910// Just test every combination of the configs in the Config enum.
911class P2PTransportChannelTest : public P2PTransportChannelTestBase {
912 protected:
913 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -0700914 void ConfigureEndpoints(Config config1,
915 Config config2,
916 int allocator_flags1,
917 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000918 ServerAddresses stun_servers;
919 stun_servers.insert(kStunAddr);
deadbeef14f97f52016-06-22 17:14:15 -0700920 GetEndpoint(0)->allocator_.reset(new BasicPortAllocator(
921 &(GetEndpoint(0)->network_manager_), stun_servers, rtc::SocketAddress(),
922 rtc::SocketAddress(), rtc::SocketAddress()));
923 GetEndpoint(1)->allocator_.reset(new BasicPortAllocator(
924 &(GetEndpoint(1)->network_manager_), stun_servers, rtc::SocketAddress(),
925 rtc::SocketAddress(), rtc::SocketAddress()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000926
deadbeef14f97f52016-06-22 17:14:15 -0700927 RelayServerConfig turn_server(RELAY_TURN);
deadbeef653b8e02015-11-11 12:55:10 -0800928 turn_server.credentials = kRelayCredentials;
929 turn_server.ports.push_back(
deadbeef14f97f52016-06-22 17:14:15 -0700930 ProtocolAddress(kTurnUdpIntAddr, PROTO_UDP, false));
deadbeef653b8e02015-11-11 12:55:10 -0800931 GetEndpoint(0)->allocator_->AddTurnServer(turn_server);
932 GetEndpoint(1)->allocator_->AddTurnServer(turn_server);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000933
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700934 int delay = kMinimumStepDelay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000935 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000936 SetAllocatorFlags(0, allocator_flags1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700937 SetAllocationStepDelay(0, delay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000938 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000939 SetAllocatorFlags(1, allocator_flags2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700940 SetAllocationStepDelay(1, delay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000941
deadbeef0af180b2016-06-21 13:15:32 -0700942 set_remote_ice_credential_source(FROM_SETICECREDENTIALS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000943 }
944 void ConfigureEndpoint(int endpoint, Config config) {
945 switch (config) {
946 case OPEN:
947 AddAddress(endpoint, kPublicAddrs[endpoint]);
948 break;
949 case NAT_FULL_CONE:
950 case NAT_ADDR_RESTRICTED:
951 case NAT_PORT_RESTRICTED:
952 case NAT_SYMMETRIC:
953 AddAddress(endpoint, kPrivateAddrs[endpoint]);
954 // Add a single NAT of the desired type
955 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
956 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
957 AddClient(kPrivateAddrs[endpoint]);
958 break;
959 case NAT_DOUBLE_CONE:
960 case NAT_SYMMETRIC_THEN_CONE:
961 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
962 // Add a two cascaded NATs of the desired types
963 nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
964 (config == NAT_DOUBLE_CONE) ?
965 rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
966 AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
967 rtc::NAT_OPEN_CONE)->
968 AddClient(kCascadedPrivateAddrs[endpoint]);
969 break;
970 case BLOCK_UDP:
971 case BLOCK_UDP_AND_INCOMING_TCP:
972 case BLOCK_ALL_BUT_OUTGOING_HTTP:
973 case PROXY_HTTPS:
974 case PROXY_SOCKS:
975 AddAddress(endpoint, kPublicAddrs[endpoint]);
976 // Block all UDP
977 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
978 kPublicAddrs[endpoint]);
979 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
980 // Block TCP inbound to the endpoint
981 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
982 kPublicAddrs[endpoint]);
983 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
984 // Block all TCP to/from the endpoint except 80/443 out
985 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
986 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
987 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
988 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
989 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
990 kPublicAddrs[endpoint]);
991 } else if (config == PROXY_HTTPS) {
992 // Block all TCP to/from the endpoint except to the proxy server
993 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
994 kHttpsProxyAddrs[endpoint]);
995 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
996 kPublicAddrs[endpoint]);
997 SetProxy(endpoint, rtc::PROXY_HTTPS);
998 } else if (config == PROXY_SOCKS) {
999 // Block all TCP to/from the endpoint except to the proxy server
1000 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1001 kSocksProxyAddrs[endpoint]);
1002 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1003 kPublicAddrs[endpoint]);
1004 SetProxy(endpoint, rtc::PROXY_SOCKS5);
1005 }
1006 break;
1007 default:
1008 break;
1009 }
1010 }
1011};
1012
1013// Shorthands for use in the test matrix.
1014#define LULU &kLocalUdpToLocalUdp
1015#define LUSU &kLocalUdpToStunUdp
1016#define LUPU &kLocalUdpToPrflxUdp
1017#define PULU &kPrflxUdpToLocalUdp
1018#define SULU &kStunUdpToLocalUdp
1019#define SUSU &kStunUdpToStunUdp
1020#define PUSU &kPrflxUdpToStunUdp
1021#define LURU &kLocalUdpToRelayUdp
1022#define PURU &kPrflxUdpToRelayUdp
1023#define LTLT &kLocalTcpToLocalTcp
1024#define LTPT &kLocalTcpToPrflxTcp
1025#define PTLT &kPrflxTcpToLocalTcp
1026// TODO: Enable these once TestRelayServer can accept external TCP.
1027#define LTRT NULL
1028#define LSRS NULL
1029
1030// Test matrix. Originator behavior defined by rows, receiever by columns.
1031
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001032// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
1033// TODO: Fix NULLs caused by no HTTP proxy support.
1034// TODO: Rearrange rows/columns from best to worst.
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001035const P2PTransportChannelTest::Result* P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
1036 // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
1037 /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, PTLT, LTPT, LSRS, NULL, LTPT},
1038 /*CO*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1039 /*AD*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1040 /*PO*/ {LULU, LUSU, LUSU, LUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
1041 /*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1042 /*2C*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
1043 /*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
1044 /*!U*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTPT, LSRS, NULL, LTRT},
1045 /*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
1046 /*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
1047 /*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1048 /*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001049};
1050
1051// The actual tests that exercise all the various configurations.
1052// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001053#define P2P_TEST_DECLARATION(x, y, z) \
1054 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1055 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1056 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001057 if (kMatrix[x][y] != NULL) \
1058 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001059 else \
1060 LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001061 }
1062
1063#define P2P_TEST(x, y) \
1064 P2P_TEST_DECLARATION(x, y,)
1065
1066#define FLAKY_P2P_TEST(x, y) \
1067 P2P_TEST_DECLARATION(x, y, DISABLED_)
1068
1069// TODO(holmer): Disabled due to randomly failing on webrtc buildbots.
1070// Issue: webrtc/2383
1071#define P2P_TEST_SET(x) \
1072 P2P_TEST(x, OPEN) \
1073 FLAKY_P2P_TEST(x, NAT_FULL_CONE) \
1074 FLAKY_P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1075 FLAKY_P2P_TEST(x, NAT_PORT_RESTRICTED) \
1076 P2P_TEST(x, NAT_SYMMETRIC) \
1077 FLAKY_P2P_TEST(x, NAT_DOUBLE_CONE) \
1078 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1079 P2P_TEST(x, BLOCK_UDP) \
1080 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1081 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1082 P2P_TEST(x, PROXY_HTTPS) \
1083 P2P_TEST(x, PROXY_SOCKS)
1084
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001085P2P_TEST_SET(OPEN)
1086P2P_TEST_SET(NAT_FULL_CONE)
1087P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1088P2P_TEST_SET(NAT_PORT_RESTRICTED)
1089P2P_TEST_SET(NAT_SYMMETRIC)
1090P2P_TEST_SET(NAT_DOUBLE_CONE)
1091P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1092P2P_TEST_SET(BLOCK_UDP)
1093P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
1094P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1095P2P_TEST_SET(PROXY_HTTPS)
1096P2P_TEST_SET(PROXY_SOCKS)
1097
1098// Test that we restart candidate allocation when local ufrag&pwd changed.
1099// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001100TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001101 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001102 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001103 CreateChannels(1);
1104 TestHandleIceUfragPasswordChanged();
1105 DestroyChannels();
1106}
1107
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001108// Same as above test, but with a symmetric NAT.
1109// We should end up with relay<->prflx candidate pairs, with generation "1".
1110TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1111 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1112 kDefaultPortAllocatorFlags);
1113 CreateChannels(1);
1114 TestHandleIceUfragPasswordChanged();
1115 DestroyChannels();
1116}
1117
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001118// Test the operation of GetStats.
1119TEST_F(P2PTransportChannelTest, GetStats) {
deadbeefcbecd352015-09-23 11:50:27 -07001120 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001121 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001122 CreateChannels(1);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001123 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1124 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001125 1000, 1000);
1126 TestSendRecv(1);
deadbeef14f97f52016-06-22 17:14:15 -07001127 ConnectionInfos infos;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001128 ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001129 ASSERT_TRUE(infos.size() >= 1);
deadbeef14f97f52016-06-22 17:14:15 -07001130 ConnectionInfo* best_conn_info = nullptr;
1131 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001132 if (info.best_connection) {
1133 best_conn_info = &info;
1134 break;
1135 }
1136 }
1137 ASSERT_TRUE(best_conn_info != nullptr);
1138 EXPECT_TRUE(best_conn_info->new_connection);
1139 EXPECT_TRUE(best_conn_info->receiving);
1140 EXPECT_TRUE(best_conn_info->writable);
1141 EXPECT_FALSE(best_conn_info->timeout);
1142 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1143 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1144 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1145 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
1146 EXPECT_GT(best_conn_info->rtt, 0U);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001147 DestroyChannels();
1148}
1149
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001150// Test that we properly create a connection on a STUN ping from unknown address
1151// when the signaling is slow.
1152TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001153 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001154 kDefaultPortAllocatorFlags);
Peter Thatcher7351f462015-04-02 16:39:16 -07001155 // Emulate no remote credentials coming in.
deadbeef0af180b2016-06-21 13:15:32 -07001156 set_remote_ice_credential_source(FROM_CANDIDATE);
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +00001157 CreateChannels(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001158 // Only have remote credentials come in for ep2, not ep1.
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001159 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001160
1161 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1162 // candidate.
1163 PauseCandidates(1);
1164
Honghai Zhang572b0942016-06-23 12:26:57 -07001165 // The caller should have the selected connection connected to the peer
1166 // reflexive candidate.
1167 const Connection* selected_connection = NULL;
1168 WAIT((selected_connection = ep1_ch1()->selected_connection()) != NULL, 2000);
1169 EXPECT_EQ("prflx",
1170 ep1_ch1()->selected_connection()->remote_candidate().type());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001171
Peter Thatcher7351f462015-04-02 16:39:16 -07001172 // Because we don't have a remote pwd, we don't ping yet.
1173 EXPECT_EQ(kIceUfrag[1],
Honghai Zhang572b0942016-06-23 12:26:57 -07001174 ep1_ch1()->selected_connection()->remote_candidate().username());
1175 EXPECT_EQ("",
1176 ep1_ch1()->selected_connection()->remote_candidate().password());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001177 // Because we don't have ICE credentials yet, we don't know the generation.
Honghai Zhang572b0942016-06-23 12:26:57 -07001178 EXPECT_EQ(0u,
1179 ep1_ch1()->selected_connection()->remote_candidate().generation());
Peter Thatcher7351f462015-04-02 16:39:16 -07001180 EXPECT_TRUE(nullptr == ep1_ch1()->FindNextPingableConnection());
1181
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001182 // Add two sets of remote ICE credentials, so that the ones used by the
1183 // candidate will be generation 1 instead of 0.
1184 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001185 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001186 // After setting the remote ICE credentials, the password and generation
1187 // of the peer reflexive candidate should be updated.
Peter Thatcher7351f462015-04-02 16:39:16 -07001188 EXPECT_EQ(kIcePwd[1],
Honghai Zhang572b0942016-06-23 12:26:57 -07001189 ep1_ch1()->selected_connection()->remote_candidate().password());
1190 EXPECT_EQ(1u,
1191 ep1_ch1()->selected_connection()->remote_candidate().generation());
Peter Thatcher7351f462015-04-02 16:39:16 -07001192 EXPECT_TRUE(nullptr != ep1_ch1()->FindNextPingableConnection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001193
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001194 ResumeCandidates(1);
1195
Honghai Zhang572b0942016-06-23 12:26:57 -07001196 WAIT(ep2_ch1()->selected_connection() != NULL, 2000);
1197 // Verify ep1's selected connection is updated to use the 'local' candidate.
1198 EXPECT_EQ_WAIT("local",
1199 ep1_ch1()->selected_connection()->remote_candidate().type(),
1200 2000);
1201 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001202 DestroyChannels();
1203}
1204
1205// Test that we properly create a connection on a STUN ping from unknown address
1206// when the signaling is slow and the end points are behind NAT.
1207TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001208 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001209 kDefaultPortAllocatorFlags);
Peter Thatcher7351f462015-04-02 16:39:16 -07001210 // Emulate no remote credentials coming in.
deadbeef0af180b2016-06-21 13:15:32 -07001211 set_remote_ice_credential_source(FROM_CANDIDATE);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001212 CreateChannels(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001213 // Only have remote credentials come in for ep2, not ep1.
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001214 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001215 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1216 // candidate.
1217 PauseCandidates(1);
1218
Honghai Zhang572b0942016-06-23 12:26:57 -07001219 // The caller should have the selected connection connected to the peer
1220 // reflexive candidate.
1221 WAIT(ep1_ch1()->selected_connection() != NULL, 2000);
1222 EXPECT_EQ("prflx",
1223 ep1_ch1()->selected_connection()->remote_candidate().type());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001224
Peter Thatcher7351f462015-04-02 16:39:16 -07001225 // Because we don't have a remote pwd, we don't ping yet.
1226 EXPECT_EQ(kIceUfrag[1],
Honghai Zhang572b0942016-06-23 12:26:57 -07001227 ep1_ch1()->selected_connection()->remote_candidate().username());
1228 EXPECT_EQ("",
1229 ep1_ch1()->selected_connection()->remote_candidate().password());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001230 // Because we don't have ICE credentials yet, we don't know the generation.
Honghai Zhang572b0942016-06-23 12:26:57 -07001231 EXPECT_EQ(0u,
1232 ep1_ch1()->selected_connection()->remote_candidate().generation());
Peter Thatcher7351f462015-04-02 16:39:16 -07001233 EXPECT_TRUE(nullptr == ep1_ch1()->FindNextPingableConnection());
1234
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001235 // Add two sets of remote ICE credentials, so that the ones used by the
1236 // candidate will be generation 1 instead of 0.
1237 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001238 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001239 // After setting the remote ICE credentials, the password and generation
1240 // of the peer reflexive candidate should be updated.
Peter Thatcher7351f462015-04-02 16:39:16 -07001241 EXPECT_EQ(kIcePwd[1],
Honghai Zhang572b0942016-06-23 12:26:57 -07001242 ep1_ch1()->selected_connection()->remote_candidate().password());
1243 EXPECT_EQ(1u,
1244 ep1_ch1()->selected_connection()->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001245
1246 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001247
Honghai Zhang572b0942016-06-23 12:26:57 -07001248 const Connection* selected_connection = NULL;
1249 WAIT((selected_connection = ep2_ch1()->selected_connection()) != NULL, 2000);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001250
1251 // Wait to verify the connection is not culled.
1252 WAIT(ep1_ch1()->writable(), 2000);
Honghai Zhang572b0942016-06-23 12:26:57 -07001253 EXPECT_EQ(ep2_ch1()->selected_connection(), selected_connection);
1254 EXPECT_EQ("prflx",
1255 ep1_ch1()->selected_connection()->remote_candidate().type());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001256 DestroyChannels();
1257}
1258
deadbeef0af180b2016-06-21 13:15:32 -07001259// Test that we properly create a connection on a STUN ping from unknown address
1260// when the signaling is slow, even if the new candidate is created due to the
1261// remote peer doing an ICE restart, pairing this candidate across generations.
1262//
1263// Previously this wasn't working due to a bug where the peer reflexive
1264// candidate was only updated for the newest generation candidate pairs, and
1265// not older-generation candidate pairs created by pairing candidates across
1266// generations. This resulted in the old-generation prflx candidate being
1267// prioritized above new-generation candidate pairs.
1268TEST_F(P2PTransportChannelTest,
1269 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1270 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1271 kDefaultPortAllocatorFlags);
1272 // Only gather relay candidates, so that when the prflx candidate arrives
1273 // it's prioritized above the current candidate pair.
deadbeef14f97f52016-06-22 17:14:15 -07001274 GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
1275 GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
deadbeef0af180b2016-06-21 13:15:32 -07001276 // Setting this allows us to control when SetRemoteIceCredentials is called.
1277 set_remote_ice_credential_source(FROM_CANDIDATE);
1278 CreateChannels(1);
1279 // Wait for the initial connection to be made.
1280 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
1281 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
1282 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1283 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1284 kDefaultTimeout);
1285
1286 // Simulate an ICE restart on ep2, but don't signal the candidate or new
1287 // ICE credentials until after a prflx connection has been made.
1288 PauseCandidates(1);
1289 ep2_ch1()->SetIceCredentials(kIceUfrag[3], kIcePwd[3]);
1290 ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
1291 ep2_ch1()->MaybeStartGathering();
1292
Honghai Zhang572b0942016-06-23 12:26:57 -07001293 // The caller should have the selected connection connected to the peer
1294 // reflexive candidate.
deadbeef0af180b2016-06-21 13:15:32 -07001295 EXPECT_EQ_WAIT("prflx",
Honghai Zhang572b0942016-06-23 12:26:57 -07001296 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001297 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001298 const Connection* prflx_selected_connection =
1299 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001300
1301 // Now simulate the ICE restart on ep1.
1302 ep1_ch1()->SetIceCredentials(kIceUfrag[2], kIcePwd[2]);
1303 ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
1304 ep1_ch1()->MaybeStartGathering();
1305
1306 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1307 // their information to update the peer reflexive candidate.
1308 ResumeCandidates(1);
1309
1310 EXPECT_EQ_WAIT("relay",
Honghai Zhang572b0942016-06-23 12:26:57 -07001311 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001312 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001313 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001314 DestroyChannels();
1315}
1316
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001317// Test that if remote candidates don't have ufrag and pwd, we still work.
1318TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
deadbeef0af180b2016-06-21 13:15:32 -07001319 set_remote_ice_credential_source(FROM_SETICECREDENTIALS);
deadbeefcbecd352015-09-23 11:50:27 -07001320 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001321 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001322 CreateChannels(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001323 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001324 // Wait until the callee's connections are created.
Honghai Zhang572b0942016-06-23 12:26:57 -07001325 WAIT((selected_connection = ep2_ch1()->selected_connection()) != NULL, 1000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001326 // Wait to see if they get culled; they shouldn't.
Honghai Zhang572b0942016-06-23 12:26:57 -07001327 WAIT(ep2_ch1()->selected_connection() != selected_connection, 1000);
1328 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001329 DestroyChannels();
1330}
1331
1332// Test that a host behind NAT cannot be reached when incoming_only
1333// is set to true.
1334TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
deadbeefcbecd352015-09-23 11:50:27 -07001335 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001336 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001337
1338 SetAllocatorFlags(0, kOnlyLocalPorts);
1339 CreateChannels(1);
1340 ep1_ch1()->set_incoming_only(true);
1341
1342 // Pump for 1 second and verify that the channels are not connected.
1343 rtc::Thread::Current()->ProcessMessages(1000);
1344
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001345 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001346 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001347 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001348 EXPECT_FALSE(ep2_ch1()->writable());
1349
1350 DestroyChannels();
1351}
1352
1353// Test that a peer behind NAT can connect to a peer that has
1354// incoming_only flag set.
1355TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
deadbeefcbecd352015-09-23 11:50:27 -07001356 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001357 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001358
1359 SetAllocatorFlags(0, kOnlyLocalPorts);
1360 CreateChannels(1);
1361 ep1_ch1()->set_incoming_only(true);
1362
1363 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001364 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1365 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001366 1000, 1000);
1367
1368 DestroyChannels();
1369}
1370
1371TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
1372 AddAddress(0, kPublicAddrs[0]);
1373 AddAddress(1, kPublicAddrs[1]);
1374
1375 SetAllocationStepDelay(0, kMinimumStepDelay);
1376 SetAllocationStepDelay(1, kMinimumStepDelay);
1377
deadbeef14f97f52016-06-22 17:14:15 -07001378 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1379 PORTALLOCATOR_DISABLE_STUN |
1380 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001381 // Disable all protocols except TCP.
1382 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1383 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1384
1385 SetAllowTcpListen(0, true); // actpass.
1386 SetAllowTcpListen(1, false); // active.
1387
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001388 // We want SetRemoteIceCredentials to be called as it normally would.
1389 // Otherwise we won't know what credentials to use for the expected
1390 // prflx TCP candidates.
1391 set_remote_ice_credential_source(FROM_SETICECREDENTIALS);
1392
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001393 // Pause candidate so we could verify the candidate properties.
1394 PauseCandidates(0);
1395 PauseCandidates(1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001396 CreateChannels(1);
1397
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001398 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001399 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1400 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001401
1402 // Resume candidates.
1403 ResumeCandidates(0);
1404 ResumeCandidates(1);
1405
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001406 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1407 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001408 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07001409 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1410 ep2_ch1()->selected_connection() &&
1411 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1412 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001413
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001414 TestSendRecv(1);
1415 DestroyChannels();
1416}
1417
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001418TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001419 AddAddress(0, kPublicAddrs[0]);
1420 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001421 TestSignalRoleConflict();
1422}
1423
1424// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1425// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001426TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001427 AddAddress(0, kPublicAddrs[0]);
1428 AddAddress(1, kPublicAddrs[1]);
1429
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001430 // Give the first connection the higher tiebreaker so its role won't
1431 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001432 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001433 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001434 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001435 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001436
1437 CreateChannels(1);
1438
1439 EXPECT_EQ_WAIT(2u, ep1_ch1()->ports().size(), 1000);
1440
deadbeef14f97f52016-06-22 17:14:15 -07001441 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001442 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001443 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001444 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001445 }
1446
deadbeef14f97f52016-06-22 17:14:15 -07001447 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001448 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001449
deadbeef14f97f52016-06-22 17:14:15 -07001450 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001451 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001452 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001453 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001454 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001455 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001456 }
1457
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001458 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001459 ep1_ch1()->writable() &&
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001460 ep2_ch1()->receiving() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001461 ep2_ch1()->writable(),
1462 1000);
1463
Honghai Zhang572b0942016-06-23 12:26:57 -07001464 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1465 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001466
1467 TestSendRecv(1);
1468 DestroyChannels();
1469}
1470
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001471// Verify that we can set DSCP value and retrieve properly from P2PTC.
1472TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1473 AddAddress(0, kPublicAddrs[0]);
1474 AddAddress(1, kPublicAddrs[1]);
1475
1476 CreateChannels(1);
1477 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1478 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1479 EXPECT_EQ(rtc::DSCP_NO_CHANGE,
1480 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1481 GetEndpoint(0)->cd1_.ch_->SetOption(
1482 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1483 GetEndpoint(1)->cd1_.ch_->SetOption(
1484 rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1485 EXPECT_EQ(rtc::DSCP_CS6,
1486 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1487 EXPECT_EQ(rtc::DSCP_CS6,
1488 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1489 GetEndpoint(0)->cd1_.ch_->SetOption(
1490 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1491 GetEndpoint(1)->cd1_.ch_->SetOption(
1492 rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1493 EXPECT_EQ(rtc::DSCP_AF41,
1494 GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1495 EXPECT_EQ(rtc::DSCP_AF41,
1496 GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1497}
1498
1499// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001500TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001501 AddAddress(0, kIPv6PublicAddrs[0]);
1502 AddAddress(0, kPublicAddrs[0]);
1503 AddAddress(1, kIPv6PublicAddrs[1]);
1504 AddAddress(1, kPublicAddrs[1]);
1505
1506 SetAllocationStepDelay(0, kMinimumStepDelay);
1507 SetAllocationStepDelay(1, kMinimumStepDelay);
1508
1509 // Enable IPv6
deadbeef14f97f52016-06-22 17:14:15 -07001510 SetAllocatorFlags(0, PORTALLOCATOR_ENABLE_IPV6);
1511 SetAllocatorFlags(1, PORTALLOCATOR_ENABLE_IPV6);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001512
1513 CreateChannels(1);
1514
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001515 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1516 ep2_ch1()->receiving() && ep2_ch1()->writable(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001517 1000);
1518 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001519 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001520 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1521 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1522
1523 TestSendRecv(1);
1524 DestroyChannels();
1525}
1526
1527// Testing forceful TURN connections.
1528TEST_F(P2PTransportChannelTest, TestForceTurn) {
deadbeefcbecd352015-09-23 11:50:27 -07001529 ConfigureEndpoints(
1530 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001531 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1532 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001533 set_force_relay(true);
1534
1535 SetAllocationStepDelay(0, kMinimumStepDelay);
1536 SetAllocationStepDelay(1, kMinimumStepDelay);
1537
1538 CreateChannels(1);
1539
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001540 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1541 ep2_ch1()->receiving() && ep2_ch1()->writable(),
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001542 2000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001543
Honghai Zhang572b0942016-06-23 12:26:57 -07001544 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1545 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001546
1547 EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
1548 EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
1549 EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
1550 EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
1551
1552 TestSendRecv(1);
1553 DestroyChannels();
1554}
1555
honghaiz98db68f2015-09-29 07:58:17 -07001556// Test that if continual gathering is set to true, ICE gathering state will
1557// not change to "Complete", and vice versa.
1558TEST_F(P2PTransportChannelTest, TestContinualGathering) {
1559 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1560 kDefaultPortAllocatorFlags);
1561 SetAllocationStepDelay(0, kDefaultStepDelay);
1562 SetAllocationStepDelay(1, kDefaultStepDelay);
1563 CreateChannels(1);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07001564 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001565 ep1_ch1()->SetIceConfig(config);
1566 // By default, ep2 does not gather continually.
1567
1568 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1569 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1570 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1571 1000, 1000);
deadbeef14f97f52016-06-22 17:14:15 -07001572 WAIT(IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
honghaiz98db68f2015-09-29 07:58:17 -07001573 1000);
deadbeef14f97f52016-06-22 17:14:15 -07001574 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001575 ep1_ch1()->gathering_state());
1576 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001577 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001578 ep2_ch1()->gathering_state());
1579
1580 DestroyChannels();
1581}
1582
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001583// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1584// PortAllocatorSession that has not yet finished gathering candidates.
1585TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
1586 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1587 kDefaultPortAllocatorFlags);
1588 // First create a pooled session for each endpoint.
1589 auto& allocator_1 = GetEndpoint(0)->allocator_;
1590 auto& allocator_2 = GetEndpoint(1)->allocator_;
1591 int pool_size = 1;
1592 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001593 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001594 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001595 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001596 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001597 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001598 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001599 allocator_2->GetPooledSession();
1600 ASSERT_NE(nullptr, pooled_session_1);
1601 ASSERT_NE(nullptr, pooled_session_2);
1602 // Sanity check that pooled sessions haven't gathered anything yet.
1603 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1604 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1605 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1606 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1607 // Now let the endpoints connect and try exchanging some data.
1608 CreateChannels(1);
1609 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1610 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1611 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1612 1000, 1000);
1613 TestSendRecv(1);
1614 // Make sure the P2PTransportChannels are actually using ports from the
1615 // pooled sessions.
1616 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1617 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1618 EXPECT_NE(pooled_ports_1.end(),
1619 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001620 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001621 EXPECT_NE(pooled_ports_2.end(),
1622 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001623 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001624}
1625
1626// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1627// PortAllocatorSession that already finished gathering candidates.
1628TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
1629 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1630 kDefaultPortAllocatorFlags);
1631 // First create a pooled session for each endpoint.
1632 auto& allocator_1 = GetEndpoint(0)->allocator_;
1633 auto& allocator_2 = GetEndpoint(1)->allocator_;
1634 int pool_size = 1;
1635 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001636 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001637 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001638 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001639 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001640 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001641 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001642 allocator_2->GetPooledSession();
1643 ASSERT_NE(nullptr, pooled_session_1);
1644 ASSERT_NE(nullptr, pooled_session_2);
1645 // Wait for the pooled sessions to finish gathering before the
1646 // P2PTransportChannels try to use them.
1647 EXPECT_TRUE_WAIT(pooled_session_1->CandidatesAllocationDone() &&
1648 pooled_session_2->CandidatesAllocationDone(),
1649 kDefaultTimeout);
1650 // Now let the endpoints connect and try exchanging some data.
1651 CreateChannels(1);
1652 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
1653 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1654 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1655 1000, 1000);
1656 TestSendRecv(1);
1657 // Make sure the P2PTransportChannels are actually using ports from the
1658 // pooled sessions.
1659 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1660 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
1661 EXPECT_NE(pooled_ports_1.end(),
1662 std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001663 ep1_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001664 EXPECT_NE(pooled_ports_2.end(),
1665 std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
Honghai Zhang572b0942016-06-23 12:26:57 -07001666 ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001667}
1668
deadbeef14f97f52016-06-22 17:14:15 -07001669// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07001670// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07001671// as soon as it's created.
1672TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
1673 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1674 kDefaultPortAllocatorFlags);
1675 // Only configure one channel so we can control when the remote candidate
1676 // is added.
1677 GetEndpoint(0)->cd1_.ch_.reset(
1678 CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceUfrag[0],
1679 kIcePwd[0], kIceUfrag[1], kIcePwd[1]));
1680 IceConfig config;
1681 config.presume_writable_when_fully_relayed = true;
1682 ep1_ch1()->SetIceConfig(config);
1683 ep1_ch1()->MaybeStartGathering();
1684 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
1685 ep1_ch1()->gathering_state(), kDefaultTimeout);
1686 // Add two remote candidates; a host candidate (with higher priority)
1687 // and TURN candidate.
1688 ep1_ch1()->AddRemoteCandidate(
1689 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
1690 ep1_ch1()->AddRemoteCandidate(
1691 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
1692 // Expect that the TURN-TURN candidate pair will be prioritized since it's
1693 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07001694 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07001695 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1696 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1697 // Also expect that the channel instantly indicates that it's writable since
1698 // it has a TURN-TURN pair.
1699 EXPECT_TRUE(ep1_ch1()->writable());
1700 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001701 // Also make sure we can immediately send packets.
1702 const char* data = "test";
1703 int len = static_cast<int>(strlen(data));
1704 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07001705}
1706
Taylor Brandstetteref184702016-06-23 17:35:47 -07001707// Test that a TURN/peer reflexive candidate pair is also presumed writable.
1708TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
1709 rtc::ScopedFakeClock fake_clock;
1710
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001711 // We need to add artificial network delay to verify that the connection
1712 // is presumed writable before it's actually writable. Without this delay
1713 // it would become writable instantly.
1714 virtual_socket_server()->set_delay_mean(50);
1715 virtual_socket_server()->UpdateDelayDistribution();
1716
Taylor Brandstetteref184702016-06-23 17:35:47 -07001717 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1718 kDefaultPortAllocatorFlags);
1719 // We want the remote TURN candidate to show up as prflx. To do this we need
1720 // to configure the server to accept packets from an address we haven't
1721 // explicitly installed permission for.
1722 test_turn_server()->set_enable_permission_checks(false);
1723 IceConfig config;
1724 config.presume_writable_when_fully_relayed = true;
1725 GetEndpoint(0)->cd1_.ch_.reset(
1726 CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceUfrag[0],
1727 kIcePwd[0], kIceUfrag[1], kIcePwd[1]));
1728 GetEndpoint(1)->cd1_.ch_.reset(
1729 CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceUfrag[1],
1730 kIcePwd[1], kIceUfrag[0], kIcePwd[0]));
1731 ep1_ch1()->SetIceConfig(config);
1732 ep2_ch1()->SetIceConfig(config);
1733 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
1734 // candidate as peer reflexive.
1735 PauseCandidates(1);
1736 ep1_ch1()->MaybeStartGathering();
1737 ep2_ch1()->MaybeStartGathering();
1738
1739 // Wait for the TURN<->prflx connection.
1740 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
1741 1000, fake_clock);
1742 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
1743 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1744 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1745 // Make sure that at this point the connection is only presumed writable,
1746 // not fully writable.
1747 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
1748
1749 // Now wait for it to actually become writable.
1750 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(), 1000,
1751 fake_clock);
1752
1753 // Explitly destroy channels, before fake clock is destroyed.
1754 DestroyChannels();
1755}
1756
deadbeef14f97f52016-06-22 17:14:15 -07001757// Test that a presumed-writable TURN<->TURN connection is preferred above an
1758// unreliable connection (one that has failed to be pinged for some time).
1759TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
1760 rtc::ScopedFakeClock fake_clock;
1761
1762 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1763 kDefaultPortAllocatorFlags);
1764 IceConfig config;
1765 config.presume_writable_when_fully_relayed = true;
1766 GetEndpoint(0)->cd1_.ch_.reset(
1767 CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceUfrag[0],
1768 kIcePwd[0], kIceUfrag[1], kIcePwd[1]));
1769 GetEndpoint(1)->cd1_.ch_.reset(
1770 CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceUfrag[1],
1771 kIcePwd[1], kIceUfrag[0], kIcePwd[0]));
1772 ep1_ch1()->SetIceConfig(config);
1773 ep2_ch1()->SetIceConfig(config);
1774 ep1_ch1()->MaybeStartGathering();
1775 ep2_ch1()->MaybeStartGathering();
1776 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07001777 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1778 ep1_ch1()->selected_connection()->writable() &&
1779 ep2_ch1()->receiving() &&
1780 ep2_ch1()->writable() &&
1781 ep2_ch1()->selected_connection()->writable(),
1782 1000, fake_clock);
1783 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07001784 // Destroy the second channel and wait for the current connection on the
1785 // first channel to become "unreliable", making it no longer writable.
1786 GetEndpoint(1)->cd1_.ch_.reset();
1787 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), 10000, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001788 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07001789 // Add a remote TURN candidate. The first channel should still have a TURN
1790 // port available to make a TURN<->TURN pair that's presumed writable.
1791 ep1_ch1()->AddRemoteCandidate(
1792 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
1793 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1794 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1795 EXPECT_TRUE(ep1_ch1()->writable());
1796 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07001797 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07001798 // Explitly destroy channels, before fake clock is destroyed.
1799 DestroyChannels();
1800}
1801
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001802// Test what happens when we have 2 users behind the same NAT. This can lead
1803// to interesting behavior because the STUN server will only give out the
1804// address of the outermost NAT.
1805class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
1806 protected:
1807 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
1808 ASSERT(nat_type >= NAT_FULL_CONE && nat_type <= NAT_SYMMETRIC);
1809 rtc::NATSocketServer::Translator* outer_nat =
1810 nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
1811 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
1812 ConfigureEndpoint(outer_nat, 0, config1);
1813 ConfigureEndpoint(outer_nat, 1, config2);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001814 set_remote_ice_credential_source(FROM_SETICECREDENTIALS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001815 }
1816 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
1817 int endpoint, Config config) {
1818 ASSERT(config <= NAT_SYMMETRIC);
1819 if (config == OPEN) {
1820 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1821 nat->AddClient(kPrivateAddrs[endpoint]);
1822 } else {
1823 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1824 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
1825 static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
1826 kCascadedPrivateAddrs[endpoint]);
1827 }
1828 }
1829};
1830
1831TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
1832 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001833 Test(P2PTransportChannelTestBase::Result(
deadbeefcbecd352015-09-23 11:50:27 -07001834 "prflx", "udp", "stun", "udp", "stun", "udp", "prflx", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001835}
1836
1837// Test what happens when we have multiple available pathways.
1838// In the future we will try different RTTs and configs for the different
1839// interfaces, so that we can simulate a user with Ethernet and VPN networks.
1840class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07001841 public:
1842 const cricket::Connection* GetConnectionWithRemoteAddress(
1843 cricket::P2PTransportChannel* channel,
1844 const SocketAddress& address) {
1845 for (cricket::Connection* conn : channel->connections()) {
1846 if (conn->remote_candidate().address().EqualIPs(address)) {
1847 return conn;
1848 }
1849 }
1850 return nullptr;
1851 }
1852
1853 const cricket::Connection* GetConnectionWithLocalAddress(
1854 cricket::P2PTransportChannel* channel,
1855 const SocketAddress& address) {
1856 for (cricket::Connection* conn : channel->connections()) {
1857 if (conn->local_candidate().address().EqualIPs(address)) {
1858 return conn;
1859 }
1860 }
1861 return nullptr;
1862 }
1863
1864 void DestroyAllButBestConnection(cricket::P2PTransportChannel* channel) {
1865 const cricket::Connection* best_connection = channel->best_connection();
1866 for (cricket::Connection* conn : channel->connections()) {
1867 if (conn != best_connection) {
1868 conn->Destroy();
1869 }
1870 }
1871 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001872};
1873
1874// Test that we can establish connectivity when both peers are multihomed.
1875TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
1876 AddAddress(0, kPublicAddrs[0]);
1877 AddAddress(0, kAlternateAddrs[0]);
1878 AddAddress(1, kPublicAddrs[1]);
1879 AddAddress(1, kAlternateAddrs[1]);
1880 Test(kLocalUdpToLocalUdp);
1881}
1882
Honghai Zhang52dce732016-03-31 12:37:31 -07001883// Test that we can quickly switch links if an interface goes down.
1884// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07001885TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07001886 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001887 AddAddress(0, kPublicAddrs[0]);
1888 // Adding alternate address will make sure |kPublicAddrs| has the higher
1889 // priority than others. This is due to FakeNetwork::AddInterface method.
1890 AddAddress(1, kAlternateAddrs[1]);
1891 AddAddress(1, kPublicAddrs[1]);
1892
1893 // Use only local ports for simplicity.
1894 SetAllocatorFlags(0, kOnlyLocalPorts);
1895 SetAllocatorFlags(1, kOnlyLocalPorts);
1896
1897 // Create channels and let them go writable, as usual.
1898 CreateChannels(1);
honghaiza58ea782015-09-24 08:13:36 -07001899
honghaiz9ad0db52016-07-14 19:30:28 -07001900 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1901 ep2_ch1()->receiving() &&
1902 ep2_ch1()->writable(),
1903 3000, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001904 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1905 ep2_ch1()->selected_connection() &&
1906 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1907 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001908
honghaiza4845ef2015-11-13 09:52:56 -08001909 // Make the receiving timeout shorter for testing.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07001910 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza4845ef2015-11-13 09:52:56 -08001911 ep1_ch1()->SetIceConfig(config);
1912 ep2_ch1()->SetIceConfig(config);
1913
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001914 // Blackhole any traffic to or from the public addrs.
1915 LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07001916 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07001917 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07001918 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
1919 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07001920 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07001921 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07001922 !selected_connection1->receiving() && !selected_connection2->receiving(),
honghaiz9ad0db52016-07-14 19:30:28 -07001923 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07001924
honghaiz9ad0db52016-07-14 19:30:28 -07001925 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07001926 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07001927 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
1928 ep2_ch1()->selected_connection()->receiving(),
1929 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07001930 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
1931 EXPECT_TRUE(
1932 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1933 EXPECT_TRUE(
1934 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1935
1936 DestroyChannels();
1937}
1938
Honghai Zhang52dce732016-03-31 12:37:31 -07001939// Test that we can quickly switch links if an interface goes down.
1940// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07001941TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07001942 rtc::ScopedFakeClock clock;
honghaiza58ea782015-09-24 08:13:36 -07001943 // Adding alternate address will make sure |kPublicAddrs| has the higher
1944 // priority than others. This is due to FakeNetwork::AddInterface method.
1945 AddAddress(0, kAlternateAddrs[0]);
1946 AddAddress(0, kPublicAddrs[0]);
1947 AddAddress(1, kPublicAddrs[1]);
1948
1949 // Use only local ports for simplicity.
1950 SetAllocatorFlags(0, kOnlyLocalPorts);
1951 SetAllocatorFlags(1, kOnlyLocalPorts);
1952
1953 // Create channels and let them go writable, as usual.
1954 CreateChannels(1);
honghaiz9ad0db52016-07-14 19:30:28 -07001955 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1956 ep2_ch1()->receiving() &&
1957 ep2_ch1()->writable(),
1958 3000, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001959 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1960 ep2_ch1()->selected_connection() &&
1961 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1962 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07001963
honghaiza4845ef2015-11-13 09:52:56 -08001964 // Make the receiving timeout shorter for testing.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07001965 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza4845ef2015-11-13 09:52:56 -08001966 ep1_ch1()->SetIceConfig(config);
1967 ep2_ch1()->SetIceConfig(config);
1968
honghaiza58ea782015-09-24 08:13:36 -07001969 // Blackhole any traffic to or from the public addrs.
1970 LOG(LS_INFO) << "Failing over...";
1971 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07001972 // The selected connections will switch, so keep references to them.
1973 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
1974 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07001975 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07001976 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07001977 !selected_connection1->receiving() && !selected_connection2->receiving(),
honghaiz9ad0db52016-07-14 19:30:28 -07001978 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07001979
honghaiz9ad0db52016-07-14 19:30:28 -07001980 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07001981 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07001982 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
1983 ep2_ch1()->selected_connection()->receiving(),
1984 3000, clock);
honghaiza58ea782015-09-24 08:13:36 -07001985 EXPECT_TRUE(
1986 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
1987 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1988 EXPECT_TRUE(
1989 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001990
1991 DestroyChannels();
1992}
1993
honghaiz9ad0db52016-07-14 19:30:28 -07001994// Test that if an interface fails temporarily and then recovers quickly,
1995// the selected connection will not switch.
1996// The case that it will switch over to the backup connection if the selected
1997// connection does not recover after enough time is covered in
1998// TestFailoverControlledSide and TestFailoverControllingSide.
1999TEST_F(P2PTransportChannelMultihomedTest,
2000 TestConnectionSwitchDampeningControlledSide) {
2001 rtc::ScopedFakeClock clock;
2002 AddAddress(0, kPublicAddrs[0]);
2003 // Adding alternate address will make sure |kPublicAddrs| has the higher
2004 // priority than others. This is due to FakeNetwork::AddInterface method.
2005 AddAddress(1, kAlternateAddrs[1]);
2006 AddAddress(1, kPublicAddrs[1]);
2007
2008 // Use only local ports for simplicity.
2009 SetAllocatorFlags(0, kOnlyLocalPorts);
2010 SetAllocatorFlags(1, kOnlyLocalPorts);
2011
2012 // Create channels and let them go writable, as usual.
2013 CreateChannels(1);
2014
2015 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2016 ep2_ch1()->receiving() &&
2017 ep2_ch1()->writable(),
2018 3000, clock);
2019 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2020 ep2_ch1()->selected_connection() &&
2021 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2022 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2023
2024 // Make the receiving timeout shorter for testing.
2025 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2026 ep1_ch1()->SetIceConfig(config);
2027 ep2_ch1()->SetIceConfig(config);
2028 reset_selected_candidate_pair_switches();
2029
2030 // Blackhole any traffic to or from the public addrs.
2031 LOG(LS_INFO) << "Failing over...";
2032 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2033
2034 // The selected connections may switch, so keep references to them.
2035 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2036 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2037 // We should detect loss of receiving within 1 second or so.
2038 EXPECT_TRUE_SIMULATED_WAIT(
2039 !selected_connection1->receiving() && !selected_connection2->receiving(),
2040 3000, clock);
2041 // After a short while, the link recovers itself.
2042 SIMULATED_WAIT(false, 10, clock);
2043 fw()->ClearRules();
2044
2045 // We should remain on the public address on both sides and no connection
2046 // switches should have happened.
2047 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2048 ep2_ch1()->selected_connection()->receiving(),
2049 3000, clock);
2050 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2051 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2052 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2053
2054 DestroyChannels();
2055}
2056
2057// Test that if an interface fails temporarily and then recovers quickly,
2058// the selected connection will not switch.
2059TEST_F(P2PTransportChannelMultihomedTest,
2060 TestConnectionSwitchDampeningControllingSide) {
2061 rtc::ScopedFakeClock clock;
2062 // Adding alternate address will make sure |kPublicAddrs| has the higher
2063 // priority than others. This is due to FakeNetwork::AddInterface method.
2064 AddAddress(0, kAlternateAddrs[0]);
2065 AddAddress(0, kPublicAddrs[0]);
2066 AddAddress(1, kPublicAddrs[1]);
2067
2068 // Use only local ports for simplicity.
2069 SetAllocatorFlags(0, kOnlyLocalPorts);
2070 SetAllocatorFlags(1, kOnlyLocalPorts);
2071
2072 // Create channels and let them go writable, as usual.
2073 CreateChannels(1);
2074 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2075 ep2_ch1()->receiving() &&
2076 ep2_ch1()->writable(),
2077 3000, clock);
2078 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2079 ep2_ch1()->selected_connection() &&
2080 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2081 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2082
2083 // Make the receiving timeout shorter for testing.
2084 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2085 ep1_ch1()->SetIceConfig(config);
2086 ep2_ch1()->SetIceConfig(config);
2087 reset_selected_candidate_pair_switches();
2088
2089 // Blackhole any traffic to or from the public addrs.
2090 LOG(LS_INFO) << "Failing over...";
2091 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2092 // The selected connections may switch, so keep references to them.
2093 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2094 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2095 // We should detect loss of receiving within 1 second or so.
2096 EXPECT_TRUE_SIMULATED_WAIT(
2097 !selected_connection1->receiving() && !selected_connection2->receiving(),
2098 3000, clock);
2099 // The link recovers after a short while.
2100 SIMULATED_WAIT(false, 10, clock);
2101 fw()->ClearRules();
2102
2103 // We should not switch to the alternate addr on both sides because of the
2104 // dampening.
2105 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2106 ep2_ch1()->selected_connection()->receiving(),
2107 3000, clock);
2108 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2109 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2110 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2111 DestroyChannels();
2112}
2113
honghaize1a0c942016-02-16 14:54:56 -08002114// Tests that a Wifi-Wifi connection has the highest precedence.
2115TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2116 // The interface names are chosen so that |cellular| would have higher
2117 // candidate priority if it is not for the network type.
2118 auto& wifi = kAlternateAddrs;
2119 auto& cellular = kPublicAddrs;
2120 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2121 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2122 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2123 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2124
2125 // Use only local ports for simplicity.
2126 SetAllocatorFlags(0, kOnlyLocalPorts);
2127 SetAllocatorFlags(1, kOnlyLocalPorts);
2128
2129 // Create channels and let them go writable, as usual.
2130 CreateChannels(1);
2131
2132 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2133 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2134 1000, 1000);
2135 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002136 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002137 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2138 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2139 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002140 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002141 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2142 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2143 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002144 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002145}
2146
2147// Tests that a Wifi-Cellular connection has higher precedence than
2148// a Cellular-Cellular connection.
2149TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2150 // The interface names are chosen so that |cellular| would have higher
2151 // candidate priority if it is not for the network type.
2152 auto& wifi = kAlternateAddrs;
2153 auto& cellular = kPublicAddrs;
2154 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2155 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2156 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2157
2158 // Use only local ports for simplicity.
2159 SetAllocatorFlags(0, kOnlyLocalPorts);
2160 SetAllocatorFlags(1, kOnlyLocalPorts);
2161
2162 // Create channels and let them go writable, as usual.
2163 CreateChannels(1);
2164
2165 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2166 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2167 1000, 1000);
2168 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002169 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002170 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2171 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002172 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002173 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2174 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002175 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002176}
2177
Honghai Zhang381b4212015-12-04 12:24:03 -08002178// Test that the backup connection is pinged at a rate no faster than
2179// what was configured.
2180TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2181 AddAddress(0, kPublicAddrs[0]);
2182 // Adding alternate address will make sure |kPublicAddrs| has the higher
2183 // priority than others. This is due to FakeNetwork::AddInterface method.
2184 AddAddress(1, kAlternateAddrs[1]);
2185 AddAddress(1, kPublicAddrs[1]);
2186
2187 // Use only local ports for simplicity.
2188 SetAllocatorFlags(0, kOnlyLocalPorts);
2189 SetAllocatorFlags(1, kOnlyLocalPorts);
2190
2191 // Create channels and let them go writable, as usual.
2192 CreateChannels(1);
2193 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2194 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2195 1000, 1000);
2196 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002197 ep2_ch1()->SetIceConfig(
2198 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002199 // After the state becomes COMPLETED, the backup connection will be pinged
2200 // once every |backup_ping_interval| milliseconds.
deadbeef14f97f52016-06-22 17:14:15 -07002201 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == STATE_COMPLETED, 1000);
2202 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002203 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002204 Connection* backup_conn = connections[1];
Honghai Zhang381b4212015-12-04 12:24:03 -08002205 EXPECT_TRUE_WAIT(backup_conn->writable(), 3000);
honghaiz34b11eb2016-03-16 08:55:44 -07002206 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002207 EXPECT_TRUE_WAIT(
2208 last_ping_response_ms < backup_conn->last_ping_response_received(), 5000);
2209 int time_elapsed =
2210 backup_conn->last_ping_response_received() - last_ping_response_ms;
2211 LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
2212 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002213
2214 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002215}
2216
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002217TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
2218 AddAddress(0, kAlternateAddrs[0]);
2219 AddAddress(0, kPublicAddrs[0]);
2220 AddAddress(1, kPublicAddrs[1]);
2221 // Create channels and let them go writable, as usual.
2222 CreateChannels(1);
2223
2224 // Both transport channels will reach STATE_COMPLETED quickly.
deadbeef14f97f52016-06-22 17:14:15 -07002225 EXPECT_EQ_WAIT(TransportChannelState::STATE_COMPLETED, ep1_ch1()->GetState(),
2226 1000);
2227 EXPECT_EQ_WAIT(TransportChannelState::STATE_COMPLETED, ep2_ch1()->GetState(),
2228 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002229}
2230
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002231// Tests that when a network interface becomes inactive, if Continual Gathering
2232// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002233// will be removed from the port list of the channel, and the respective
2234// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002235TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002236 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002237 AddAddress(0, kPublicAddrs[0]);
2238 AddAddress(1, kPublicAddrs[1]);
2239 // Create channels and let them go writable, as usual.
2240 CreateChannels(1);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002241 ep1_ch1()->SetIceConfig(CreateIceConfig(2000, GATHER_CONTINUALLY));
2242 ep2_ch1()->SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaize3c6c822016-02-17 13:00:28 -08002243
2244 SetAllocatorFlags(0, kOnlyLocalPorts);
2245 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002246 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2247 ep2_ch1()->receiving() &&
2248 ep2_ch1()->writable(),
2249 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002250 // More than one port has been created.
2251 EXPECT_LE(1U, ep1_ch1()->ports().size());
2252 // Endpoint 1 enabled continual gathering; the port will be removed
2253 // when the interface is removed.
2254 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002255 EXPECT_TRUE(ep1_ch1()->ports().empty());
2256 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002257 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2258 clock);
honghaize3c6c822016-02-17 13:00:28 -08002259
2260 size_t num_ports = ep2_ch1()->ports().size();
2261 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002262 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002263 // Endpoint 2 did not enable continual gathering; the local port will still be
2264 // removed when the interface is removed but the remote candidates on the
2265 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002266 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002267
2268 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2269 clock);
2270 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002271 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002272
2273 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002274}
2275
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002276// Tests that continual gathering will create new connections when a new
2277// interface is added.
2278TEST_F(P2PTransportChannelMultihomedTest,
2279 TestContinualGatheringOnNewInterface) {
2280 auto& wifi = kAlternateAddrs;
2281 auto& cellular = kPublicAddrs;
2282 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2283 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2284 CreateChannels(1);
2285 // Set continual gathering policy.
2286 ep1_ch1()->SetIceConfig(CreateIceConfig(1000, GATHER_CONTINUALLY));
2287 ep2_ch1()->SetIceConfig(CreateIceConfig(1000, GATHER_CONTINUALLY));
2288 SetAllocatorFlags(0, kOnlyLocalPorts);
2289 SetAllocatorFlags(1, kOnlyLocalPorts);
2290 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2291 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2292 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002293
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002294 // Add a new wifi interface on end point 2. We should expect a new connection
2295 // to be created and the new one will be the best connection.
2296 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2297 const cricket::Connection* conn;
2298 EXPECT_TRUE_WAIT((conn = ep1_ch1()->best_connection()) != nullptr &&
2299 conn->remote_candidate().address().EqualIPs(wifi[1]),
2300 kDefaultTimeout);
2301 EXPECT_TRUE_WAIT((conn = ep2_ch1()->best_connection()) != nullptr &&
2302 conn->local_candidate().address().EqualIPs(wifi[1]),
2303 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002304
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002305 // Add a new cellular interface on end point 1, we should expect a new
2306 // backup connection created using this new interface.
2307 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2308 EXPECT_TRUE_WAIT(ep1_ch1()->GetState() == cricket::STATE_COMPLETED &&
2309 (conn = GetConnectionWithLocalAddress(
2310 ep1_ch1(), cellular[0])) != nullptr &&
2311 conn != ep1_ch1()->best_connection() && conn->writable(),
2312 kDefaultTimeout);
2313 EXPECT_TRUE_WAIT(
2314 ep2_ch1()->GetState() == cricket::STATE_COMPLETED &&
2315 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
2316 nullptr &&
2317 conn != ep2_ch1()->best_connection() && conn->receiving(),
2318 kDefaultTimeout);
2319
2320 DestroyChannels();
2321}
2322
2323// Tests that we can switch links via continual gathering.
2324TEST_F(P2PTransportChannelMultihomedTest,
2325 TestSwitchLinksViaContinualGathering) {
2326 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002327 AddAddress(0, kPublicAddrs[0]);
2328 AddAddress(1, kPublicAddrs[1]);
2329 // Use only local ports for simplicity.
2330 SetAllocatorFlags(0, kOnlyLocalPorts);
2331 SetAllocatorFlags(1, kOnlyLocalPorts);
2332
2333 // Create channels and let them go writable, as usual.
2334 CreateChannels(1);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002335 // Set continual gathering policy.
2336 ep1_ch1()->SetIceConfig(CreateIceConfig(1000, GATHER_CONTINUALLY));
2337 ep2_ch1()->SetIceConfig(CreateIceConfig(1000, GATHER_CONTINUALLY));
2338 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2339 ep2_ch1()->receiving() &&
2340 ep2_ch1()->writable(),
2341 3000, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002342 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07002343 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002344 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2345 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2346
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002347 // Add the new address first and then remove the other one.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002348 LOG(LS_INFO) << "Draining...";
2349 AddAddress(1, kAlternateAddrs[1]);
2350 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002351 // We should switch to use the alternate address after an exchange of pings.
2352 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002353 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002354 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2355 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
2356 3000, clock);
2357
2358 // Remove one address first and then add another address.
2359 LOG(LS_INFO) << "Draining again...";
2360 RemoveAddress(1, kAlternateAddrs[1]);
2361 AddAddress(1, kAlternateAddrs[0]);
2362 EXPECT_TRUE_SIMULATED_WAIT(
2363 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
2364 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2365 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
2366 3000, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002367
2368 DestroyChannels();
2369}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002370
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002371/*
2372TODO(honghaiz) Once continual gathering fully supports
2373GATHER_CONTINUALLY_AND_RECOVER, put this test back.
2374
2375// Tests that if the backup connections are lost and then the interface with the
2376// selected connection is gone, continual gathering will restore the
2377// connectivity.
2378TEST_F(P2PTransportChannelMultihomedTest,
2379 TestBackupConnectionLostThenInterfaceGone) {
2380 rtc::ScopedFakeClock clock;
2381 auto& wifi = kAlternateAddrs;
2382 auto& cellular = kPublicAddrs;
2383 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2384 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2385 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2386 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2387 // Use only local ports for simplicity.
2388 SetAllocatorFlags(0, kOnlyLocalPorts);
2389 SetAllocatorFlags(1, kOnlyLocalPorts);
2390
2391 // Create channels and let them go writable, as usual.
2392 CreateChannels(1);
2393 // Set continual gathering policy.
2394 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER);
2395 ep1_ch1()->SetIceConfig(config);
2396 ep2_ch1()->SetIceConfig(config);
2397 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2398 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2399 3000, clock);
2400 EXPECT_TRUE(ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
2401 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2402 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2403
2404 // First destroy all backup connection.
2405 DestroyAllButBestConnection(ep1_ch1());
2406
2407 SIMULATED_WAIT(false, 10, clock);
2408 // Then the interface of the best connection goes away.
2409 RemoveAddress(0, wifi[0]);
2410 EXPECT_TRUE_SIMULATED_WAIT(
2411 ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
2412 LocalCandidate(ep1_ch1())->address().EqualIPs(cellular[0]) &&
2413 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2414 3000, clock);
2415
2416 DestroyChannels();
2417}
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002418*/
2419
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002420// Tests that the backup connection will be restored after it is destroyed.
2421TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
2422 rtc::ScopedFakeClock clock;
2423 auto& wifi = kAlternateAddrs;
2424 auto& cellular = kPublicAddrs;
2425 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2426 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
2427 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
2428 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
2429 // Use only local ports for simplicity.
2430 SetAllocatorFlags(0, kOnlyLocalPorts);
2431 SetAllocatorFlags(1, kOnlyLocalPorts);
2432
2433 // Create channels and let them go writable, as usual.
2434 CreateChannels(1);
2435 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2436 config.regather_on_failed_networks_interval = rtc::Optional<int>(2000);
2437 ep1_ch1()->SetIceConfig(config);
2438 ep2_ch1()->SetIceConfig(config);
2439 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2440 ep2_ch1()->receiving() &&
2441 ep2_ch1()->writable(),
2442 3000, clock);
2443 EXPECT_TRUE(ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
2444 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2445 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
2446
2447 // Destroy all backup connections.
2448 DestroyAllButBestConnection(ep1_ch1());
2449 // Ensure the backup connection is removed first.
2450 EXPECT_TRUE_SIMULATED_WAIT(
2451 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
2452 kDefaultTimeout, clock);
2453 const cricket::Connection* conn;
2454 EXPECT_TRUE_SIMULATED_WAIT(
2455 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
2456 nullptr &&
2457 conn != ep1_ch1()->best_connection() && conn->writable(),
2458 5000, clock);
2459
2460 DestroyChannels();
2461}
2462
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002463// A collection of tests which tests a single P2PTransportChannel by sending
2464// pings.
2465class P2PTransportChannelPingTest : public testing::Test,
2466 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002467 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002468 P2PTransportChannelPingTest()
2469 : pss_(new rtc::PhysicalSocketServer),
2470 vss_(new rtc::VirtualSocketServer(pss_.get())),
2471 ss_scope_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002472
2473 protected:
deadbeef14f97f52016-06-22 17:14:15 -07002474 void PrepareChannel(P2PTransportChannel* ch) {
2475 ch->SetIceRole(ICEROLE_CONTROLLING);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002476 ch->SetIceCredentials(kIceUfrag[0], kIcePwd[0]);
2477 ch->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
Honghai Zhang52dce732016-03-31 12:37:31 -07002478 ch->SignalSelectedCandidatePairChanged.connect(
2479 this, &P2PTransportChannelPingTest::OnSelectedCandidatePairChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07002480 ch->SignalReadyToSend.connect(this,
2481 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07002482 ch->SignalStateChanged.connect(
2483 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002484 }
2485
deadbeef14f97f52016-06-22 17:14:15 -07002486 Connection* WaitForConnectionTo(P2PTransportChannel* ch,
2487 const std::string& ip,
2488 int port_num) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002489 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr, 3000);
2490 return GetConnectionTo(ch, ip, port_num);
2491 }
2492
deadbeef14f97f52016-06-22 17:14:15 -07002493 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002494 if (ch->ports().empty()) {
2495 return nullptr;
2496 }
deadbeef14f97f52016-06-22 17:14:15 -07002497 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002498 }
2499
Honghai Zhanga74363c2016-07-28 18:06:15 -07002500 Port* GetPrunedPort(P2PTransportChannel* ch) {
2501 if (ch->pruned_ports().empty()) {
2502 return nullptr;
2503 }
2504 return static_cast<Port*>(ch->pruned_ports()[0]);
2505 }
2506
deadbeef14f97f52016-06-22 17:14:15 -07002507 Connection* GetConnectionTo(P2PTransportChannel* ch,
2508 const std::string& ip,
2509 int port_num) {
2510 Port* port = GetPort(ch);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002511 if (!port) {
2512 return nullptr;
2513 }
2514 return port->GetConnection(rtc::SocketAddress(ip, port_num));
2515 }
2516
deadbeef14f97f52016-06-22 17:14:15 -07002517 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
2518 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08002519 if (conn) {
2520 ch->MarkConnectionPinged(conn);
2521 }
2522 return conn;
2523 }
2524
deadbeef14f97f52016-06-22 17:14:15 -07002525 int SendData(TransportChannel& channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07002526 const char* data,
2527 size_t len,
2528 int packet_id) {
2529 rtc::PacketOptions options;
2530 options.packet_id = packet_id;
2531 return channel.SendPacket(data, len, options, 0);
2532 }
2533
Honghai Zhang572b0942016-06-23 12:26:57 -07002534 Connection* CreateConnectionWithCandidate(P2PTransportChannel& channel,
2535 rtc::ScopedFakeClock& clock,
2536 const std::string& ip_addr,
2537 int port,
2538 int priority,
2539 bool writable) {
2540 channel.AddRemoteCandidate(
2541 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
2542 EXPECT_TRUE_SIMULATED_WAIT(
2543 GetConnectionTo(&channel, ip_addr, port) != nullptr, 3000, clock);
2544 Connection* conn = GetConnectionTo(&channel, ip_addr, port);
2545
2546 if (conn && writable) {
2547 conn->ReceivedPingResponse(LOW_RTT); // make it writable
2548 }
2549 return conn;
2550 }
2551
2552 void NominateConnection(Connection* conn) {
2553 conn->set_nominated(true);
2554 conn->SignalNominated(conn);
2555 }
2556
Honghai Zhang52dce732016-03-31 12:37:31 -07002557 void OnSelectedCandidatePairChanged(
deadbeef14f97f52016-06-22 17:14:15 -07002558 TransportChannel* transport_channel,
2559 CandidatePairInterface* selected_candidate_pair,
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002560 int last_sent_packet_id,
2561 bool ready_to_send) {
Honghai Zhang52dce732016-03-31 12:37:31 -07002562 last_selected_candidate_pair_ = selected_candidate_pair;
2563 last_sent_packet_id_ = last_sent_packet_id;
Honghai Zhang572b0942016-06-23 12:26:57 -07002564 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07002565 }
2566
deadbeef14f97f52016-06-22 17:14:15 -07002567 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07002568 const std::string& remote_ufrag,
2569 int priority) {
deadbeef14f97f52016-06-22 17:14:15 -07002570 IceMessage msg;
2571 msg.SetType(STUN_BINDING_REQUEST);
2572 msg.AddAttribute(new StunByteStringAttribute(
2573 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07002574 conn->local_candidate().username() + ":" + remote_ufrag));
deadbeef14f97f52016-06-22 17:14:15 -07002575 msg.AddAttribute(new StunUInt32Attribute(STUN_ATTR_PRIORITY, priority));
2576 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07002577 msg.AddMessageIntegrity(conn->local_candidate().password());
2578 msg.AddFingerprint();
2579 rtc::ByteBufferWriter buf;
2580 msg.Write(&buf);
2581 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
2582 }
2583
deadbeef14f97f52016-06-22 17:14:15 -07002584 void OnReadyToSend(TransportChannel* channel) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07002585 channel_ready_to_send_ = true;
2586 }
deadbeef14f97f52016-06-22 17:14:15 -07002587 void OnChannelStateChanged(TransportChannelImpl* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07002588 channel_state_ = channel->GetState();
2589 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002590
deadbeef14f97f52016-06-22 17:14:15 -07002591 CandidatePairInterface* last_selected_candidate_pair() {
Honghai Zhang52dce732016-03-31 12:37:31 -07002592 return last_selected_candidate_pair_;
2593 }
2594 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002595 bool channel_ready_to_send() { return channel_ready_to_send_; }
2596 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
deadbeef14f97f52016-06-22 17:14:15 -07002597 TransportChannelState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07002598 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07002599 int switches = selected_candidate_pair_switches_;
2600 selected_candidate_pair_switches_ = 0;
2601 return switches;
2602 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002603
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002604 private:
kwiberg3ec46792016-04-27 07:22:53 -07002605 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
2606 std::unique_ptr<rtc::VirtualSocketServer> vss_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002607 rtc::SocketServerScope ss_scope_;
deadbeef14f97f52016-06-22 17:14:15 -07002608 CandidatePairInterface* last_selected_candidate_pair_ = nullptr;
Honghai Zhang572b0942016-06-23 12:26:57 -07002609 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07002610 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07002611 bool channel_ready_to_send_ = false;
deadbeef14f97f52016-06-22 17:14:15 -07002612 TransportChannelState channel_state_ = STATE_INIT;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002613};
2614
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002615TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07002616 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2617 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002618 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002619 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002620 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2621 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002622
deadbeef14f97f52016-06-22 17:14:15 -07002623 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2624 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002625 ASSERT_TRUE(conn1 != nullptr);
2626 ASSERT_TRUE(conn2 != nullptr);
2627
2628 // Before a triggered check, the first connection to ping is the
2629 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08002630 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002631
2632 // Receiving a ping causes a triggered check which should make conn1
2633 // be pinged first instead of conn2, even though conn2 has a higher
2634 // priority.
2635 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08002636 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002637}
2638
honghaiz524ecc22016-05-25 12:48:31 -07002639TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07002640 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2641 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07002642 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07002643 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002644 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2645 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07002646
deadbeef14f97f52016-06-22 17:14:15 -07002647 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2648 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07002649 ASSERT_TRUE(conn1 != nullptr);
2650 ASSERT_TRUE(conn2 != nullptr);
2651
2652 // Low-priority connection becomes writable so that the other connection
2653 // is not pruned.
zhihuang435264a2016-06-21 11:28:38 -07002654 conn1->ReceivedPingResponse(LOW_RTT);
honghaiz524ecc22016-05-25 12:48:31 -07002655 EXPECT_TRUE_WAIT(
2656 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
2657 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
2658 kDefaultTimeout);
2659}
2660
zhihuang435264a2016-06-21 11:28:38 -07002661// Verify that the connections are pinged at the right time.
2662TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
2663 rtc::ScopedFakeClock clock;
2664 int RTT_RATIO = 4;
2665 int SCHEDULING_RANGE = 200;
2666 int RTT_RANGE = 10;
2667
deadbeef14f97f52016-06-22 17:14:15 -07002668 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2669 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07002670 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07002671 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002672 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2673 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07002674
2675 ASSERT_TRUE(conn != nullptr);
2676 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
2677
2678 // Initializing.
2679
2680 int64_t start = clock.TimeNanos();
2681 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
2682 kDefaultTimeout, clock);
2683 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
2684 rtc::kNumNanosecsPerMillisec /
2685 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07002686 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002687
2688 // Stabilizing.
2689
2690 conn->ReceivedPingResponse(LOW_RTT);
2691 int ping_sent_before = conn->num_pings_sent();
2692 start = clock.TimeNanos();
2693 // The connection becomes strong but not stable because we haven't been able
2694 // to converge the RTT.
2695 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2696 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002697 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002698 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07002699 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002700
2701 // Stabilized.
2702
2703 // The connection becomes stable after receiving more than RTT_RATIO rtt
2704 // samples.
2705 for (int i = 0; i < RTT_RATIO; i++) {
2706 conn->ReceivedPingResponse(LOW_RTT);
2707 }
2708 ping_sent_before = conn->num_pings_sent();
2709 start = clock.TimeNanos();
2710 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2711 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002712 EXPECT_GE(ping_interval_ms, STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
2713 EXPECT_LE(ping_interval_ms,
2714 STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002715
2716 // Destabilized.
2717
2718 conn->ReceivedPingResponse(LOW_RTT);
2719 // Create a in-flight ping.
2720 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
2721 start = clock.TimeNanos();
2722 // In-flight ping timeout and the connection will be unstable.
2723 SIMULATED_WAIT(
2724 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec), 3000,
2725 clock);
2726 int64_t duration_ms =
2727 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
2728 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
2729 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
2730 // The connection become unstable due to not receiving ping responses.
2731 ping_sent_before = conn->num_pings_sent();
2732 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2733 // The interval is expected to be
2734 // STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
2735 start = clock.TimeNanos();
2736 ping_sent_before = conn->num_pings_sent();
2737 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2738 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002739 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002740 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07002741 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002742}
2743
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002744// Test that we start pinging as soon as we have a connection and remote ICE
2745// credentials.
2746TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
2747 rtc::ScopedFakeClock clock;
2748
2749 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2750 P2PTransportChannel ch("TestChannel", 1, &pa);
2751 ch.SetIceRole(ICEROLE_CONTROLLING);
2752 ch.SetIceCredentials(kIceUfrag[0], kIcePwd[0]);
2753 ch.MaybeStartGathering();
2754 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
2755 kDefaultTimeout);
2756
2757 // Simulate a binding request being received, creating a peer reflexive
2758 // candidate pair while we still don't have remote ICE credentials.
2759 IceMessage request;
2760 request.SetType(STUN_BINDING_REQUEST);
2761 request.AddAttribute(
2762 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
2763 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
2764 request.AddAttribute(
2765 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
2766 Port* port = GetPort(&ch);
2767 ASSERT_NE(nullptr, port);
2768 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
2769 &request, kIceUfrag[1], false);
2770 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
2771 ASSERT_NE(nullptr, conn);
2772
2773 // Simulate waiting for a second (and change) and verify that no pings were
2774 // sent, since we don't yet have remote ICE credentials.
2775 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
2776 EXPECT_EQ(0, conn->num_pings_sent());
2777
2778 // Set remote ICE credentials. Now we should be able to ping. Ensure that
2779 // the first ping is sent as soon as possible, within one simulated clock
2780 // tick.
2781 ch.SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
2782 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
2783}
2784
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002785TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07002786 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2787 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002788 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002789 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002790 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2791 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002792
deadbeef14f97f52016-06-22 17:14:15 -07002793 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2794 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002795 ASSERT_TRUE(conn1 != nullptr);
2796 ASSERT_TRUE(conn2 != nullptr);
2797
guoweis36f01372016-03-02 18:02:40 -08002798 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
2799 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
zhihuang435264a2016-06-21 11:28:38 -07002800 conn1->ReceivedPingResponse(LOW_RTT);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002801 ASSERT_TRUE(conn1->writable());
2802 conn1->ReceivedPing();
2803
2804 // Ping received, but the connection is already writable, so no
2805 // "triggered check" and conn2 is pinged before conn1 because it has
2806 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08002807 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002808}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002809
honghaiz079a7a12016-06-22 16:26:29 -07002810TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07002811 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2812 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07002813 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07002814 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002815 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07002816
deadbeef14f97f52016-06-22 17:14:15 -07002817 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07002818 ASSERT_TRUE(conn1 != nullptr);
2819
2820 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
2821 conn1->Prune(); // A pruned connection may still be pingable.
2822 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
2823 conn1->FailAndPrune();
2824 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
2825}
2826
Honghai Zhang1590c392016-05-24 13:15:02 -07002827TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07002828 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2829 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07002830 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07002831 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002832 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2833 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07002834 ASSERT_TRUE(conn1 != nullptr);
2835 // Pruning the connection reduces the set of active connections and changes
2836 // the channel state.
2837 conn1->Prune();
deadbeef14f97f52016-06-22 17:14:15 -07002838 EXPECT_EQ_WAIT(STATE_FAILED, channel_state(), kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07002839}
2840
honghaiza54a0802015-12-16 18:37:23 -08002841// Test adding remote candidates with different ufrags. If a remote candidate
2842// is added with an old ufrag, it will be discarded. If it is added with a
2843// ufrag that was not seen before, it will be used to create connections
2844// although the ICE pwd in the remote candidate will be set when the ICE
2845// credentials arrive. If a remote candidate is added with the current ICE
2846// ufrag, its pwd and generation will be set properly.
2847TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07002848 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2849 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08002850 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08002851 ch.MaybeStartGathering();
2852 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07002853 ch.AddRemoteCandidate(
2854 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
2855 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08002856 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002857 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08002858 EXPECT_EQ(kIceUfrag[2], candidate.username());
2859 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08002860 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08002861
2862 // Set the remote credentials with the "future" ufrag.
2863 // This should set the ICE pwd in the remote candidate of |conn1|, making
2864 // it pingable.
2865 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
2866 EXPECT_EQ(kIceUfrag[2], candidate.username());
2867 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08002868 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08002869
2870 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07002871 ch.AddRemoteCandidate(
2872 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08002873 rtc::Thread::Current()->ProcessMessages(500);
2874 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
2875
2876 // Add a candidate with the current ufrag, its pwd and generation will be
2877 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07002878 ch.AddRemoteCandidate(
2879 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
2880 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08002881 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
2882 3000);
deadbeef14f97f52016-06-22 17:14:15 -07002883 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08002884 EXPECT_EQ(kIcePwd[2], new_candidate.password());
2885 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08002886
2887 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07002888 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08002889 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
2890 candidate.username() == kIceUfrag[2]);
2891 if (candidate.username() == kIceUfrag[1]) {
2892 EXPECT_EQ(kIcePwd[1], candidate.password());
2893 } else if (candidate.username() == kIceUfrag[2]) {
2894 EXPECT_EQ(kIcePwd[2], candidate.password());
2895 }
2896 }
honghaiza54a0802015-12-16 18:37:23 -08002897}
2898
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002899TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07002900 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2901 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002902 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002903 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002904
2905 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07002906 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2907 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002908 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02002909 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002910
2911 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07002912 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07002913 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
2914 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002915 ASSERT_TRUE(conn2 != nullptr);
2916 conn2->ReceivedPing();
zhihuang435264a2016-06-21 11:28:38 -07002917 conn2->ReceivedPingResponse(LOW_RTT);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002918
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002919 // Wait for conn1 to be pruned.
2920 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
2921 // Destroy the connection to test SignalUnknownAddress.
2922 conn1->Destroy();
2923 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr, 1000);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002924
2925 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07002926 IceMessage request;
2927 request.SetType(STUN_BINDING_REQUEST);
2928 request.AddAttribute(
2929 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
2930 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
2931 request.AddAttribute(
2932 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002933 EXPECT_NE(prflx_priority, remote_priority);
2934
deadbeef14f97f52016-06-22 17:14:15 -07002935 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002936 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07002937 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
2938 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002939 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2940 ASSERT_TRUE(conn1 != nullptr);
2941 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
2942
2943 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07002944 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
2945 &request, kIceUfrag[1], false);
2946 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002947 ASSERT_TRUE(conn3 != nullptr);
2948 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
2949}
Peter Thatcher54360512015-07-08 11:08:35 -07002950
2951TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
deadbeef14f97f52016-06-22 17:14:15 -07002952 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2953 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07002954 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08002955 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07002956 // small.
2957 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002958 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002959 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Peter Thatcher54360512015-07-08 11:08:35 -07002960 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002961 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07002962 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002963 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2964 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Peter Thatcher54360512015-07-08 11:08:35 -07002965 ASSERT_TRUE(conn1 != nullptr);
2966
2967 conn1->ReceivedPing();
2968 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07002969 EXPECT_TRUE_WAIT(ch.selected_connection() != nullptr, 1000);
Peter Thatcher54360512015-07-08 11:08:35 -07002970 EXPECT_TRUE_WAIT(ch.receiving(), 1000);
2971 EXPECT_TRUE_WAIT(!ch.receiving(), 1000);
2972}
honghaiz5a3acd82015-08-20 15:53:17 -07002973
Honghai Zhang572b0942016-06-23 12:26:57 -07002974// The controlled side will select a connection as the "selected connection"
2975// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07002976// point the controlled side will select that connection as the
Honghai Zhang572b0942016-06-23 12:26:57 -07002977// "selected connection". Plus, SignalSelectedCandidatePair will be fired if the
2978// selected connection changes and SignalReadyToSend will be fired if the new
2979// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07002980TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07002981 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2982 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07002983 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07002984 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07002985 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002986 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2987 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07002988 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07002989 EXPECT_EQ(conn1, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07002990 EXPECT_EQ(conn1, last_selected_candidate_pair());
2991 EXPECT_EQ(-1, last_sent_packet_id());
2992 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07002993 EXPECT_FALSE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07002994
Honghai Zhang52dce732016-03-31 12:37:31 -07002995 int last_packet_id = 0;
2996 const char* data = "ABCDEFGH";
2997 int len = static_cast<int>(strlen(data));
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002998 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
honghaiz5a3acd82015-08-20 15:53:17 -07002999 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003000 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003001 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3002 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003003 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003004 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07003005 EXPECT_EQ(conn2, last_selected_candidate_pair());
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003006 EXPECT_EQ(-1, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003007 EXPECT_FALSE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003008
3009 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003010 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003011 // its priority is lower.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003012 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003013 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3014 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003015 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003016 // Because it has a lower priority, the selected connection is still conn2.
3017 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003018 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003019 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003020 // connection.
3021 conn3->set_nominated(true);
3022 conn3->SignalNominated(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003023 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07003024 EXPECT_EQ(conn3, last_selected_candidate_pair());
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003025 EXPECT_EQ(-1, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003026 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003027
Honghai Zhang572b0942016-06-23 12:26:57 -07003028 // Even if another higher priority candidate arrives, it will not be set as
3029 // the selected connection because the selected connection is nominated by
3030 // the controlling side.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003031 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003032 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3033 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003034 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003035 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003036 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003037 // the selected connection.
honghaiz5a3acd82015-08-20 15:53:17 -07003038 conn4->set_nominated(true);
3039 conn4->SignalNominated(conn4);
3040 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003041 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003042 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003043 // The selected connection switches after conn4 becomes writable.
zhihuang435264a2016-06-21 11:28:38 -07003044 conn4->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003045 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003046 EXPECT_EQ(conn4, last_selected_candidate_pair());
3047 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003048 // SignalReadyToSend is fired again because conn4 is writable.
3049 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003050}
3051
Honghai Zhang572b0942016-06-23 12:26:57 -07003052// The controlled side will select a connection as the "selected connection"
3053// based on requests from an unknown address before the controlling side
3054// nominates a connection, and will nominate a connection from an unknown
3055// address if the request contains the use_candidate attribute. Plus, it will
3056// also sends back a ping response and set the ICE pwd in the remote candidate
3057// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003058TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003059 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3060 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003061 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003062 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003063 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003064 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003065 IceMessage request;
3066 request.SetType(STUN_BINDING_REQUEST);
3067 request.AddAttribute(
3068 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3069 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3070 request.AddAttribute(
3071 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3072 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
3073 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3074 &request, kIceUfrag[1], false);
3075 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003076 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003077 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003078 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003079 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003080 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003081 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003082
3083 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003084 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3085 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003086 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003087 // Because it has a lower priority, the selected connection is still conn1.
3088 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003089 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003090 // selected connection.
zhihuang435264a2016-06-21 11:28:38 -07003091 conn2->ReceivedPingResponse(LOW_RTT); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003092 conn2->set_nominated(true);
3093 conn2->SignalNominated(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003094 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003095
Honghai Zhang572b0942016-06-23 12:26:57 -07003096 // Another request with unknown address, it will not be set as the selected
3097 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003098 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003099 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3100 &request, kIceUfrag[1], false);
3101 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003102 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003103 EXPECT_TRUE(port->sent_binding_response());
zhihuang435264a2016-06-21 11:28:38 -07003104 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003105 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003106 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003107
3108 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003109 // selected as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003110 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3111 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3112 &request, kIceUfrag[1], false);
3113 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003114 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003115 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003116 // conn4 is not the selected connection yet because it is not writable.
3117 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003118 conn4->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003119 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003120
3121 // Test that the request from an unknown address contains a ufrag from an old
3122 // generation.
3123 port->set_sent_binding_response(false);
3124 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
3125 ch.SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003126 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3127 &request, kIceUfrag[2], false);
3128 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003129 ASSERT_TRUE(conn5 != nullptr);
3130 EXPECT_TRUE(port->sent_binding_response());
3131 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003132}
3133
Honghai Zhang572b0942016-06-23 12:26:57 -07003134// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003135// based on media received until the controlling side nominates a connection,
3136// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003137// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003138TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003139 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3140 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003141 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003142 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003143 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003144 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3145 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003146 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003147 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003148
Honghai Zhang572b0942016-06-23 12:26:57 -07003149 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003150 // switch to conn2 because the controlled side must mirror the media path
3151 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003152 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3153 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003154 ASSERT_TRUE(conn2 != nullptr);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003155 conn2->ReceivedPing(); // Start receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003156 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003157 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003158 conn2->ReceivedPingResponse(LOW_RTT); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003159
3160 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003161 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003162 IceMessage request;
3163 request.SetType(STUN_BINDING_REQUEST);
honghaiz5a3acd82015-08-20 15:53:17 -07003164 request.AddAttribute(
deadbeef14f97f52016-06-22 17:14:15 -07003165 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3166 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3167 request.AddAttribute(
3168 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3169 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3170 Port* port = GetPort(&ch);
3171 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3172 &request, kIceUfrag[1], false);
3173 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003174 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003175 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
zhihuang435264a2016-06-21 11:28:38 -07003176 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003177 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003178
Honghai Zhang572b0942016-06-23 12:26:57 -07003179 // Now another data packet will not switch the selected connection because the
3180 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003181 conn2->ReceivedPing();
zhihuang435264a2016-06-21 11:28:38 -07003182 conn2->ReceivedPingResponse(LOW_RTT);
honghaiz5a3acd82015-08-20 15:53:17 -07003183 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003184 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3185}
3186
3187TEST_F(P2PTransportChannelPingTest,
3188 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3189 rtc::ScopedFakeClock clock;
3190
3191 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3192 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3193 PrepareChannel(&ch);
3194 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003195 ch.MaybeStartGathering();
3196 // The connections have decreasing priority.
3197 Connection* conn1 =
3198 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
3199 ASSERT_TRUE(conn1 != nullptr);
3200 Connection* conn2 =
3201 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
3202 ASSERT_TRUE(conn2 != nullptr);
3203
3204 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003205 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003206 EXPECT_EQ(conn1, last_selected_candidate_pair());
3207
3208 // conn2 receives data; it becomes selected.
3209 // Advance the clock by 1ms so that the last data receiving timestamp of
3210 // conn2 is larger.
3211 SIMULATED_WAIT(false, 1, clock);
3212 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003213 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003214 EXPECT_EQ(conn2, last_selected_candidate_pair());
3215
3216 // conn1 also receives data; it becomes selected due to priority again.
3217 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003218 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003219 EXPECT_EQ(conn1, last_selected_candidate_pair());
3220
3221 // Make sure sorting won't reselect candidate pair.
3222 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003223 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003224}
3225
3226TEST_F(P2PTransportChannelPingTest,
3227 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3228 rtc::ScopedFakeClock clock;
3229
3230 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3231 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3232 PrepareChannel(&ch);
3233 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003234 ch.MaybeStartGathering();
3235 // The connections have decreasing priority.
3236 Connection* conn1 =
3237 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3238 ASSERT_TRUE(conn1 != nullptr);
3239 Connection* conn2 =
3240 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3241 ASSERT_TRUE(conn2 != nullptr);
3242
3243 // conn1 received data; it is the selected connection.
3244 // Advance the clock to have a non-zero last-data-receiving time.
3245 SIMULATED_WAIT(false, 1, clock);
3246 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003247 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003248 EXPECT_EQ(conn1, last_selected_candidate_pair());
3249
3250 // conn2 is nominated; it becomes the selected connection.
3251 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003252 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003253 EXPECT_EQ(conn2, last_selected_candidate_pair());
3254
3255 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003256 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003257 EXPECT_EQ(conn1, last_selected_candidate_pair());
3258
3259 // conn2 received data more recently; it is selected now because it
3260 // received data more recently.
3261 SIMULATED_WAIT(false, 1, clock);
3262 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003263 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003264 EXPECT_EQ(conn2, last_selected_candidate_pair());
3265
3266 // Make sure sorting won't reselect candidate pair.
3267 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003268 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003269}
3270
3271TEST_F(P2PTransportChannelPingTest,
3272 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3273 rtc::ScopedFakeClock clock;
3274
3275 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3276 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3277 PrepareChannel(&ch);
3278 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003279 ch.MaybeStartGathering();
3280 // The connections have decreasing priority.
3281 Connection* conn1 =
3282 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3283 ASSERT_TRUE(conn1 != nullptr);
3284 Connection* conn2 =
3285 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3286 ASSERT_TRUE(conn2 != nullptr);
3287
3288 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003289 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003290
3291 // conn2 becomes writable; it is selected even though it is not nominated.
3292 conn2->ReceivedPingResponse(LOW_RTT);
3293
honghaiz9ad0db52016-07-14 19:30:28 -07003294 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003295 kDefaultTimeout, clock);
3296 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(),
3297 kDefaultTimeout, clock);
3298
3299 // If conn1 is also writable, it will become selected.
3300 conn1->ReceivedPingResponse(LOW_RTT);
honghaiz9ad0db52016-07-14 19:30:28 -07003301 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003302 kDefaultTimeout, clock);
3303 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3304 kDefaultTimeout, clock);
3305
3306 // Make sure sorting won't reselect candidate pair.
3307 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003308 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07003309}
honghaiz89374372015-09-24 13:14:47 -07003310
honghaiz36f50e82016-06-01 15:57:03 -07003311// Test that if a new remote candidate has the same address and port with
3312// an old one, it will be used to create a new connection.
3313TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07003314 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3315 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07003316 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07003317 ch.MaybeStartGathering();
3318 const std::string host_address = "1.1.1.1";
3319 const int port_num = 1;
3320
3321 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003322 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
3323 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07003324 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003325 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003326 ASSERT_TRUE(conn1 != nullptr);
3327 EXPECT_EQ(0u, conn1->remote_candidate().generation());
3328
3329 // Simply adding the same candidate again won't create a new connection.
3330 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003331 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003332 EXPECT_EQ(conn1, conn2);
3333
3334 // Update the ufrag of the candidate and add it again.
3335 candidate.set_username(kIceUfrag[2]);
3336 ch.AddRemoteCandidate(candidate);
3337 conn2 = GetConnectionTo(&ch, host_address, port_num);
3338 EXPECT_NE(conn1, conn2);
3339 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
3340 EXPECT_EQ(1u, conn2->remote_candidate().generation());
3341
3342 // Verify that a ping with the new ufrag can be received on the new
3343 // connection.
3344 EXPECT_EQ(0, conn2->last_ping_received());
3345 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
3346 EXPECT_TRUE(conn2->last_ping_received() > 0);
3347}
3348
Honghai Zhang572b0942016-06-23 12:26:57 -07003349// When the current selected connection is strong, lower-priority connections
3350// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07003351TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
deadbeef14f97f52016-06-22 17:14:15 -07003352 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3353 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07003354 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003355 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07003356 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003357 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3358 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07003359 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003360 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003361 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07003362
3363 // When a higher-priority, nominated candidate comes in, the connections with
3364 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07003365 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3366 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003367 ASSERT_TRUE(conn2 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003368 conn2->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07003369 conn2->set_nominated(true);
3370 conn2->SignalNominated(conn2);
3371 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
3372
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003373 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07003374 // Wait until conn2 becomes not receiving.
3375 EXPECT_TRUE_WAIT(!conn2->receiving(), 3000);
3376
deadbeef14f97f52016-06-22 17:14:15 -07003377 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3378 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz89374372015-09-24 13:14:47 -07003379 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003380 // The selected connection should still be conn2. Even through conn3 has lower
3381 // priority and is not receiving/writable, it is not pruned because the
3382 // selected connection is not receiving.
honghaiz89374372015-09-24 13:14:47 -07003383 WAIT(conn3->pruned(), 1000);
3384 EXPECT_FALSE(conn3->pruned());
3385}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003386
Honghai Zhang572b0942016-06-23 12:26:57 -07003387TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
3388 rtc::ScopedFakeClock clock;
3389 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3390 P2PTransportChannel ch("test channel", 1, &pa);
3391 PrepareChannel(&ch);
3392 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003393 ch.MaybeStartGathering();
3394 Connection* conn1 =
3395 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 100, true);
3396 ASSERT_TRUE(conn1 != nullptr);
3397 Connection* conn2 =
3398 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 200, false);
3399 ASSERT_TRUE(conn2 != nullptr);
3400 // Even if conn1 is writable, nominated, receiving data, it should not prune
3401 // conn2.
3402 NominateConnection(conn1);
3403 SIMULATED_WAIT(false, 1, clock);
3404 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3405 SIMULATED_WAIT(conn2->pruned(), 100, clock);
3406 EXPECT_FALSE(conn2->pruned());
3407}
3408
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003409// Test that GetState returns the state correctly.
3410TEST_F(P2PTransportChannelPingTest, TestGetState) {
deadbeef14f97f52016-06-22 17:14:15 -07003411 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3412 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003413 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003414 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003415 EXPECT_EQ(TransportChannelState::STATE_INIT, ch.GetState());
3416 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3417 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3418 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3419 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003420 ASSERT_TRUE(conn1 != nullptr);
3421 ASSERT_TRUE(conn2 != nullptr);
3422 // Now there are two connections, so the transport channel is connecting.
deadbeef14f97f52016-06-22 17:14:15 -07003423 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003424 // |conn1| becomes writable and receiving; it then should prune |conn2|.
zhihuang435264a2016-06-21 11:28:38 -07003425 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003426 EXPECT_TRUE_WAIT(conn2->pruned(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003427 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003428 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08003429 // Need to wait until the channel state is updated.
deadbeef14f97f52016-06-22 17:14:15 -07003430 EXPECT_EQ_WAIT(TransportChannelState::STATE_FAILED, ch.GetState(), 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003431}
3432
3433// Test that when a low-priority connection is pruned, it is not deleted
3434// right away, and it can become active and be pruned again.
3435TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
deadbeef14f97f52016-06-22 17:14:15 -07003436 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3437 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003438 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07003439 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
3440 config.receiving_switching_delay = rtc::Optional<int>(800);
3441 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003442 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003443 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3444 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003445 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003446 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003447 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003448
3449 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07003450 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003451 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07003452 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003453 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3454 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003455 ASSERT_TRUE(conn2 != nullptr);
3456 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
3457 // |conn2| should not send a ping yet.
deadbeef14f97f52016-06-22 17:14:15 -07003458 EXPECT_EQ(Connection::STATE_WAITING, conn2->state());
3459 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003460 // Wait for |conn1| becoming not receiving.
3461 EXPECT_TRUE_WAIT(!conn1->receiving(), 3000);
3462 // Make sure conn2 is not deleted.
3463 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3464 ASSERT_TRUE(conn2 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003465 EXPECT_EQ_WAIT(Connection::STATE_INPROGRESS, conn2->state(), 1000);
zhihuang435264a2016-06-21 11:28:38 -07003466 conn2->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003467 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003468 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003469
3470 // When |conn1| comes back again, |conn2| will be pruned again.
zhihuang435264a2016-06-21 11:28:38 -07003471 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003472 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003473 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003474 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003475}
honghaiz77d0d6e2015-10-27 11:34:45 -07003476
3477// Test that if all connections in a channel has timed out on writing, they
3478// will all be deleted. We use Prune to simulate write_time_out.
3479TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
deadbeef14f97f52016-06-22 17:14:15 -07003480 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3481 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07003482 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07003483 ch.MaybeStartGathering();
3484 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07003485 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3486 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz77d0d6e2015-10-27 11:34:45 -07003487 ASSERT_TRUE(conn1 != nullptr);
3488 conn1->ReceivedPing(); // Becomes receiving
3489 conn1->Prune();
3490 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3491
3492 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07003493 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3494 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz77d0d6e2015-10-27 11:34:45 -07003495 ASSERT_TRUE(conn2 != nullptr);
3496 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07003497 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
3498 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz77d0d6e2015-10-27 11:34:45 -07003499 ASSERT_TRUE(conn3 != nullptr);
3500 conn3->ReceivedPing(); // Becomes receiving
3501 // Now prune both conn2 and conn3; they will be deleted soon.
3502 conn2->Prune();
3503 conn3->Prune();
3504 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3505}
honghaiz9b669572015-11-04 12:07:44 -08003506
Honghai Zhang5a246372016-05-02 17:28:35 -07003507// Tests that after a port allocator session is started, it will be stopped
3508// when a new connection becomes writable and receiving. Also tests that if a
3509// connection belonging to an old session becomes writable, it won't stop
3510// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08003511TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07003512 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3513 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08003514 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003515 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08003516 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003517 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3518 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08003519 ASSERT_TRUE(conn1 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003520 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003521 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3522
Honghai Zhang5a246372016-05-02 17:28:35 -07003523 // Start a new session. Even though conn1, which belongs to an older
3524 // session, becomes unwritable and writable again, it should not stop the
3525 // current session.
honghaiz9b669572015-11-04 12:07:44 -08003526 ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]);
3527 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07003528 conn1->Prune();
zhihuang435264a2016-06-21 11:28:38 -07003529 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang5a246372016-05-02 17:28:35 -07003530 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
3531
3532 // But if a new connection created from the new session becomes writable,
3533 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07003534 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
3535 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08003536 ASSERT_TRUE(conn2 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003537 conn2->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003538 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3539}
guoweis36f01372016-03-02 18:02:40 -08003540
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003541// Test that the ICE role is updated even on ports that has been removed.
3542// These ports may still have connections that need a correct role, in case that
3543// the connections on it may still receive stun pings.
3544TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07003545 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3546 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003547 // Starts with ICEROLE_CONTROLLING.
3548 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003549 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07003550 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07003551 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003552 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003553
deadbeef14f97f52016-06-22 17:14:15 -07003554 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003555 ASSERT_TRUE(conn != nullptr);
3556
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003557 // Make a fake signal to remove the ports in the p2ptransportchannel. then
3558 // change the ICE role and expect it to be updated.
3559 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07003560 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07003561 ch.SetIceRole(ICEROLE_CONTROLLED);
3562 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003563}
3564
3565// Test that the ICE role is updated even on ports with inactive networks.
3566// These ports may still have connections that need a correct role, for the
3567// pings sent by those connections until they're replaced by newer-generation
3568// connections.
3569TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07003570 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3571 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003572 // Starts with ICEROLE_CONTROLLING.
3573 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07003574 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003575 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003576
deadbeef14f97f52016-06-22 17:14:15 -07003577 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003578 ASSERT_TRUE(conn != nullptr);
3579
3580 // Do an ICE restart, change the role, and expect the old port to have its
3581 // role updated.
3582 ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]);
3583 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003584 ch.SetIceRole(ICEROLE_CONTROLLED);
3585 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003586}
3587
3588// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07003589// will be destroyed. The port will only be destroyed after it is marked as
3590// "pruned."
3591TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07003592 rtc::ScopedFakeClock fake_clock;
3593
deadbeef14f97f52016-06-22 17:14:15 -07003594 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3595 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003596 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003597 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07003598 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003599 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003600
deadbeef14f97f52016-06-22 17:14:15 -07003601 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003602 ASSERT_TRUE(conn != nullptr);
3603
3604 // Simulate 2 minutes going by. This should be enough time for the port to
3605 // time out.
3606 for (int second = 0; second < 120; ++second) {
3607 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
3608 }
3609 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07003610 // Port will not be removed because it is not pruned yet.
3611 PortInterface* port = GetPort(&ch);
3612 ASSERT_NE(nullptr, port);
3613
3614 // If the session prunes all ports, the port will be destroyed.
3615 ch.allocator_session()->PruneAllPorts();
3616 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
3617 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07003618}
3619
guoweis36f01372016-03-02 18:02:40 -08003620class P2PTransportChannelMostLikelyToWorkFirstTest
3621 : public P2PTransportChannelPingTest {
3622 public:
3623 P2PTransportChannelMostLikelyToWorkFirstTest()
3624 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
3625 network_manager_.AddInterface(kPublicAddrs[0]);
deadbeef14f97f52016-06-22 17:14:15 -07003626 allocator_.reset(new BasicPortAllocator(
guoweis36f01372016-03-02 18:02:40 -08003627 &network_manager_, ServerAddresses(), rtc::SocketAddress(),
3628 rtc::SocketAddress(), rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07003629 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
3630 PORTALLOCATOR_DISABLE_TCP);
3631 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08003632 config.credentials = kRelayCredentials;
deadbeef14f97f52016-06-22 17:14:15 -07003633 config.ports.push_back(ProtocolAddress(kTurnUdpIntAddr, PROTO_UDP, false));
guoweis36f01372016-03-02 18:02:40 -08003634 allocator_->AddTurnServer(config);
3635 allocator_->set_step_delay(kMinimumStepDelay);
3636 }
3637
deadbeef14f97f52016-06-22 17:14:15 -07003638 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08003639 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07003640 int stable_writable_connection_ping_interval) {
deadbeef14f97f52016-06-22 17:14:15 -07003641 channel_.reset(new P2PTransportChannel("checks", 1, nullptr, allocator()));
3642 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08003643 config.prioritize_most_likely_candidate_pairs =
3644 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07003645 config.stable_writable_connection_ping_interval =
3646 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08003647 channel_->SetIceConfig(config);
3648 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08003649 channel_->MaybeStartGathering();
3650 return *channel_.get();
3651 }
3652
deadbeef14f97f52016-06-22 17:14:15 -07003653 BasicPortAllocator* allocator() { return allocator_.get(); }
3654 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08003655
3656 // This verifies the next pingable connection has the expected candidates'
3657 // types and, for relay local candidate, the expected relay protocol and ping
3658 // it.
3659 void VerifyNextPingableConnection(
3660 const std::string& local_candidate_type,
3661 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07003662 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
3663 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08003664 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07003665 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08003666 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
3667 }
3668 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
3669 }
3670
guoweis36f01372016-03-02 18:02:40 -08003671 private:
deadbeef14f97f52016-06-22 17:14:15 -07003672 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08003673 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07003674 TestTurnServer turn_server_;
3675 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08003676};
3677
3678// Test that Relay/Relay connections will be pinged first when no other
3679// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07003680// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08003681TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3682 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08003683 const int max_strong_interval = 100;
deadbeef14f97f52016-06-22 17:14:15 -07003684 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
guoweis36f01372016-03-02 18:02:40 -08003685 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003686 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3687 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003688
deadbeef14f97f52016-06-22 17:14:15 -07003689 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
3690 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003691
3692 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3693
3694 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07003695 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
3696 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
3697 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003698
3699 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07003700 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3701 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
3702 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003703 conn2->ReceivedPing();
3704 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3705
Honghai Zhang572b0942016-06-23 12:26:57 -07003706 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003707 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3708 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
3709 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
zhihuang435264a2016-06-21 11:28:38 -07003710 conn3->ReceivedPingResponse(LOW_RTT);
guoweis36f01372016-03-02 18:02:40 -08003711 ASSERT_TRUE(conn3->writable());
3712 conn3->ReceivedPing();
3713
honghaiz524ecc22016-05-25 12:48:31 -07003714 /*
3715
3716 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
3717 the flakiness. The following test becomes flaky because we now ping the
3718 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07003719 times. The selected connection may have been pinged before
3720 |max_strong_interval|, so it may not be the next connection to be pinged as
3721 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07003722
Honghai Zhang572b0942016-06-23 12:26:57 -07003723 // Verify that conn3 will be the "selected connection" since it is readable
3724 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08003725 // pingable connection.
Honghai Zhang572b0942016-06-23 12:26:57 -07003726 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), 5000);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003727 WAIT(false, max_strong_interval + 100);
zhihuang435264a2016-06-21 11:28:38 -07003728 conn3->ReceivedPingResponse(LOW_RTT);
guoweis36f01372016-03-02 18:02:40 -08003729 ASSERT_TRUE(conn3->writable());
3730 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07003731
3732 */
guoweis36f01372016-03-02 18:02:40 -08003733}
3734
3735// Test that Relay/Relay connections will be pinged first when everything has
3736// been pinged even if the Relay/Relay connection wasn't the first to be pinged
3737// in the first round.
3738TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3739 TestRelayRelayFirstWhenEverythingPinged) {
deadbeef14f97f52016-06-22 17:14:15 -07003740 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003741 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003742 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3743 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003744
deadbeef14f97f52016-06-22 17:14:15 -07003745 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003746 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
3747
3748 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003749 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
3750 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003751
3752 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003753 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003754 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3755
3756 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07003757 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003758
3759 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07003760 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003761
3762 // Now, every connection has been pinged once. The next one should be
3763 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003764 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003765}
3766
3767// Test that when we receive a new remote candidate, they will be tried first
3768// before we re-ping Relay/Relay connections again.
3769TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3770 TestNoStarvationOnNonRelayConnection) {
deadbeef14f97f52016-06-22 17:14:15 -07003771 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003772 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003773 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3774 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003775
deadbeef14f97f52016-06-22 17:14:15 -07003776 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003777 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
3778
3779 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07003780 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003781
3782 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003783 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003784
3785 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003786 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003787 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3788
3789 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07003790 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003791
3792 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07003793 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003794
3795 // Now, every connection has been pinged once. The next one should be
3796 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003797 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003798}
3799
3800// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
3801// followed by the rest.
3802TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
3803 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07003804 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
3805 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08003806 config.credentials = kRelayCredentials;
deadbeef14f97f52016-06-22 17:14:15 -07003807 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP, false));
guoweis36f01372016-03-02 18:02:40 -08003808 allocator()->AddTurnServer(config);
3809
deadbeef14f97f52016-06-22 17:14:15 -07003810 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003811 EXPECT_TRUE_WAIT(ch.ports().size() == 3, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003812 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3813 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
3814 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003815
3816 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003817 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003818 EXPECT_TRUE_WAIT(ch.connections().size() == 3, 5000);
3819
3820 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07003821 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003822
3823 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07003824 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
3825 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08003826
3827 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07003828 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003829}
deadbeef14f97f52016-06-22 17:14:15 -07003830
3831} // namespace cricket {