blob: c9600ddddd4a0b719f3f67a6086d1ce8b1d66b3d [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
deadbeef14f97f52016-06-22 17:14:15 -07002500 Connection* GetConnectionTo(P2PTransportChannel* ch,
2501 const std::string& ip,
2502 int port_num) {
2503 Port* port = GetPort(ch);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002504 if (!port) {
2505 return nullptr;
2506 }
2507 return port->GetConnection(rtc::SocketAddress(ip, port_num));
2508 }
2509
deadbeef14f97f52016-06-22 17:14:15 -07002510 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
2511 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08002512 if (conn) {
2513 ch->MarkConnectionPinged(conn);
2514 }
2515 return conn;
2516 }
2517
deadbeef14f97f52016-06-22 17:14:15 -07002518 int SendData(TransportChannel& channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07002519 const char* data,
2520 size_t len,
2521 int packet_id) {
2522 rtc::PacketOptions options;
2523 options.packet_id = packet_id;
2524 return channel.SendPacket(data, len, options, 0);
2525 }
2526
Honghai Zhang572b0942016-06-23 12:26:57 -07002527 Connection* CreateConnectionWithCandidate(P2PTransportChannel& channel,
2528 rtc::ScopedFakeClock& clock,
2529 const std::string& ip_addr,
2530 int port,
2531 int priority,
2532 bool writable) {
2533 channel.AddRemoteCandidate(
2534 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
2535 EXPECT_TRUE_SIMULATED_WAIT(
2536 GetConnectionTo(&channel, ip_addr, port) != nullptr, 3000, clock);
2537 Connection* conn = GetConnectionTo(&channel, ip_addr, port);
2538
2539 if (conn && writable) {
2540 conn->ReceivedPingResponse(LOW_RTT); // make it writable
2541 }
2542 return conn;
2543 }
2544
2545 void NominateConnection(Connection* conn) {
2546 conn->set_nominated(true);
2547 conn->SignalNominated(conn);
2548 }
2549
Honghai Zhang52dce732016-03-31 12:37:31 -07002550 void OnSelectedCandidatePairChanged(
deadbeef14f97f52016-06-22 17:14:15 -07002551 TransportChannel* transport_channel,
2552 CandidatePairInterface* selected_candidate_pair,
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002553 int last_sent_packet_id,
2554 bool ready_to_send) {
Honghai Zhang52dce732016-03-31 12:37:31 -07002555 last_selected_candidate_pair_ = selected_candidate_pair;
2556 last_sent_packet_id_ = last_sent_packet_id;
Honghai Zhang572b0942016-06-23 12:26:57 -07002557 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07002558 }
2559
deadbeef14f97f52016-06-22 17:14:15 -07002560 void ReceivePingOnConnection(Connection* conn,
honghaiz36f50e82016-06-01 15:57:03 -07002561 const std::string& remote_ufrag,
2562 int priority) {
deadbeef14f97f52016-06-22 17:14:15 -07002563 IceMessage msg;
2564 msg.SetType(STUN_BINDING_REQUEST);
2565 msg.AddAttribute(new StunByteStringAttribute(
2566 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07002567 conn->local_candidate().username() + ":" + remote_ufrag));
deadbeef14f97f52016-06-22 17:14:15 -07002568 msg.AddAttribute(new StunUInt32Attribute(STUN_ATTR_PRIORITY, priority));
2569 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07002570 msg.AddMessageIntegrity(conn->local_candidate().password());
2571 msg.AddFingerprint();
2572 rtc::ByteBufferWriter buf;
2573 msg.Write(&buf);
2574 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
2575 }
2576
deadbeef14f97f52016-06-22 17:14:15 -07002577 void OnReadyToSend(TransportChannel* channel) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07002578 channel_ready_to_send_ = true;
2579 }
deadbeef14f97f52016-06-22 17:14:15 -07002580 void OnChannelStateChanged(TransportChannelImpl* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07002581 channel_state_ = channel->GetState();
2582 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002583
deadbeef14f97f52016-06-22 17:14:15 -07002584 CandidatePairInterface* last_selected_candidate_pair() {
Honghai Zhang52dce732016-03-31 12:37:31 -07002585 return last_selected_candidate_pair_;
2586 }
2587 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002588 bool channel_ready_to_send() { return channel_ready_to_send_; }
2589 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
deadbeef14f97f52016-06-22 17:14:15 -07002590 TransportChannelState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07002591 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07002592 int switches = selected_candidate_pair_switches_;
2593 selected_candidate_pair_switches_ = 0;
2594 return switches;
2595 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07002596
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002597 private:
kwiberg3ec46792016-04-27 07:22:53 -07002598 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
2599 std::unique_ptr<rtc::VirtualSocketServer> vss_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002600 rtc::SocketServerScope ss_scope_;
deadbeef14f97f52016-06-22 17:14:15 -07002601 CandidatePairInterface* last_selected_candidate_pair_ = nullptr;
Honghai Zhang572b0942016-06-23 12:26:57 -07002602 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07002603 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07002604 bool channel_ready_to_send_ = false;
deadbeef14f97f52016-06-22 17:14:15 -07002605 TransportChannelState channel_state_ = STATE_INIT;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002606};
2607
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002608TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07002609 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2610 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002611 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002612 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002613 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2614 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002615
deadbeef14f97f52016-06-22 17:14:15 -07002616 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2617 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002618 ASSERT_TRUE(conn1 != nullptr);
2619 ASSERT_TRUE(conn2 != nullptr);
2620
2621 // Before a triggered check, the first connection to ping is the
2622 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08002623 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002624
2625 // Receiving a ping causes a triggered check which should make conn1
2626 // be pinged first instead of conn2, even though conn2 has a higher
2627 // priority.
2628 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08002629 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002630}
2631
honghaiz524ecc22016-05-25 12:48:31 -07002632TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07002633 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2634 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07002635 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07002636 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002637 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2638 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07002639
deadbeef14f97f52016-06-22 17:14:15 -07002640 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2641 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07002642 ASSERT_TRUE(conn1 != nullptr);
2643 ASSERT_TRUE(conn2 != nullptr);
2644
2645 // Low-priority connection becomes writable so that the other connection
2646 // is not pruned.
zhihuang435264a2016-06-21 11:28:38 -07002647 conn1->ReceivedPingResponse(LOW_RTT);
honghaiz524ecc22016-05-25 12:48:31 -07002648 EXPECT_TRUE_WAIT(
2649 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
2650 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
2651 kDefaultTimeout);
2652}
2653
zhihuang435264a2016-06-21 11:28:38 -07002654// Verify that the connections are pinged at the right time.
2655TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
2656 rtc::ScopedFakeClock clock;
2657 int RTT_RATIO = 4;
2658 int SCHEDULING_RANGE = 200;
2659 int RTT_RANGE = 10;
2660
deadbeef14f97f52016-06-22 17:14:15 -07002661 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2662 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07002663 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07002664 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002665 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2666 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07002667
2668 ASSERT_TRUE(conn != nullptr);
2669 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
2670
2671 // Initializing.
2672
2673 int64_t start = clock.TimeNanos();
2674 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
2675 kDefaultTimeout, clock);
2676 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
2677 rtc::kNumNanosecsPerMillisec /
2678 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07002679 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002680
2681 // Stabilizing.
2682
2683 conn->ReceivedPingResponse(LOW_RTT);
2684 int ping_sent_before = conn->num_pings_sent();
2685 start = clock.TimeNanos();
2686 // The connection becomes strong but not stable because we haven't been able
2687 // to converge the RTT.
2688 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2689 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002690 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002691 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07002692 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002693
2694 // Stabilized.
2695
2696 // The connection becomes stable after receiving more than RTT_RATIO rtt
2697 // samples.
2698 for (int i = 0; i < RTT_RATIO; i++) {
2699 conn->ReceivedPingResponse(LOW_RTT);
2700 }
2701 ping_sent_before = conn->num_pings_sent();
2702 start = clock.TimeNanos();
2703 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2704 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002705 EXPECT_GE(ping_interval_ms, STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
2706 EXPECT_LE(ping_interval_ms,
2707 STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002708
2709 // Destabilized.
2710
2711 conn->ReceivedPingResponse(LOW_RTT);
2712 // Create a in-flight ping.
2713 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
2714 start = clock.TimeNanos();
2715 // In-flight ping timeout and the connection will be unstable.
2716 SIMULATED_WAIT(
2717 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec), 3000,
2718 clock);
2719 int64_t duration_ms =
2720 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
2721 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
2722 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
2723 // The connection become unstable due to not receiving ping responses.
2724 ping_sent_before = conn->num_pings_sent();
2725 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2726 // The interval is expected to be
2727 // STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
2728 start = clock.TimeNanos();
2729 ping_sent_before = conn->num_pings_sent();
2730 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, 3000, clock);
2731 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
deadbeef14f97f52016-06-22 17:14:15 -07002732 EXPECT_GE(ping_interval_ms, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07002733 EXPECT_LE(ping_interval_ms,
deadbeef14f97f52016-06-22 17:14:15 -07002734 STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07002735}
2736
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002737// Test that we start pinging as soon as we have a connection and remote ICE
2738// credentials.
2739TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
2740 rtc::ScopedFakeClock clock;
2741
2742 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2743 P2PTransportChannel ch("TestChannel", 1, &pa);
2744 ch.SetIceRole(ICEROLE_CONTROLLING);
2745 ch.SetIceCredentials(kIceUfrag[0], kIcePwd[0]);
2746 ch.MaybeStartGathering();
2747 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
2748 kDefaultTimeout);
2749
2750 // Simulate a binding request being received, creating a peer reflexive
2751 // candidate pair while we still don't have remote ICE credentials.
2752 IceMessage request;
2753 request.SetType(STUN_BINDING_REQUEST);
2754 request.AddAttribute(
2755 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
2756 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
2757 request.AddAttribute(
2758 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
2759 Port* port = GetPort(&ch);
2760 ASSERT_NE(nullptr, port);
2761 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
2762 &request, kIceUfrag[1], false);
2763 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
2764 ASSERT_NE(nullptr, conn);
2765
2766 // Simulate waiting for a second (and change) and verify that no pings were
2767 // sent, since we don't yet have remote ICE credentials.
2768 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
2769 EXPECT_EQ(0, conn->num_pings_sent());
2770
2771 // Set remote ICE credentials. Now we should be able to ping. Ensure that
2772 // the first ping is sent as soon as possible, within one simulated clock
2773 // tick.
2774 ch.SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
2775 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
2776}
2777
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002778TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07002779 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2780 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002781 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002782 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002783 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2784 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002785
deadbeef14f97f52016-06-22 17:14:15 -07002786 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2787 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002788 ASSERT_TRUE(conn1 != nullptr);
2789 ASSERT_TRUE(conn2 != nullptr);
2790
guoweis36f01372016-03-02 18:02:40 -08002791 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
2792 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
zhihuang435264a2016-06-21 11:28:38 -07002793 conn1->ReceivedPingResponse(LOW_RTT);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002794 ASSERT_TRUE(conn1->writable());
2795 conn1->ReceivedPing();
2796
2797 // Ping received, but the connection is already writable, so no
2798 // "triggered check" and conn2 is pinged before conn1 because it has
2799 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08002800 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07002801}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002802
honghaiz079a7a12016-06-22 16:26:29 -07002803TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07002804 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2805 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07002806 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07002807 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002808 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07002809
deadbeef14f97f52016-06-22 17:14:15 -07002810 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07002811 ASSERT_TRUE(conn1 != nullptr);
2812
2813 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
2814 conn1->Prune(); // A pruned connection may still be pingable.
2815 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
2816 conn1->FailAndPrune();
2817 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
2818}
2819
Honghai Zhang1590c392016-05-24 13:15:02 -07002820TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07002821 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2822 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07002823 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07002824 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002825 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2826 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07002827 ASSERT_TRUE(conn1 != nullptr);
2828 // Pruning the connection reduces the set of active connections and changes
2829 // the channel state.
2830 conn1->Prune();
deadbeef14f97f52016-06-22 17:14:15 -07002831 EXPECT_EQ_WAIT(STATE_FAILED, channel_state(), kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07002832}
2833
honghaiza54a0802015-12-16 18:37:23 -08002834// Test adding remote candidates with different ufrags. If a remote candidate
2835// is added with an old ufrag, it will be discarded. If it is added with a
2836// ufrag that was not seen before, it will be used to create connections
2837// although the ICE pwd in the remote candidate will be set when the ICE
2838// credentials arrive. If a remote candidate is added with the current ICE
2839// ufrag, its pwd and generation will be set properly.
2840TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07002841 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2842 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08002843 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08002844 ch.MaybeStartGathering();
2845 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07002846 ch.AddRemoteCandidate(
2847 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
2848 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08002849 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002850 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08002851 EXPECT_EQ(kIceUfrag[2], candidate.username());
2852 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08002853 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08002854
2855 // Set the remote credentials with the "future" ufrag.
2856 // This should set the ICE pwd in the remote candidate of |conn1|, making
2857 // it pingable.
2858 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
2859 EXPECT_EQ(kIceUfrag[2], candidate.username());
2860 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08002861 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08002862
2863 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07002864 ch.AddRemoteCandidate(
2865 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08002866 rtc::Thread::Current()->ProcessMessages(500);
2867 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
2868
2869 // Add a candidate with the current ufrag, its pwd and generation will be
2870 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07002871 ch.AddRemoteCandidate(
2872 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
2873 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08002874 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
2875 3000);
deadbeef14f97f52016-06-22 17:14:15 -07002876 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08002877 EXPECT_EQ(kIcePwd[2], new_candidate.password());
2878 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08002879
2880 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07002881 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08002882 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
2883 candidate.username() == kIceUfrag[2]);
2884 if (candidate.username() == kIceUfrag[1]) {
2885 EXPECT_EQ(kIcePwd[1], candidate.password());
2886 } else if (candidate.username() == kIceUfrag[2]) {
2887 EXPECT_EQ(kIcePwd[2], candidate.password());
2888 }
2889 }
honghaiza54a0802015-12-16 18:37:23 -08002890}
2891
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002892TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07002893 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2894 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002895 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07002896 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002897
2898 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07002899 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2900 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002901 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02002902 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002903
2904 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07002905 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07002906 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
2907 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002908 ASSERT_TRUE(conn2 != nullptr);
2909 conn2->ReceivedPing();
zhihuang435264a2016-06-21 11:28:38 -07002910 conn2->ReceivedPingResponse(LOW_RTT);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002911
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002912 // Wait for conn1 to be pruned.
2913 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
2914 // Destroy the connection to test SignalUnknownAddress.
2915 conn1->Destroy();
2916 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr, 1000);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002917
2918 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07002919 IceMessage request;
2920 request.SetType(STUN_BINDING_REQUEST);
2921 request.AddAttribute(
2922 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
2923 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
2924 request.AddAttribute(
2925 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002926 EXPECT_NE(prflx_priority, remote_priority);
2927
deadbeef14f97f52016-06-22 17:14:15 -07002928 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002929 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07002930 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
2931 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002932 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
2933 ASSERT_TRUE(conn1 != nullptr);
2934 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
2935
2936 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07002937 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
2938 &request, kIceUfrag[1], false);
2939 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07002940 ASSERT_TRUE(conn3 != nullptr);
2941 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
2942}
Peter Thatcher54360512015-07-08 11:08:35 -07002943
2944TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
deadbeef14f97f52016-06-22 17:14:15 -07002945 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2946 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07002947 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08002948 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07002949 // small.
2950 EXPECT_LE(1000, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002951 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002952 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Peter Thatcher54360512015-07-08 11:08:35 -07002953 EXPECT_EQ(500, ch.receiving_timeout());
Honghai Zhang049fbb12016-03-07 11:13:07 -08002954 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07002955 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002956 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2957 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Peter Thatcher54360512015-07-08 11:08:35 -07002958 ASSERT_TRUE(conn1 != nullptr);
2959
2960 conn1->ReceivedPing();
2961 conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07002962 EXPECT_TRUE_WAIT(ch.selected_connection() != nullptr, 1000);
Peter Thatcher54360512015-07-08 11:08:35 -07002963 EXPECT_TRUE_WAIT(ch.receiving(), 1000);
2964 EXPECT_TRUE_WAIT(!ch.receiving(), 1000);
2965}
honghaiz5a3acd82015-08-20 15:53:17 -07002966
Honghai Zhang572b0942016-06-23 12:26:57 -07002967// The controlled side will select a connection as the "selected connection"
2968// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07002969// point the controlled side will select that connection as the
Honghai Zhang572b0942016-06-23 12:26:57 -07002970// "selected connection". Plus, SignalSelectedCandidatePair will be fired if the
2971// selected connection changes and SignalReadyToSend will be fired if the new
2972// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07002973TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07002974 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
2975 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07002976 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07002977 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07002978 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07002979 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
2980 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07002981 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07002982 EXPECT_EQ(conn1, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07002983 EXPECT_EQ(conn1, last_selected_candidate_pair());
2984 EXPECT_EQ(-1, last_sent_packet_id());
2985 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07002986 EXPECT_FALSE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07002987
Honghai Zhang52dce732016-03-31 12:37:31 -07002988 int last_packet_id = 0;
2989 const char* data = "ABCDEFGH";
2990 int len = static_cast<int>(strlen(data));
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002991 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
honghaiz5a3acd82015-08-20 15:53:17 -07002992 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07002993 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07002994 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
2995 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07002996 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07002997 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07002998 EXPECT_EQ(conn2, last_selected_candidate_pair());
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002999 EXPECT_EQ(-1, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003000 EXPECT_FALSE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003001
3002 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003003 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003004 // its priority is lower.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003005 EXPECT_EQ(-1, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003006 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3007 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003008 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003009 // Because it has a lower priority, the selected connection is still conn2.
3010 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003011 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003012 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003013 // connection.
3014 conn3->set_nominated(true);
3015 conn3->SignalNominated(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003016 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang52dce732016-03-31 12:37:31 -07003017 EXPECT_EQ(conn3, last_selected_candidate_pair());
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003018 EXPECT_EQ(-1, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003019 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003020
Honghai Zhang572b0942016-06-23 12:26:57 -07003021 // Even if another higher priority candidate arrives, it will not be set as
3022 // the selected connection because the selected connection is nominated by
3023 // the controlling side.
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07003024 EXPECT_EQ(len, SendData(ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003025 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3026 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003027 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003028 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003029 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003030 // the selected connection.
honghaiz5a3acd82015-08-20 15:53:17 -07003031 conn4->set_nominated(true);
3032 conn4->SignalNominated(conn4);
3033 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003034 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003035 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003036 // The selected connection switches after conn4 becomes writable.
zhihuang435264a2016-06-21 11:28:38 -07003037 conn4->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003038 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Honghai Zhang52dce732016-03-31 12:37:31 -07003039 EXPECT_EQ(conn4, last_selected_candidate_pair());
3040 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003041 // SignalReadyToSend is fired again because conn4 is writable.
3042 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003043}
3044
Honghai Zhang572b0942016-06-23 12:26:57 -07003045// The controlled side will select a connection as the "selected connection"
3046// based on requests from an unknown address before the controlling side
3047// nominates a connection, and will nominate a connection from an unknown
3048// address if the request contains the use_candidate attribute. Plus, it will
3049// also sends back a ping response and set the ICE pwd in the remote candidate
3050// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003051TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003052 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3053 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003054 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003055 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003056 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003057 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003058 IceMessage request;
3059 request.SetType(STUN_BINDING_REQUEST);
3060 request.AddAttribute(
3061 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3062 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3063 request.AddAttribute(
3064 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3065 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
3066 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3067 &request, kIceUfrag[1], false);
3068 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003069 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003070 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003071 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003072 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003073 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003074 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003075
3076 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003077 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3078 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003079 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003080 // Because it has a lower priority, the selected connection is still conn1.
3081 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003082 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003083 // selected connection.
zhihuang435264a2016-06-21 11:28:38 -07003084 conn2->ReceivedPingResponse(LOW_RTT); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003085 conn2->set_nominated(true);
3086 conn2->SignalNominated(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003087 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003088
Honghai Zhang572b0942016-06-23 12:26:57 -07003089 // Another request with unknown address, it will not be set as the selected
3090 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003091 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003092 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3093 &request, kIceUfrag[1], false);
3094 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003095 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003096 EXPECT_TRUE(port->sent_binding_response());
zhihuang435264a2016-06-21 11:28:38 -07003097 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003098 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003099 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003100
3101 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003102 // selected as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003103 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3104 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3105 &request, kIceUfrag[1], false);
3106 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003107 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003108 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003109 // conn4 is not the selected connection yet because it is not writable.
3110 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003111 conn4->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003112 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003113
3114 // Test that the request from an unknown address contains a ufrag from an old
3115 // generation.
3116 port->set_sent_binding_response(false);
3117 ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
3118 ch.SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003119 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3120 &request, kIceUfrag[2], false);
3121 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003122 ASSERT_TRUE(conn5 != nullptr);
3123 EXPECT_TRUE(port->sent_binding_response());
3124 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003125}
3126
Honghai Zhang572b0942016-06-23 12:26:57 -07003127// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003128// based on media received until the controlling side nominates a connection,
3129// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003130// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003131TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003132 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3133 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003134 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003135 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003136 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003137 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3138 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003139 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003140 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003141
Honghai Zhang572b0942016-06-23 12:26:57 -07003142 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003143 // switch to conn2 because the controlled side must mirror the media path
3144 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003145 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3146 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003147 ASSERT_TRUE(conn2 != nullptr);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003148 conn2->ReceivedPing(); // Start receiving.
honghaiz5a3acd82015-08-20 15:53:17 -07003149 conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003150 EXPECT_EQ(conn2, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003151 conn2->ReceivedPingResponse(LOW_RTT); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003152
3153 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003154 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003155 IceMessage request;
3156 request.SetType(STUN_BINDING_REQUEST);
honghaiz5a3acd82015-08-20 15:53:17 -07003157 request.AddAttribute(
deadbeef14f97f52016-06-22 17:14:15 -07003158 new StunByteStringAttribute(STUN_ATTR_USERNAME, kIceUfrag[1]));
3159 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
3160 request.AddAttribute(
3161 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
3162 request.AddAttribute(new StunByteStringAttribute(STUN_ATTR_USE_CANDIDATE));
3163 Port* port = GetPort(&ch);
3164 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3165 &request, kIceUfrag[1], false);
3166 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003167 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003168 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
zhihuang435264a2016-06-21 11:28:38 -07003169 conn3->ReceivedPingResponse(LOW_RTT); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003170 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003171
Honghai Zhang572b0942016-06-23 12:26:57 -07003172 // Now another data packet will not switch the selected connection because the
3173 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003174 conn2->ReceivedPing();
zhihuang435264a2016-06-21 11:28:38 -07003175 conn2->ReceivedPingResponse(LOW_RTT);
honghaiz5a3acd82015-08-20 15:53:17 -07003176 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
Honghai Zhang572b0942016-06-23 12:26:57 -07003177 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3178}
3179
3180TEST_F(P2PTransportChannelPingTest,
3181 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3182 rtc::ScopedFakeClock clock;
3183
3184 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3185 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3186 PrepareChannel(&ch);
3187 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003188 ch.MaybeStartGathering();
3189 // The connections have decreasing priority.
3190 Connection* conn1 =
3191 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
3192 ASSERT_TRUE(conn1 != nullptr);
3193 Connection* conn2 =
3194 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
3195 ASSERT_TRUE(conn2 != nullptr);
3196
3197 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003198 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003199 EXPECT_EQ(conn1, last_selected_candidate_pair());
3200
3201 // conn2 receives data; it becomes selected.
3202 // Advance the clock by 1ms so that the last data receiving timestamp of
3203 // conn2 is larger.
3204 SIMULATED_WAIT(false, 1, clock);
3205 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003206 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003207 EXPECT_EQ(conn2, last_selected_candidate_pair());
3208
3209 // conn1 also receives data; it becomes selected due to priority again.
3210 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003211 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003212 EXPECT_EQ(conn1, last_selected_candidate_pair());
3213
3214 // Make sure sorting won't reselect candidate pair.
3215 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003216 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003217}
3218
3219TEST_F(P2PTransportChannelPingTest,
3220 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3221 rtc::ScopedFakeClock clock;
3222
3223 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3224 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3225 PrepareChannel(&ch);
3226 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003227 ch.MaybeStartGathering();
3228 // The connections have decreasing priority.
3229 Connection* conn1 =
3230 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3231 ASSERT_TRUE(conn1 != nullptr);
3232 Connection* conn2 =
3233 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3234 ASSERT_TRUE(conn2 != nullptr);
3235
3236 // conn1 received data; it is the selected connection.
3237 // Advance the clock to have a non-zero last-data-receiving time.
3238 SIMULATED_WAIT(false, 1, clock);
3239 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
honghaiz9ad0db52016-07-14 19:30:28 -07003240 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003241 EXPECT_EQ(conn1, last_selected_candidate_pair());
3242
3243 // conn2 is nominated; it becomes the selected connection.
3244 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003245 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003246 EXPECT_EQ(conn2, last_selected_candidate_pair());
3247
3248 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003249 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003250 EXPECT_EQ(conn1, last_selected_candidate_pair());
3251
3252 // conn2 received data more recently; it is selected now because it
3253 // received data more recently.
3254 SIMULATED_WAIT(false, 1, clock);
3255 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
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(conn2, last_selected_candidate_pair());
3258
3259 // Make sure sorting won't reselect candidate pair.
3260 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003261 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003262}
3263
3264TEST_F(P2PTransportChannelPingTest,
3265 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3266 rtc::ScopedFakeClock clock;
3267
3268 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3269 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3270 PrepareChannel(&ch);
3271 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003272 ch.MaybeStartGathering();
3273 // The connections have decreasing priority.
3274 Connection* conn1 =
3275 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3276 ASSERT_TRUE(conn1 != nullptr);
3277 Connection* conn2 =
3278 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3279 ASSERT_TRUE(conn2 != nullptr);
3280
3281 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003282 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003283
3284 // conn2 becomes writable; it is selected even though it is not nominated.
3285 conn2->ReceivedPingResponse(LOW_RTT);
3286
honghaiz9ad0db52016-07-14 19:30:28 -07003287 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07003288 kDefaultTimeout, clock);
3289 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(),
3290 kDefaultTimeout, clock);
3291
3292 // If conn1 is also writable, it will become selected.
3293 conn1->ReceivedPingResponse(LOW_RTT);
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(conn1, last_selected_candidate_pair(),
3297 kDefaultTimeout, clock);
3298
3299 // Make sure sorting won't reselect candidate pair.
3300 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003301 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07003302}
honghaiz89374372015-09-24 13:14:47 -07003303
honghaiz36f50e82016-06-01 15:57:03 -07003304// Test that if a new remote candidate has the same address and port with
3305// an old one, it will be used to create a new connection.
3306TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07003307 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3308 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07003309 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07003310 ch.MaybeStartGathering();
3311 const std::string host_address = "1.1.1.1";
3312 const int port_num = 1;
3313
3314 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003315 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
3316 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07003317 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003318 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003319 ASSERT_TRUE(conn1 != nullptr);
3320 EXPECT_EQ(0u, conn1->remote_candidate().generation());
3321
3322 // Simply adding the same candidate again won't create a new connection.
3323 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07003324 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07003325 EXPECT_EQ(conn1, conn2);
3326
3327 // Update the ufrag of the candidate and add it again.
3328 candidate.set_username(kIceUfrag[2]);
3329 ch.AddRemoteCandidate(candidate);
3330 conn2 = GetConnectionTo(&ch, host_address, port_num);
3331 EXPECT_NE(conn1, conn2);
3332 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
3333 EXPECT_EQ(1u, conn2->remote_candidate().generation());
3334
3335 // Verify that a ping with the new ufrag can be received on the new
3336 // connection.
3337 EXPECT_EQ(0, conn2->last_ping_received());
3338 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
3339 EXPECT_TRUE(conn2->last_ping_received() > 0);
3340}
3341
Honghai Zhang572b0942016-06-23 12:26:57 -07003342// When the current selected connection is strong, lower-priority connections
3343// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07003344TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
deadbeef14f97f52016-06-22 17:14:15 -07003345 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3346 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07003347 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003348 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07003349 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003350 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3351 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07003352 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003353 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003354 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07003355
3356 // When a higher-priority, nominated candidate comes in, the connections with
3357 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07003358 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3359 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003360 ASSERT_TRUE(conn2 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003361 conn2->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07003362 conn2->set_nominated(true);
3363 conn2->SignalNominated(conn2);
3364 EXPECT_TRUE_WAIT(conn1->pruned(), 3000);
3365
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003366 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07003367 // Wait until conn2 becomes not receiving.
3368 EXPECT_TRUE_WAIT(!conn2->receiving(), 3000);
3369
deadbeef14f97f52016-06-22 17:14:15 -07003370 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3371 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz89374372015-09-24 13:14:47 -07003372 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003373 // The selected connection should still be conn2. Even through conn3 has lower
3374 // priority and is not receiving/writable, it is not pruned because the
3375 // selected connection is not receiving.
honghaiz89374372015-09-24 13:14:47 -07003376 WAIT(conn3->pruned(), 1000);
3377 EXPECT_FALSE(conn3->pruned());
3378}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003379
Honghai Zhang572b0942016-06-23 12:26:57 -07003380TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
3381 rtc::ScopedFakeClock clock;
3382 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3383 P2PTransportChannel ch("test channel", 1, &pa);
3384 PrepareChannel(&ch);
3385 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003386 ch.MaybeStartGathering();
3387 Connection* conn1 =
3388 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 100, true);
3389 ASSERT_TRUE(conn1 != nullptr);
3390 Connection* conn2 =
3391 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 200, false);
3392 ASSERT_TRUE(conn2 != nullptr);
3393 // Even if conn1 is writable, nominated, receiving data, it should not prune
3394 // conn2.
3395 NominateConnection(conn1);
3396 SIMULATED_WAIT(false, 1, clock);
3397 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3398 SIMULATED_WAIT(conn2->pruned(), 100, clock);
3399 EXPECT_FALSE(conn2->pruned());
3400}
3401
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003402// Test that GetState returns the state correctly.
3403TEST_F(P2PTransportChannelPingTest, TestGetState) {
deadbeef14f97f52016-06-22 17:14:15 -07003404 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3405 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003406 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003407 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003408 EXPECT_EQ(TransportChannelState::STATE_INIT, ch.GetState());
3409 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3410 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3411 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3412 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003413 ASSERT_TRUE(conn1 != nullptr);
3414 ASSERT_TRUE(conn2 != nullptr);
3415 // Now there are two connections, so the transport channel is connecting.
deadbeef14f97f52016-06-22 17:14:15 -07003416 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003417 // |conn1| becomes writable and receiving; it then should prune |conn2|.
zhihuang435264a2016-06-21 11:28:38 -07003418 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003419 EXPECT_TRUE_WAIT(conn2->pruned(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003420 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003421 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08003422 // Need to wait until the channel state is updated.
deadbeef14f97f52016-06-22 17:14:15 -07003423 EXPECT_EQ_WAIT(TransportChannelState::STATE_FAILED, ch.GetState(), 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003424}
3425
3426// Test that when a low-priority connection is pruned, it is not deleted
3427// right away, and it can become active and be pruned again.
3428TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
deadbeef14f97f52016-06-22 17:14:15 -07003429 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3430 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003431 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07003432 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
3433 config.receiving_switching_delay = rtc::Optional<int>(800);
3434 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003435 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003436 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3437 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003438 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003439 EXPECT_EQ(conn1, ch.selected_connection());
zhihuang435264a2016-06-21 11:28:38 -07003440 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003441
3442 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07003443 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003444 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07003445 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003446 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3447 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003448 ASSERT_TRUE(conn2 != nullptr);
3449 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
3450 // |conn2| should not send a ping yet.
deadbeef14f97f52016-06-22 17:14:15 -07003451 EXPECT_EQ(Connection::STATE_WAITING, conn2->state());
3452 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003453 // Wait for |conn1| becoming not receiving.
3454 EXPECT_TRUE_WAIT(!conn1->receiving(), 3000);
3455 // Make sure conn2 is not deleted.
3456 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3457 ASSERT_TRUE(conn2 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003458 EXPECT_EQ_WAIT(Connection::STATE_INPROGRESS, conn2->state(), 1000);
zhihuang435264a2016-06-21 11:28:38 -07003459 conn2->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003460 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003461 EXPECT_EQ(TransportChannelState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003462
3463 // When |conn1| comes back again, |conn2| will be pruned again.
zhihuang435264a2016-06-21 11:28:38 -07003464 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang572b0942016-06-23 12:26:57 -07003465 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), 1000);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003466 EXPECT_TRUE_WAIT(!conn2->active(), 1000);
deadbeef14f97f52016-06-22 17:14:15 -07003467 EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003468}
honghaiz77d0d6e2015-10-27 11:34:45 -07003469
3470// Test that if all connections in a channel has timed out on writing, they
3471// will all be deleted. We use Prune to simulate write_time_out.
3472TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
deadbeef14f97f52016-06-22 17:14:15 -07003473 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3474 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07003475 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07003476 ch.MaybeStartGathering();
3477 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07003478 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3479 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz77d0d6e2015-10-27 11:34:45 -07003480 ASSERT_TRUE(conn1 != nullptr);
3481 conn1->ReceivedPing(); // Becomes receiving
3482 conn1->Prune();
3483 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3484
3485 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07003486 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3487 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz77d0d6e2015-10-27 11:34:45 -07003488 ASSERT_TRUE(conn2 != nullptr);
3489 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07003490 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
3491 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz77d0d6e2015-10-27 11:34:45 -07003492 ASSERT_TRUE(conn3 != nullptr);
3493 conn3->ReceivedPing(); // Becomes receiving
3494 // Now prune both conn2 and conn3; they will be deleted soon.
3495 conn2->Prune();
3496 conn3->Prune();
3497 EXPECT_TRUE_WAIT(ch.connections().empty(), 1000);
3498}
honghaiz9b669572015-11-04 12:07:44 -08003499
Honghai Zhang5a246372016-05-02 17:28:35 -07003500// Tests that after a port allocator session is started, it will be stopped
3501// when a new connection becomes writable and receiving. Also tests that if a
3502// connection belonging to an old session becomes writable, it won't stop
3503// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08003504TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07003505 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3506 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08003507 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003508 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08003509 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003510 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3511 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08003512 ASSERT_TRUE(conn1 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003513 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003514 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3515
Honghai Zhang5a246372016-05-02 17:28:35 -07003516 // Start a new session. Even though conn1, which belongs to an older
3517 // session, becomes unwritable and writable again, it should not stop the
3518 // current session.
honghaiz9b669572015-11-04 12:07:44 -08003519 ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]);
3520 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07003521 conn1->Prune();
zhihuang435264a2016-06-21 11:28:38 -07003522 conn1->ReceivedPingResponse(LOW_RTT);
Honghai Zhang5a246372016-05-02 17:28:35 -07003523 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
3524
3525 // But if a new connection created from the new session becomes writable,
3526 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07003527 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
3528 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08003529 ASSERT_TRUE(conn2 != nullptr);
zhihuang435264a2016-06-21 11:28:38 -07003530 conn2->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08003531 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
3532}
guoweis36f01372016-03-02 18:02:40 -08003533
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003534// Test that the ICE role is updated even on ports that has been removed.
3535// These ports may still have connections that need a correct role, in case that
3536// the connections on it may still receive stun pings.
3537TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07003538 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3539 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003540 // Starts with ICEROLE_CONTROLLING.
3541 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003542 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07003543 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07003544 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003545 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003546
deadbeef14f97f52016-06-22 17:14:15 -07003547 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003548 ASSERT_TRUE(conn != nullptr);
3549
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003550 // Make a fake signal to remove the ports in the p2ptransportchannel. then
3551 // change the ICE role and expect it to be updated.
3552 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07003553 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07003554 ch.SetIceRole(ICEROLE_CONTROLLED);
3555 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003556}
3557
3558// Test that the ICE role is updated even on ports with inactive networks.
3559// These ports may still have connections that need a correct role, for the
3560// pings sent by those connections until they're replaced by newer-generation
3561// connections.
3562TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07003563 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3564 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003565 // Starts with ICEROLE_CONTROLLING.
3566 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07003567 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003568 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003569
deadbeef14f97f52016-06-22 17:14:15 -07003570 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003571 ASSERT_TRUE(conn != nullptr);
3572
3573 // Do an ICE restart, change the role, and expect the old port to have its
3574 // role updated.
3575 ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]);
3576 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003577 ch.SetIceRole(ICEROLE_CONTROLLED);
3578 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07003579}
3580
3581// Test that after some amount of time without receiving data, the connection
3582// and port are destroyed.
3583TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeout) {
3584 rtc::ScopedFakeClock fake_clock;
3585
deadbeef14f97f52016-06-22 17:14:15 -07003586 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3587 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07003588 PrepareChannel(&ch);
3589 // Only a controlled channel should expect its ports to be destroyed.
deadbeef14f97f52016-06-22 17:14:15 -07003590 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07003591 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003592 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07003593
deadbeef14f97f52016-06-22 17:14:15 -07003594 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07003595 ASSERT_TRUE(conn != nullptr);
3596
3597 // Simulate 2 minutes going by. This should be enough time for the port to
3598 // time out.
3599 for (int second = 0; second < 120; ++second) {
3600 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
3601 }
3602 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
3603 EXPECT_EQ(nullptr, GetPort(&ch));
3604}
3605
guoweis36f01372016-03-02 18:02:40 -08003606class P2PTransportChannelMostLikelyToWorkFirstTest
3607 : public P2PTransportChannelPingTest {
3608 public:
3609 P2PTransportChannelMostLikelyToWorkFirstTest()
3610 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
3611 network_manager_.AddInterface(kPublicAddrs[0]);
deadbeef14f97f52016-06-22 17:14:15 -07003612 allocator_.reset(new BasicPortAllocator(
guoweis36f01372016-03-02 18:02:40 -08003613 &network_manager_, ServerAddresses(), rtc::SocketAddress(),
3614 rtc::SocketAddress(), rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07003615 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
3616 PORTALLOCATOR_DISABLE_TCP);
3617 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08003618 config.credentials = kRelayCredentials;
deadbeef14f97f52016-06-22 17:14:15 -07003619 config.ports.push_back(ProtocolAddress(kTurnUdpIntAddr, PROTO_UDP, false));
guoweis36f01372016-03-02 18:02:40 -08003620 allocator_->AddTurnServer(config);
3621 allocator_->set_step_delay(kMinimumStepDelay);
3622 }
3623
deadbeef14f97f52016-06-22 17:14:15 -07003624 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08003625 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07003626 int stable_writable_connection_ping_interval) {
deadbeef14f97f52016-06-22 17:14:15 -07003627 channel_.reset(new P2PTransportChannel("checks", 1, nullptr, allocator()));
3628 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08003629 config.prioritize_most_likely_candidate_pairs =
3630 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07003631 config.stable_writable_connection_ping_interval =
3632 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08003633 channel_->SetIceConfig(config);
3634 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08003635 channel_->MaybeStartGathering();
3636 return *channel_.get();
3637 }
3638
deadbeef14f97f52016-06-22 17:14:15 -07003639 BasicPortAllocator* allocator() { return allocator_.get(); }
3640 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08003641
3642 // This verifies the next pingable connection has the expected candidates'
3643 // types and, for relay local candidate, the expected relay protocol and ping
3644 // it.
3645 void VerifyNextPingableConnection(
3646 const std::string& local_candidate_type,
3647 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07003648 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
3649 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08003650 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07003651 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08003652 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
3653 }
3654 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
3655 }
3656
guoweis36f01372016-03-02 18:02:40 -08003657 private:
deadbeef14f97f52016-06-22 17:14:15 -07003658 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08003659 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07003660 TestTurnServer turn_server_;
3661 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08003662};
3663
3664// Test that Relay/Relay connections will be pinged first when no other
3665// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07003666// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08003667TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3668 TestRelayRelayFirstWhenNothingPingedYet) {
Honghai Zhang049fbb12016-03-07 11:13:07 -08003669 const int max_strong_interval = 100;
deadbeef14f97f52016-06-22 17:14:15 -07003670 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
guoweis36f01372016-03-02 18:02:40 -08003671 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003672 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3673 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003674
deadbeef14f97f52016-06-22 17:14:15 -07003675 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
3676 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003677
3678 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3679
3680 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07003681 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
3682 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
3683 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003684
3685 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07003686 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
3687 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
3688 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003689 conn2->ReceivedPing();
3690 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3691
Honghai Zhang572b0942016-06-23 12:26:57 -07003692 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003693 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3694 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
3695 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
zhihuang435264a2016-06-21 11:28:38 -07003696 conn3->ReceivedPingResponse(LOW_RTT);
guoweis36f01372016-03-02 18:02:40 -08003697 ASSERT_TRUE(conn3->writable());
3698 conn3->ReceivedPing();
3699
honghaiz524ecc22016-05-25 12:48:31 -07003700 /*
3701
3702 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
3703 the flakiness. The following test becomes flaky because we now ping the
3704 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07003705 times. The selected connection may have been pinged before
3706 |max_strong_interval|, so it may not be the next connection to be pinged as
3707 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07003708
Honghai Zhang572b0942016-06-23 12:26:57 -07003709 // Verify that conn3 will be the "selected connection" since it is readable
3710 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08003711 // pingable connection.
Honghai Zhang572b0942016-06-23 12:26:57 -07003712 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), 5000);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003713 WAIT(false, max_strong_interval + 100);
zhihuang435264a2016-06-21 11:28:38 -07003714 conn3->ReceivedPingResponse(LOW_RTT);
guoweis36f01372016-03-02 18:02:40 -08003715 ASSERT_TRUE(conn3->writable());
3716 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07003717
3718 */
guoweis36f01372016-03-02 18:02:40 -08003719}
3720
3721// Test that Relay/Relay connections will be pinged first when everything has
3722// been pinged even if the Relay/Relay connection wasn't the first to be pinged
3723// in the first round.
3724TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3725 TestRelayRelayFirstWhenEverythingPinged) {
deadbeef14f97f52016-06-22 17:14:15 -07003726 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003727 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003728 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3729 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003730
deadbeef14f97f52016-06-22 17:14:15 -07003731 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003732 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
3733
3734 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003735 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
3736 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003737
3738 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003739 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003740 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3741
3742 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07003743 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003744
3745 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07003746 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003747
3748 // Now, every connection has been pinged once. The next one should be
3749 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003750 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003751}
3752
3753// Test that when we receive a new remote candidate, they will be tried first
3754// before we re-ping Relay/Relay connections again.
3755TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
3756 TestNoStarvationOnNonRelayConnection) {
deadbeef14f97f52016-06-22 17:14:15 -07003757 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003758 EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003759 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3760 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003761
deadbeef14f97f52016-06-22 17:14:15 -07003762 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003763 EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000);
3764
3765 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07003766 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003767
3768 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003769 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003770
3771 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003772 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08003773 EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000);
3774
3775 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07003776 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003777
3778 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07003779 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003780
3781 // Now, every connection has been pinged once. The next one should be
3782 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07003783 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003784}
3785
3786// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
3787// followed by the rest.
3788TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
3789 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07003790 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
3791 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08003792 config.credentials = kRelayCredentials;
deadbeef14f97f52016-06-22 17:14:15 -07003793 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP, false));
guoweis36f01372016-03-02 18:02:40 -08003794 allocator()->AddTurnServer(config);
3795
deadbeef14f97f52016-06-22 17:14:15 -07003796 P2PTransportChannel& ch = StartTransportChannel(true, 100);
guoweis36f01372016-03-02 18:02:40 -08003797 EXPECT_TRUE_WAIT(ch.ports().size() == 3, 5000);
deadbeef14f97f52016-06-22 17:14:15 -07003798 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
3799 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
3800 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003801
3802 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07003803 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
guoweis36f01372016-03-02 18:02:40 -08003804 EXPECT_TRUE_WAIT(ch.connections().size() == 3, 5000);
3805
3806 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07003807 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003808
3809 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07003810 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
3811 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08003812
3813 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07003814 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08003815}
deadbeef14f97f52016-06-22 17:14:15 -07003816
3817} // namespace cricket {