blob: b97e66bb64f3cdea8db5ea0db8c395167c58c791 [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
Steve Antone9324572017-11-29 10:18:21 -080011#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
Qingsi Wangecd30542019-05-22 14:34:56 -070013#include <utility>
kwiberg3ec46792016-04-27 07:22:53 -070014
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Jonas Orelande8e7d7b2019-05-29 09:30:55 +020016#include "p2p/base/connection.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "p2p/base/fake_port_allocator.h"
18#include "p2p/base/ice_transport_internal.h"
19#include "p2p/base/mock_async_resolver.h"
20#include "p2p/base/p2p_transport_channel.h"
21#include "p2p/base/packet_transport_internal.h"
22#include "p2p/base/test_relay_server.h"
23#include "p2p/base/test_stun_server.h"
24#include "p2p/base/test_turn_server.h"
25#include "p2p/client/basic_port_allocator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/checks.h"
27#include "rtc_base/dscp.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070029#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/fake_network.h"
31#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/gunit.h"
33#include "rtc_base/helpers.h"
34#include "rtc_base/logging.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070035#include "rtc_base/mdns_responder_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/nat_server.h"
37#include "rtc_base/nat_socket_factory.h"
38#include "rtc_base/proxy_server.h"
39#include "rtc_base/socket_address.h"
40#include "rtc_base/ssl_adapter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020043#include "system_wrappers/include/metrics.h"
Qingsi Wangc129c352019-04-18 10:41:58 -070044#include "test/field_trial.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000045
deadbeef14f97f52016-06-22 17:14:15 -070046namespace {
47
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000048using rtc::SocketAddress;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070049using ::testing::_;
Zach Stein5ec2c942018-11-27 16:58:08 -080050using ::testing::Assign;
Steve Antonae226f62019-01-29 12:47:38 -080051using ::testing::Contains;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070052using ::testing::DoAll;
Qingsi Wang09619332018-09-12 22:51:55 -070053using ::testing::InSequence;
54using ::testing::InvokeWithoutArgs;
55using ::testing::NiceMock;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070056using ::testing::Return;
57using ::testing::SetArgPointee;
Qingsi Wangc129c352019-04-18 10:41:58 -070058using ::testing::SizeIs;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000059
deadbeef14f97f52016-06-22 17:14:15 -070060// Default timeout for tests in this file.
61// Should be large enough for slow buildbots to run the tests reliably.
62static const int kDefaultTimeout = 10000;
Honghai Zhang161a5862016-10-20 11:47:02 -070063static const int kMediumTimeout = 3000;
64static const int kShortTimeout = 1000;
deadbeef14f97f52016-06-22 17:14:15 -070065
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
67 cricket::PORTALLOCATOR_DISABLE_RELAY |
68 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070069static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070// Addresses on the public internet.
Yves Gerey665174f2018-06-19 15:03:05 +020071static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
72 SocketAddress("22.22.22.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073// IPv6 Addresses on the public internet.
74static const SocketAddress kIPv6PublicAddrs[2] = {
75 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
honghaiz7252a002016-11-08 20:04:09 -080076 SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000077// For configuring multihomed clients.
Honghai Zhangfd16da22016-08-17 16:12:46 -070078static const SocketAddress kAlternateAddrs[2] = {
79 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
honghaiz7252a002016-11-08 20:04:09 -080080static const SocketAddress kIPv6AlternateAddrs[2] = {
81 SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
82 SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
deadbeeff137e972017-03-23 15:45:49 -070083// Addresses for HTTP proxy servers.
Yves Gerey665174f2018-06-19 15:03:05 +020084static const SocketAddress kHttpsProxyAddrs[2] = {
85 SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443)};
deadbeeff137e972017-03-23 15:45:49 -070086// Addresses for SOCKS proxy servers.
Yves Gerey665174f2018-06-19 15:03:05 +020087static const SocketAddress kSocksProxyAddrs[2] = {
88 SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000089// Internal addresses for NAT boxes.
Yves Gerey665174f2018-06-19 15:03:05 +020090static const SocketAddress kNatAddrs[2] = {SocketAddress("192.168.1.1", 0),
91 SocketAddress("192.168.2.1", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000092// Private addresses inside the NAT private networks.
Yves Gerey665174f2018-06-19 15:03:05 +020093static const SocketAddress kPrivateAddrs[2] = {
94 SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000095// For cascaded NATs, the internal addresses of the inner NAT boxes.
Yves Gerey665174f2018-06-19 15:03:05 +020096static const SocketAddress kCascadedNatAddrs[2] = {
97 SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098// For cascaded NATs, private addresses inside the inner private networks.
Yves Gerey665174f2018-06-19 15:03:05 +020099static const SocketAddress kCascadedPrivateAddrs[2] = {
100 SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000101// The address of the public STUN server.
102static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103// The addresses for the public turn server.
Honghai Zhangb73d2692016-09-29 22:46:09 -0700104static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -0800106static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
107 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000108static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
109static const cricket::RelayCredentials kRelayCredentials("test", "test");
110
111// Based on ICE_UFRAG_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700112const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113// Based on ICE_PWD_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700114const char* kIcePwd[4] = {
115 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
116 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
117const cricket::IceParameters kIceParams[4] = {
118 {kIceUfrag[0], kIcePwd[0], false},
119 {kIceUfrag[1], kIcePwd[1], false},
120 {kIceUfrag[2], kIcePwd[2], false},
121 {kIceUfrag[3], kIcePwd[3], false}};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000122
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700123const uint64_t kLowTiebreaker = 11111;
124const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700126enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000127
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700128cricket::IceConfig CreateIceConfig(
129 int receiving_timeout,
130 cricket::ContinualGatheringPolicy continual_gathering_policy,
Danil Chapovalov00c71832018-06-15 15:58:38 +0200131 absl::optional<int> backup_ping_interval = absl::nullopt) {
honghaiz1f429e32015-09-28 07:57:34 -0700132 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800133 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700134 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800135 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700136 return config;
137}
138
deadbeef14f97f52016-06-22 17:14:15 -0700139cricket::Candidate CreateUdpCandidate(const std::string& type,
140 const std::string& ip,
141 int port,
142 int priority,
143 const std::string& ufrag = "") {
144 cricket::Candidate c;
145 c.set_address(rtc::SocketAddress(ip, port));
146 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
147 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
148 c.set_priority(priority);
149 c.set_username(ufrag);
150 c.set_type(type);
151 return c;
152}
153
Honghai Zhangb73d2692016-09-29 22:46:09 -0700154cricket::BasicPortAllocator* CreateBasicPortAllocator(
155 rtc::NetworkManager* network_manager,
156 const cricket::ServerAddresses& stun_servers,
157 const rtc::SocketAddress& turn_server_udp,
158 const rtc::SocketAddress& turn_server_tcp) {
159 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
160 turn_server.credentials = kRelayCredentials;
161 if (!turn_server_udp.IsNil()) {
162 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800163 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700164 }
165 if (!turn_server_tcp.IsNil()) {
166 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800167 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700168 }
169 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
170
171 cricket::BasicPortAllocator* allocator =
172 new cricket::BasicPortAllocator(network_manager);
Qingsi Wanga2d60672018-04-11 16:57:45 -0700173 allocator->Initialize();
Honghai Zhangb73d2692016-09-29 22:46:09 -0700174 allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
175 return allocator;
176}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700177} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700178
179namespace cricket {
180
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000181// This test simulates 2 P2P endpoints that want to establish connectivity
182// with each other over various network topologies and conditions, which can be
183// specified in each individial test.
184// A virtual network (via VirtualSocketServer) along with virtual firewalls and
185// NATs (via Firewall/NATSocketServer) are used to simulate the various network
186// conditions. We can configure the IP addresses of the endpoints,
187// block various types of connectivity, or add arbitrary levels of NAT.
188// We also run a STUN server and a relay server on the virtual network to allow
189// our typical P2P mechanisms to do their thing.
190// For each case, we expect the P2P stack to eventually settle on a specific
191// form of connectivity to the other side. The test checks that the P2P
192// negotiation successfully establishes connectivity within a certain time,
193// and that the result is what we expect.
194// Note that this class is a base class for use by other tests, who will provide
195// specialized test behavior.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200196class P2PTransportChannelTestBase : public ::testing::Test,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197 public rtc::MessageHandler,
198 public sigslot::has_slots<> {
199 public:
200 P2PTransportChannelTestBase()
deadbeef98e186c2017-05-16 18:00:06 -0700201 : vss_(new rtc::VirtualSocketServer()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202 nss_(new rtc::NATSocketServer(vss_.get())),
203 ss_(new rtc::FirewallSocketServer(nss_.get())),
nisse7eaa4ea2017-05-08 05:25:41 -0700204 main_(ss_.get()),
205 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
206 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeeff137e972017-03-23 15:45:49 -0700207 socks_server1_(ss_.get(),
208 kSocksProxyAddrs[0],
209 ss_.get(),
210 kSocksProxyAddrs[0]),
211 socks_server2_(ss_.get(),
212 kSocksProxyAddrs[1],
213 ss_.get(),
214 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000215 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700216 ep1_.role_ = ICEROLE_CONTROLLING;
217 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000218
219 ServerAddresses stun_servers;
220 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700221 ep1_.allocator_.reset(
222 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
223 kTurnUdpIntAddr, rtc::SocketAddress()));
224 ep2_.allocator_.reset(
225 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
226 kTurnUdpIntAddr, rtc::SocketAddress()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700227 webrtc::metrics::Reset();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000228 }
229
230 protected:
231 enum Config {
Yves Gerey665174f2018-06-19 15:03:05 +0200232 OPEN, // Open to the Internet
233 NAT_FULL_CONE, // NAT, no filtering
234 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
235 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
236 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
237 NAT_DOUBLE_CONE, // Double NAT, both cone
238 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
239 BLOCK_UDP, // Firewall, UDP in/out blocked
240 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
241 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
242 PROXY_HTTPS, // All traffic through HTTPS proxy
243 PROXY_SOCKS, // All traffic through SOCKS proxy
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000244 NUM_CONFIGS
245 };
246
247 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700248 Result(const std::string& controlling_type,
249 const std::string& controlling_protocol,
250 const std::string& controlled_type,
251 const std::string& controlled_protocol,
252 int wait)
253 : controlling_type(controlling_type),
254 controlling_protocol(controlling_protocol),
255 controlled_type(controlled_type),
256 controlled_protocol(controlled_protocol),
257 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700258
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700259 // The expected candidate type and protocol of the controlling ICE agent.
260 std::string controlling_type;
261 std::string controlling_protocol;
262 // The expected candidate type and protocol of the controlled ICE agent.
263 std::string controlled_type;
264 std::string controlled_protocol;
265 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 int connect_wait;
267 };
268
269 struct ChannelData {
270 bool CheckData(const char* data, int len) {
271 bool ret = false;
272 if (!ch_packets_.empty()) {
Yves Gerey665174f2018-06-19 15:03:05 +0200273 std::string packet = ch_packets_.front();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000274 ret = (packet == std::string(data, len));
275 ch_packets_.pop_front();
276 }
277 return ret;
278 }
279
Steve Antone9324572017-11-29 10:18:21 -0800280 std::string name_; // TODO(?) - Currently not used.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000281 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700282 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000283 };
284
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700285 struct CandidatesData : public rtc::MessageData {
zhihuangd06adf62017-01-12 15:58:31 -0800286 CandidatesData(IceTransportInternal* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700287 : channel(ch), candidates(1, c) {}
zhihuangd06adf62017-01-12 15:58:31 -0800288 CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700289 : channel(ch), candidates(cc) {}
zhihuangd06adf62017-01-12 15:58:31 -0800290 IceTransportInternal* channel;
deadbeef14f97f52016-06-22 17:14:15 -0700291 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000292 };
293
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700294 struct Endpoint : public sigslot::has_slots<> {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000295 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700296 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000297 tiebreaker_(0),
298 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700299 save_candidates_(false) {}
deadbeef5bd5ca32017-02-10 11:31:50 -0800300 bool HasTransport(const rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700301 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000302 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800303 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700304 if (!HasTransport(transport))
305 return NULL;
306 if (cd1_.ch_.get() == transport)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000307 return &cd1_;
308 else
309 return &cd2_;
310 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000311
deadbeef14f97f52016-06-22 17:14:15 -0700312 void SetIceRole(IceRole role) { role_ = role; }
313 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200314 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
315 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000316 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
317 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200318 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000319 allocator_->set_step_delay(delay);
320 }
321 void SetAllowTcpListen(bool allow_tcp_listen) {
322 allocator_->set_allow_tcp_listen(allow_tcp_listen);
323 }
324
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700325 void OnIceRegathering(PortAllocatorSession*, IceRegatheringReason reason) {
326 ++ice_regathering_counter_[reason];
327 }
328
329 int GetIceRegatheringCountForReason(IceRegatheringReason reason) {
330 return ice_regathering_counter_[reason];
331 }
332
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000333 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -0700334 std::unique_ptr<BasicPortAllocator> allocator_;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700335 webrtc::AsyncResolverFactory* async_resolver_factory_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000336 ChannelData cd1_;
337 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700338 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200339 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000340 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000341 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700342 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700343 bool ready_to_send_ = false;
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700344 std::map<IceRegatheringReason, int> ice_regathering_counter_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000345 };
346
deadbeef5bd5ca32017-02-10 11:31:50 -0800347 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700348 if (ep1_.HasTransport(transport))
349 return ep1_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000350 else
johand89ab142016-10-25 10:50:32 -0700351 return ep2_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000352 }
353
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700354 IceParameters IceParamsWithRenomination(const IceParameters& ice,
355 bool renomination) {
356 IceParameters new_ice = ice;
357 new_ice.renomination = renomination;
358 return new_ice;
359 }
360
johan02bd5122016-09-20 00:23:27 -0700361 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700362 const IceConfig& ep2_config,
363 bool renomination = false) {
364 IceParameters ice_ep1_cd1_ch =
365 IceParamsWithRenomination(kIceParams[0], renomination);
366 IceParameters ice_ep2_cd1_ch =
367 IceParamsWithRenomination(kIceParams[1], renomination);
368 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
369 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
370 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
371 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
deadbeefb60a8192016-08-24 15:15:00 -0700372 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
373 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700374 ep1_.cd1_.ch_->MaybeStartGathering();
375 ep2_.cd1_.ch_->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700376 ep1_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
377 &ep1_, &Endpoint::OnIceRegathering);
378 ep2_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
379 &ep2_, &Endpoint::OnIceRegathering);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000380 }
deadbeefb60a8192016-08-24 15:15:00 -0700381
johan02bd5122016-09-20 00:23:27 -0700382 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700383 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700384 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700385 }
386
deadbeef14f97f52016-06-22 17:14:15 -0700387 P2PTransportChannel* CreateChannel(int endpoint,
388 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700389 const IceParameters& local_ice,
390 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700391 P2PTransportChannel* channel = new P2PTransportChannel(
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700392 "test content name", component, GetAllocator(endpoint),
393 GetEndpoint(endpoint)->async_resolver_factory_);
deadbeef14f97f52016-06-22 17:14:15 -0700394 channel->SignalReadyToSend.connect(
395 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700396 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700397 this, &P2PTransportChannelTestBase::OnCandidateGathered);
398 channel->SignalCandidatesRemoved.connect(
399 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000400 channel->SignalReadPacket.connect(
401 this, &P2PTransportChannelTestBase::OnReadPacket);
402 channel->SignalRoleConflict.connect(
403 this, &P2PTransportChannelTestBase::OnRoleConflict);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800404 channel->SignalNetworkRouteChanged.connect(
405 this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
Qingsi Wang6e641e62018-04-11 20:14:17 -0700406 channel->SignalSentPacket.connect(
407 this, &P2PTransportChannelTestBase::OnSentPacket);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700408 channel->SetIceParameters(local_ice);
409 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
410 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000411 }
412 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
413 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000414 return channel;
415 }
416 void DestroyChannels() {
Qingsi Wang5b8dd4d2018-06-20 13:30:43 -0700417 main_.Clear(this);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000418 ep1_.cd1_.ch_.reset();
419 ep2_.cd1_.ch_.reset();
420 ep1_.cd2_.ch_.reset();
421 ep2_.cd2_.ch_.reset();
422 }
deadbeef14f97f52016-06-22 17:14:15 -0700423 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
424 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
425 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
426 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000427
Taylor Brandstetteref184702016-06-23 17:35:47 -0700428 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700429 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700430
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000431 // Common results.
432 static const Result kLocalUdpToLocalUdp;
433 static const Result kLocalUdpToStunUdp;
434 static const Result kLocalUdpToPrflxUdp;
435 static const Result kPrflxUdpToLocalUdp;
436 static const Result kStunUdpToLocalUdp;
437 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700438 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000439 static const Result kPrflxUdpToStunUdp;
440 static const Result kLocalUdpToRelayUdp;
441 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700442 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000443 static const Result kLocalTcpToLocalTcp;
444 static const Result kLocalTcpToPrflxTcp;
445 static const Result kPrflxTcpToLocalTcp;
446
447 rtc::NATSocketServer* nat() { return nss_.get(); }
448 rtc::FirewallSocketServer* fw() { return ss_.get(); }
449
450 Endpoint* GetEndpoint(int endpoint) {
451 if (endpoint == 0) {
452 return &ep1_;
453 } else if (endpoint == 1) {
454 return &ep2_;
455 } else {
456 return NULL;
457 }
458 }
honghaiz7252a002016-11-08 20:04:09 -0800459 BasicPortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000460 return GetEndpoint(endpoint)->allocator_.get();
461 }
462 void AddAddress(int endpoint, const SocketAddress& addr) {
463 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
464 }
honghaize1a0c942016-02-16 14:54:56 -0800465 void AddAddress(int endpoint,
466 const SocketAddress& addr,
467 const std::string& ifname,
468 rtc::AdapterType adapter_type) {
469 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
470 adapter_type);
471 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000472 void RemoveAddress(int endpoint, const SocketAddress& addr) {
473 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700474 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000475 }
deadbeeff137e972017-03-23 15:45:49 -0700476 void SetProxy(int endpoint, rtc::ProxyType type) {
477 rtc::ProxyInfo info;
478 info.type = type;
Yves Gerey665174f2018-06-19 15:03:05 +0200479 info.address = (type == rtc::PROXY_HTTPS) ? kHttpsProxyAddrs[endpoint]
480 : kSocksProxyAddrs[endpoint];
deadbeeff137e972017-03-23 15:45:49 -0700481 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
482 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000483 void SetAllocatorFlags(int endpoint, int flags) {
484 GetAllocator(endpoint)->set_flags(flags);
485 }
deadbeef14f97f52016-06-22 17:14:15 -0700486 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000487 GetEndpoint(endpoint)->SetIceRole(role);
488 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200489 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000490 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
491 }
492 bool GetRoleConflict(int endpoint) {
493 return GetEndpoint(endpoint)->role_conflict();
494 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200495 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000496 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
497 }
498 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
499 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
500 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700501
502 // Return true if the approprite parts of the expected Result, based
503 // on the local and remote candidate of ep1_ch1, match. This can be
504 // used in an EXPECT_TRUE_WAIT.
505 bool CheckCandidate1(const Result& expected) {
506 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700507 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700508 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700509 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
510 return (local_protocol == expected.controlling_protocol &&
511 remote_protocol == expected.controlled_protocol &&
512 local_type == expected.controlling_type &&
513 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700514 }
515
516 // EXPECT_EQ on the approprite parts of the expected Result, based
517 // on the local and remote candidate of ep1_ch1. This is like
518 // CheckCandidate1, except that it will provide more detail about
519 // what didn't match.
520 void ExpectCandidate1(const Result& expected) {
521 if (CheckCandidate1(expected)) {
522 return;
523 }
524
525 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700526 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700527 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700528 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
529 EXPECT_EQ(expected.controlling_type, local_type);
530 EXPECT_EQ(expected.controlled_type, remote_type);
531 EXPECT_EQ(expected.controlling_protocol, local_protocol);
532 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700533 }
534
535 // Return true if the approprite parts of the expected Result, based
536 // on the local and remote candidate of ep2_ch1, match. This can be
537 // used in an EXPECT_TRUE_WAIT.
538 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700539 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
540 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
541 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
542 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
543 return (local_protocol == expected.controlled_protocol &&
544 remote_protocol == expected.controlling_protocol &&
545 local_type == expected.controlled_type &&
546 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700547 }
548
549 // EXPECT_EQ on the approprite parts of the expected Result, based
550 // on the local and remote candidate of ep2_ch1. This is like
551 // CheckCandidate2, except that it will provide more detail about
552 // what didn't match.
553 void ExpectCandidate2(const Result& expected) {
554 if (CheckCandidate2(expected)) {
555 return;
556 }
557
558 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700559 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700560 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700561 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
562 EXPECT_EQ(expected.controlled_type, local_type);
563 EXPECT_EQ(expected.controlling_type, remote_type);
564 EXPECT_EQ(expected.controlled_protocol, local_protocol);
565 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700566 }
567
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000568 void Test(const Result& expected) {
honghaize58d73d2016-10-24 16:38:26 -0700569 rtc::ScopedFakeClock clock;
nisse1bffc1d2016-05-02 08:18:55 -0700570 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700571 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000572
573 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700574 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -0700575 EXPECT_TRUE_SIMULATED_WAIT(
576 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
577 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
578 ep2_ch1()->writable(),
579 expected.connect_wait + kShortTimeout, clock);
nisse1bffc1d2016-05-02 08:18:55 -0700580 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000581 if (connect_time < expected.connect_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100582 RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000583 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200584 RTC_LOG(LS_INFO) << "Connect time: TIMEOUT (" << expected.connect_wait
585 << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000586 }
587
Honghai Zhang572b0942016-06-23 12:26:57 -0700588 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000589 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700590 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700591 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700592 int64_t converge_time;
Honghai Zhang572b0942016-06-23 12:26:57 -0700593 // Verifying local and remote channel selected connection information.
594 // This is done only for the RFC 5245 as controlled agent will use
595 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
596 // EP1 result matrix.
honghaize58d73d2016-10-24 16:38:26 -0700597 EXPECT_TRUE_SIMULATED_WAIT(
598 CheckCandidate1(expected) && CheckCandidate2(expected),
599 kMediumTimeout, clock);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700600 // Also do EXPECT_EQ on each part so that failures are more verbose.
601 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700602 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000603
nisse1bffc1d2016-05-02 08:18:55 -0700604 converge_time = rtc::TimeMillis() - converge_start;
honghaize58d73d2016-10-24 16:38:26 -0700605 int64_t converge_wait = 2000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000606 if (converge_time < converge_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100607 RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000608 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200609 RTC_LOG(LS_INFO) << "Converge time: TIMEOUT (" << converge_wait
610 << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000611 }
612 }
613 // Try sending some data to other end.
Steve Antone9324572017-11-29 10:18:21 -0800614 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000615
616 // Destroy the channels, and wait for them to be fully cleaned up.
617 DestroyChannels();
618 }
619
Sebastian Janssond624c392019-04-17 10:36:03 +0200620 void TestSendRecv(rtc::ThreadProcessingFakeClock* clock) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000621 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700622 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000623 int len = static_cast<int>(strlen(data));
624 // local_channel1 <==> remote_channel1
honghaize58d73d2016-10-24 16:38:26 -0700625 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800626 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700627 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800628 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700629 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800630 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700631 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800632 kMediumTimeout, *clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000633 }
634 }
635
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700636 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700637 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000638 // restart the ice gathering. Finally it waits for the transport to select a
639 // new connection using the newly generated ice candidates.
640 // Before calling this function the end points must be configured.
641 void TestHandleIceUfragPasswordChanged() {
honghaize58d73d2016-10-24 16:38:26 -0700642 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700643 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
644 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
honghaize58d73d2016-10-24 16:38:26 -0700645 EXPECT_TRUE_SIMULATED_WAIT(
646 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
647 ep2_ch1()->receiving() && ep2_ch1()->writable(),
648 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000649
deadbeef14f97f52016-06-22 17:14:15 -0700650 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
651 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
652 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
653 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000654
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700655 ep1_ch1()->SetIceParameters(kIceParams[2]);
656 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700657 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700658 ep2_ch1()->SetIceParameters(kIceParams[3]);
659
660 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700661 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000662
honghaize58d73d2016-10-24 16:38:26 -0700663 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
664 old_local_candidate1->generation(),
665 kMediumTimeout, clock);
666 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
667 old_local_candidate2->generation(),
668 kMediumTimeout, clock);
669 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
670 old_remote_candidate1->generation(),
671 kMediumTimeout, clock);
672 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
673 old_remote_candidate2->generation(),
674 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000675 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
676 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
677 }
678
679 void TestSignalRoleConflict() {
honghaize58d73d2016-10-24 16:38:26 -0700680 rtc::ScopedFakeClock clock;
681 // Default EP1 is in controlling state.
682 SetIceTiebreaker(0, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000683
deadbeef14f97f52016-06-22 17:14:15 -0700684 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700685 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000686
687 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700688 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000689 // Since both the channels initiated with controlling state and channel2
690 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
honghaize58d73d2016-10-24 16:38:26 -0700691 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000692 EXPECT_FALSE(GetRoleConflict(1));
693
honghaize58d73d2016-10-24 16:38:26 -0700694 EXPECT_TRUE_SIMULATED_WAIT(
695 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
696 ep2_ch1()->receiving() && ep2_ch1()->writable(),
697 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000698
Honghai Zhang572b0942016-06-23 12:26:57 -0700699 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
700 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000701
Steve Antone9324572017-11-29 10:18:21 -0800702 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000703 }
704
Qingsi Wang6e641e62018-04-11 20:14:17 -0700705 void TestPacketInfoIsSet(rtc::PacketInfo info) {
706 EXPECT_NE(info.packet_type, rtc::PacketType::kUnknown);
707 EXPECT_NE(info.protocol, rtc::PacketInfoProtocolType::kUnknown);
708 EXPECT_TRUE(info.network_id.has_value());
Qingsi Wang6e641e62018-04-11 20:14:17 -0700709 }
710
deadbeef5bd5ca32017-02-10 11:31:50 -0800711 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700712 GetEndpoint(transport)->ready_to_send_ = true;
deadbeef14f97f52016-06-22 17:14:15 -0700713 }
714
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000715 // We pass the candidates directly to the other side.
zhihuangd06adf62017-01-12 15:58:31 -0800716 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
deadbeef14f97f52016-06-22 17:14:15 -0700717 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000718 return;
719
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000720 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700721 GetEndpoint(ch)->saved_candidates_.push_back(
722 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000723 } else {
nisse7eaa4ea2017-05-08 05:25:41 -0700724 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
725 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000726 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000727 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800728
Danil Chapovalov00c71832018-06-15 15:58:38 +0200729 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800730 // If the |network_route| is unset, don't count. This is used in the case
731 // when the network on remote side is down, the signal will be fired with an
732 // unset network route and it shouldn't trigger a connection switch.
733 if (network_route) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700734 ++selected_candidate_pair_switches_;
735 }
honghaiz9ad0db52016-07-14 19:30:28 -0700736 }
737
738 int reset_selected_candidate_pair_switches() {
739 int switches = selected_candidate_pair_switches_;
740 selected_candidate_pair_switches_ = 0;
741 return switches;
742 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000743
744 void PauseCandidates(int endpoint) {
745 GetEndpoint(endpoint)->save_candidates_ = true;
746 }
747
zhihuangd06adf62017-01-12 15:58:31 -0800748 void OnCandidatesRemoved(IceTransportInternal* ch,
deadbeef14f97f52016-06-22 17:14:15 -0700749 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700750 // Candidate removals are not paused.
751 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
nisse7eaa4ea2017-05-08 05:25:41 -0700752 main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700753 }
754
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800755 // Tcp candidate verification has to be done when they are generated.
756 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
757 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700758 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700759 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700760 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700761 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
762 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
763 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
764 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700765 } else {
766 FAIL() << "Unknown tcptype: " << candidate.tcptype();
767 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800768 }
769 }
770 }
771
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000772 void ResumeCandidates(int endpoint) {
773 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700774 for (auto& candidate : ed->saved_candidates_) {
nisse7eaa4ea2017-05-08 05:25:41 -0700775 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000776 }
777 ed->saved_candidates_.clear();
778 ed->save_candidates_ = false;
779 }
780
781 void OnMessage(rtc::Message* msg) {
782 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700783 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700784 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700785 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700786 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
787 if (!rch) {
788 return;
789 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700790 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700791 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700792 c.set_username("");
793 c.set_password("");
794 }
Mirko Bonadei675513b2017-11-09 11:09:25 +0100795 RTC_LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
796 << rch->component() << "): " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700797 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000798 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700799 break;
800 }
801 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700802 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700803 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700804 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
805 if (!rch) {
806 return;
807 }
808 for (Candidate& c : data->candidates) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100809 RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700810 rch->RemoveRemoteCandidate(c);
811 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000812 break;
813 }
814 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000815 }
johand89ab142016-10-25 10:50:32 -0700816
deadbeef5bd5ca32017-02-10 11:31:50 -0800817 void OnReadPacket(rtc::PacketTransportInternal* transport,
deadbeef14f97f52016-06-22 17:14:15 -0700818 const char* data,
819 size_t len,
Niels Möllere6933812018-11-05 13:01:41 +0100820 const int64_t& /* packet_time_us */,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000821 int flags) {
johand89ab142016-10-25 10:50:32 -0700822 std::list<std::string>& packets = GetPacketList(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000823 packets.push_front(std::string(data, len));
824 }
johand89ab142016-10-25 10:50:32 -0700825
zhihuangd06adf62017-01-12 15:58:31 -0800826 void OnRoleConflict(IceTransportInternal* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000827 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700828 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
829 ? ICEROLE_CONTROLLED
830 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000831 channel->SetIceRole(new_role);
832 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700833
Qingsi Wang6e641e62018-04-11 20:14:17 -0700834 void OnSentPacket(rtc::PacketTransportInternal* transport,
835 const rtc::SentPacket& packet) {
836 TestPacketInfoIsSet(packet.info);
837 }
838
zhihuangd06adf62017-01-12 15:58:31 -0800839 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000840 rtc::PacketOptions options;
841 return channel->SendPacket(data, len, options, 0);
842 }
zhihuangd06adf62017-01-12 15:58:31 -0800843 bool CheckDataOnChannel(IceTransportInternal* channel,
deadbeef14f97f52016-06-22 17:14:15 -0700844 const char* data,
845 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000846 return GetChannelData(channel)->CheckData(data, len);
847 }
deadbeef14f97f52016-06-22 17:14:15 -0700848 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700849 return (ch && ch->selected_connection())
850 ? &ch->selected_connection()->local_candidate()
851 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000852 }
deadbeef14f97f52016-06-22 17:14:15 -0700853 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700854 return (ch && ch->selected_connection())
855 ? &ch->selected_connection()->remote_candidate()
856 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000857 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800858 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700859 if (ep1_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000860 return &ep1_;
johand89ab142016-10-25 10:50:32 -0700861 } else if (ep2_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000862 return &ep2_;
863 } else {
864 return NULL;
865 }
866 }
zhihuangd06adf62017-01-12 15:58:31 -0800867 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000868 if (ch == ep1_ch1())
869 return ep2_ch1();
870 else if (ch == ep1_ch2())
871 return ep2_ch2();
872 else if (ch == ep2_ch1())
873 return ep1_ch1();
874 else if (ch == ep2_ch2())
875 return ep1_ch2();
876 else
877 return NULL;
878 }
johand89ab142016-10-25 10:50:32 -0700879 std::list<std::string>& GetPacketList(
deadbeef5bd5ca32017-02-10 11:31:50 -0800880 rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700881 return GetChannelData(transport)->ch_packets_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000882 }
883
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700884 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700885
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700886 // How does the test pass ICE parameters to the P2PTransportChannel?
887 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700888 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700889 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
890 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000891 }
892
Yves Gerey665174f2018-06-19 15:03:05 +0200893 void set_force_relay(bool relay) { force_relay_ = relay; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000894
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700895 void ConnectSignalNominated(Connection* conn) {
896 conn->SignalNominated.connect(this,
897 &P2PTransportChannelTestBase::OnNominated);
898 }
899
900 void OnNominated(Connection* conn) { nominated_ = true; }
901 bool nominated() { return nominated_; }
902
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000903 private:
kwiberg3ec46792016-04-27 07:22:53 -0700904 std::unique_ptr<rtc::VirtualSocketServer> vss_;
905 std::unique_ptr<rtc::NATSocketServer> nss_;
906 std::unique_ptr<rtc::FirewallSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700907 rtc::AutoSocketServerThread main_;
deadbeef14f97f52016-06-22 17:14:15 -0700908 std::unique_ptr<TestStunServer> stun_server_;
909 TestTurnServer turn_server_;
deadbeeff137e972017-03-23 15:45:49 -0700910 rtc::SocksProxyServer socks_server1_;
911 rtc::SocksProxyServer socks_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000912 Endpoint ep1_;
913 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700914 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000915 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700916 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700917
918 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000919};
920
921// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700922const P2PTransportChannelTestBase::Result
923 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
924 "udp",
925 "local",
926 "udp",
927 1000);
928const P2PTransportChannelTestBase::Result
929 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
930 "udp",
931 "stun",
932 "udp",
933 1000);
934const P2PTransportChannelTestBase::Result
935 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
936 "udp",
937 "prflx",
938 "udp",
939 1000);
940const P2PTransportChannelTestBase::Result
941 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
942 "udp",
943 "local",
944 "udp",
945 1000);
946const P2PTransportChannelTestBase::Result
947 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
948 "udp",
949 "local",
950 "udp",
951 1000);
952const P2PTransportChannelTestBase::Result
953 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
954 "udp",
955 "stun",
956 "udp",
957 1000);
958const P2PTransportChannelTestBase::Result
959 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
960 "udp",
961 "prflx",
962 "udp",
963 1000);
964const P2PTransportChannelTestBase::Result
965 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
966 "udp",
967 "stun",
968 "udp",
969 1000);
970const P2PTransportChannelTestBase::Result
971 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
972 "udp",
973 "relay",
974 "udp",
975 2000);
976const P2PTransportChannelTestBase::Result
977 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
978 "udp",
979 "relay",
980 "udp",
981 2000);
982const P2PTransportChannelTestBase::Result
983 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
984 "udp",
985 "prflx",
986 "udp",
987 2000);
988const P2PTransportChannelTestBase::Result
989 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
990 "tcp",
991 "local",
992 "tcp",
993 3000);
994const P2PTransportChannelTestBase::Result
995 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
996 "tcp",
997 "prflx",
998 "tcp",
999 3000);
1000const P2PTransportChannelTestBase::Result
1001 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
1002 "tcp",
1003 "local",
1004 "tcp",
1005 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001006
1007// Test the matrix of all the connectivity types we expect to see in the wild.
1008// Just test every combination of the configs in the Config enum.
1009class P2PTransportChannelTest : public P2PTransportChannelTestBase {
1010 protected:
1011 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -07001012 void ConfigureEndpoints(Config config1,
1013 Config config2,
1014 int allocator_flags1,
1015 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001016 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001017 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001018 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001019 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001020 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001021 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001022
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001023 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001024 }
1025 void ConfigureEndpoint(int endpoint, Config config) {
1026 switch (config) {
1027 case OPEN:
1028 AddAddress(endpoint, kPublicAddrs[endpoint]);
1029 break;
1030 case NAT_FULL_CONE:
1031 case NAT_ADDR_RESTRICTED:
1032 case NAT_PORT_RESTRICTED:
1033 case NAT_SYMMETRIC:
1034 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1035 // Add a single NAT of the desired type
Yves Gerey665174f2018-06-19 15:03:05 +02001036 nat()
1037 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1038 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
1039 ->AddClient(kPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001040 break;
1041 case NAT_DOUBLE_CONE:
1042 case NAT_SYMMETRIC_THEN_CONE:
1043 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1044 // Add a two cascaded NATs of the desired types
Yves Gerey665174f2018-06-19 15:03:05 +02001045 nat()
1046 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1047 (config == NAT_DOUBLE_CONE) ? rtc::NAT_OPEN_CONE
1048 : rtc::NAT_SYMMETRIC)
1049 ->AddTranslator(kPrivateAddrs[endpoint],
1050 kCascadedNatAddrs[endpoint], rtc::NAT_OPEN_CONE)
1051 ->AddClient(kCascadedPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001052 break;
1053 case BLOCK_UDP:
1054 case BLOCK_UDP_AND_INCOMING_TCP:
deadbeeff137e972017-03-23 15:45:49 -07001055 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1056 case PROXY_HTTPS:
1057 case PROXY_SOCKS:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001058 AddAddress(endpoint, kPublicAddrs[endpoint]);
1059 // Block all UDP
Yves Gerey665174f2018-06-19 15:03:05 +02001060 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001061 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1062 // Block TCP inbound to the endpoint
1063 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1064 kPublicAddrs[endpoint]);
deadbeeff137e972017-03-23 15:45:49 -07001065 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1066 // Block all TCP to/from the endpoint except 80/443 out
1067 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1068 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1069 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1070 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1071 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1072 kPublicAddrs[endpoint]);
1073 } else if (config == PROXY_HTTPS) {
1074 // Block all TCP to/from the endpoint except to the proxy server
1075 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1076 kHttpsProxyAddrs[endpoint]);
1077 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1078 kPublicAddrs[endpoint]);
1079 SetProxy(endpoint, rtc::PROXY_HTTPS);
1080 } else if (config == PROXY_SOCKS) {
1081 // Block all TCP to/from the endpoint except to the proxy server
1082 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1083 kSocksProxyAddrs[endpoint]);
1084 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1085 kPublicAddrs[endpoint]);
1086 SetProxy(endpoint, rtc::PROXY_SOCKS5);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001087 }
1088 break;
1089 default:
deadbeef1ee21252017-06-13 15:49:45 -07001090 RTC_NOTREACHED();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001091 break;
1092 }
1093 }
1094};
1095
1096// Shorthands for use in the test matrix.
1097#define LULU &kLocalUdpToLocalUdp
1098#define LUSU &kLocalUdpToStunUdp
1099#define LUPU &kLocalUdpToPrflxUdp
1100#define PULU &kPrflxUdpToLocalUdp
1101#define SULU &kStunUdpToLocalUdp
1102#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001103#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001104#define PUSU &kPrflxUdpToStunUdp
1105#define LURU &kLocalUdpToRelayUdp
1106#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001107#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001108#define LTLT &kLocalTcpToLocalTcp
1109#define LTPT &kLocalTcpToPrflxTcp
1110#define PTLT &kPrflxTcpToLocalTcp
Steve Antone9324572017-11-29 10:18:21 -08001111// TODO(?): Enable these once TestRelayServer can accept external TCP.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001112#define LTRT NULL
1113#define LSRS NULL
1114
1115// Test matrix. Originator behavior defined by rows, receiever by columns.
1116
Steve Antone9324572017-11-29 10:18:21 -08001117// TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
1118// TODO(?): Fix NULLs caused by no HTTP proxy support.
1119// TODO(?): Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001120const P2PTransportChannelTest::Result*
1121 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
Yves Gerey665174f2018-06-19 15:03:05 +02001122 // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH
1123 // PRXS
1124 /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS,
1125 NULL, LTPT},
1126 /*CO*/
1127 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1128 LTRT},
1129 /*AD*/
1130 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1131 LTRT},
1132 /*PO*/
1133 {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL,
1134 LTRT},
1135 /*SY*/
1136 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1137 LTRT},
1138 /*2C*/
1139 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1140 LTRT},
1141 /*SC*/
1142 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1143 LTRT},
1144 /*!U*/
1145 {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL,
1146 LTRT},
1147 /*!T*/
1148 {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL,
1149 LTRT},
1150 /*HT*/
1151 {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL,
1152 LSRS},
1153 /*PR*/
1154 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1155 NULL},
1156 /*PR*/
1157 {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL,
1158 LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001159};
1160
1161// The actual tests that exercise all the various configurations.
1162// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001163#define P2P_TEST_DECLARATION(x, y, z) \
1164 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1165 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1166 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001167 if (kMatrix[x][y] != NULL) \
1168 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001169 else \
Mirko Bonadei675513b2017-11-09 11:09:25 +01001170 RTC_LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001171 }
1172
Steve Antone9324572017-11-29 10:18:21 -08001173#define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001174
deadbeeff137e972017-03-23 15:45:49 -07001175#define P2P_TEST_SET(x) \
1176 P2P_TEST(x, OPEN) \
1177 P2P_TEST(x, NAT_FULL_CONE) \
1178 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1179 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1180 P2P_TEST(x, NAT_SYMMETRIC) \
1181 P2P_TEST(x, NAT_DOUBLE_CONE) \
1182 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1183 P2P_TEST(x, BLOCK_UDP) \
1184 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1185 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1186 P2P_TEST(x, PROXY_HTTPS) \
1187 P2P_TEST(x, PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001188
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001189P2P_TEST_SET(OPEN)
1190P2P_TEST_SET(NAT_FULL_CONE)
1191P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1192P2P_TEST_SET(NAT_PORT_RESTRICTED)
1193P2P_TEST_SET(NAT_SYMMETRIC)
1194P2P_TEST_SET(NAT_DOUBLE_CONE)
1195P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1196P2P_TEST_SET(BLOCK_UDP)
1197P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
deadbeeff137e972017-03-23 15:45:49 -07001198P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1199P2P_TEST_SET(PROXY_HTTPS)
1200P2P_TEST_SET(PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001201
1202// Test that we restart candidate allocation when local ufrag&pwd changed.
1203// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001204TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001205 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001206 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001207 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001208 TestHandleIceUfragPasswordChanged();
1209 DestroyChannels();
1210}
1211
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001212// Same as above test, but with a symmetric NAT.
1213// We should end up with relay<->prflx candidate pairs, with generation "1".
1214TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1215 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1216 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001217 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001218 TestHandleIceUfragPasswordChanged();
1219 DestroyChannels();
1220}
1221
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001222// Test the operation of GetStats.
1223TEST_F(P2PTransportChannelTest, GetStats) {
honghaize58d73d2016-10-24 16:38:26 -07001224 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001225 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001226 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001227 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -07001228 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1229 ep2_ch1()->receiving() &&
1230 ep2_ch1()->writable(),
1231 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001232 TestSendRecv(&clock);
deadbeef14f97f52016-06-22 17:14:15 -07001233 ConnectionInfos infos;
Qingsi Wang72a43a12018-02-20 16:03:18 -08001234 CandidateStatsList candidate_stats_list;
1235 ASSERT_TRUE(ep1_ch1()->GetStats(&infos, &candidate_stats_list));
Steve Antone9324572017-11-29 10:18:21 -08001236 ASSERT_GE(infos.size(), 1u);
Qingsi Wang72a43a12018-02-20 16:03:18 -08001237 ASSERT_GE(candidate_stats_list.size(), 1u);
deadbeef14f97f52016-06-22 17:14:15 -07001238 ConnectionInfo* best_conn_info = nullptr;
1239 for (ConnectionInfo& info : infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001240 if (info.best_connection) {
1241 best_conn_info = &info;
1242 break;
1243 }
1244 }
1245 ASSERT_TRUE(best_conn_info != nullptr);
1246 EXPECT_TRUE(best_conn_info->new_connection);
1247 EXPECT_TRUE(best_conn_info->receiving);
1248 EXPECT_TRUE(best_conn_info->writable);
1249 EXPECT_FALSE(best_conn_info->timeout);
1250 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1251 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1252 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1253 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001254 DestroyChannels();
1255}
1256
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001257// Tests that UMAs are recorded when ICE restarts while the channel
1258// is disconnected.
1259TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1260 rtc::ScopedFakeClock clock;
1261 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1262
1263 CreateChannels();
1264 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1265 ep2_ch1()->receiving() &&
1266 ep2_ch1()->writable(),
1267 kDefaultTimeout, clock);
1268
1269 // Drop all packets so that both channels become not writable.
1270 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
skvlad51072462017-02-02 11:50:14 -08001271 const int kWriteTimeoutDelay = 8000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001272 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1273 kWriteTimeoutDelay, clock);
1274
1275 ep1_ch1()->SetIceParameters(kIceParams[2]);
1276 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1277 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001278 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1279 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001280 static_cast<int>(IceRestartState::DISCONNECTED)));
1281
1282 ep2_ch1()->SetIceParameters(kIceParams[3]);
1283 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1284 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001285 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1286 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001287 static_cast<int>(IceRestartState::DISCONNECTED)));
1288
1289 DestroyChannels();
1290}
1291
1292// Tests that UMAs are recorded when ICE restarts while the channel
1293// is connected.
1294TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1295 rtc::ScopedFakeClock clock;
1296 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1297
1298 CreateChannels();
1299 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1300 ep2_ch1()->receiving() &&
1301 ep2_ch1()->writable(),
1302 kDefaultTimeout, clock);
1303
1304 ep1_ch1()->SetIceParameters(kIceParams[2]);
1305 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1306 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001307 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1308 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001309 static_cast<int>(IceRestartState::CONNECTED)));
1310
1311 ep2_ch1()->SetIceParameters(kIceParams[3]);
1312 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1313 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001314 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1315 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001316 static_cast<int>(IceRestartState::CONNECTED)));
1317
1318 DestroyChannels();
1319}
1320
1321// Tests that UMAs are recorded when ICE restarts while the channel
1322// is connecting.
1323TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1324 rtc::ScopedFakeClock clock;
1325 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1326
1327 // Create the channels without waiting for them to become connected.
1328 CreateChannels();
1329
1330 ep1_ch1()->SetIceParameters(kIceParams[2]);
1331 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1332 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001333 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1334 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001335 static_cast<int>(IceRestartState::CONNECTING)));
1336
1337 ep2_ch1()->SetIceParameters(kIceParams[3]);
1338 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1339 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001340 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1341 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001342 static_cast<int>(IceRestartState::CONNECTING)));
1343
1344 DestroyChannels();
1345}
1346
1347// Tests that a UMA on ICE regathering is recorded when there is a network
1348// change if and only if continual gathering is enabled.
1349TEST_F(P2PTransportChannelTest,
1350 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1351 rtc::ScopedFakeClock clock;
1352 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1353
1354 // ep1 gathers continually but ep2 does not.
1355 IceConfig continual_gathering_config =
1356 CreateIceConfig(1000, GATHER_CONTINUALLY);
1357 IceConfig default_config;
1358 CreateChannels(continual_gathering_config, default_config);
1359
1360 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1361 ep2_ch1()->receiving() &&
1362 ep2_ch1()->writable(),
1363 kDefaultTimeout, clock);
1364
1365 // Adding address in ep1 will trigger continual gathering.
1366 AddAddress(0, kAlternateAddrs[0]);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001367 EXPECT_EQ_SIMULATED_WAIT(1,
1368 GetEndpoint(0)->GetIceRegatheringCountForReason(
1369 IceRegatheringReason::NETWORK_CHANGE),
1370 kDefaultTimeout, clock);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001371
1372 ep2_ch1()->SetIceParameters(kIceParams[3]);
1373 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1374 ep2_ch1()->MaybeStartGathering();
1375
1376 AddAddress(1, kAlternateAddrs[1]);
1377 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1378 // ep2 has not enabled continual gathering.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001379 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1380 IceRegatheringReason::NETWORK_CHANGE));
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001381
1382 DestroyChannels();
1383}
1384
1385// Tests that a UMA on ICE regathering is recorded when there is a network
1386// failure if and only if continual gathering is enabled.
1387TEST_F(P2PTransportChannelTest,
1388 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1389 rtc::ScopedFakeClock clock;
1390 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1391
1392 // ep1 gathers continually but ep2 does not.
1393 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001394 config1.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001395 IceConfig config2;
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001396 config2.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001397 CreateChannels(config1, config2);
1398
1399 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1400 ep2_ch1()->receiving() &&
1401 ep2_ch1()->writable(),
1402 kDefaultTimeout, clock);
1403
1404 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1405 // Timeout value such that all connections are deleted.
1406 const int kNetworkFailureTimeout = 35000;
1407 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001408 EXPECT_LE(1, GetEndpoint(0)->GetIceRegatheringCountForReason(
1409 IceRegatheringReason::NETWORK_FAILURE));
1410 EXPECT_LE(1, webrtc::metrics::NumEvents(
1411 "WebRTC.PeerConnection.IceRegatheringReason",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001412 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001413 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1414 IceRegatheringReason::NETWORK_FAILURE));
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001415
1416 DestroyChannels();
1417}
1418
Steve Anton300bf8e2017-07-14 10:13:10 -07001419// Tests that ICE regathering occurs regularly when
1420// regather_all_networks_interval_range configuration value is set.
1421TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
1422 rtc::ScopedFakeClock clock;
1423 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1424
1425 // ep1 gathers continually but ep2 does not.
1426 const int kRegatherInterval = 2000;
1427 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Yves Gerey665174f2018-06-19 15:03:05 +02001428 config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
1429 kRegatherInterval);
Steve Anton300bf8e2017-07-14 10:13:10 -07001430 IceConfig config2;
Steve Anton300bf8e2017-07-14 10:13:10 -07001431 CreateChannels(config1, config2);
1432
1433 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1434 ep2_ch1()->receiving() &&
1435 ep2_ch1()->writable(),
1436 kDefaultTimeout, clock);
1437
1438 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1439 // Timeout value such that all connections are deleted.
1440 const int kNetworkGatherDuration = 11000;
1441 SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
1442 // Expect regathering to happen 5 times in 11s with 2s interval.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001443 EXPECT_LE(5, GetEndpoint(0)->GetIceRegatheringCountForReason(
1444 IceRegatheringReason::OCCASIONAL_REFRESH));
1445 EXPECT_LE(5, webrtc::metrics::NumEvents(
1446 "WebRTC.PeerConnection.IceRegatheringReason",
Steve Anton300bf8e2017-07-14 10:13:10 -07001447 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1448 // Expect no regathering if continual gathering not configured.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001449 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1450 IceRegatheringReason::OCCASIONAL_REFRESH));
Steve Anton300bf8e2017-07-14 10:13:10 -07001451
1452 DestroyChannels();
1453}
1454
1455// Test that ICE periodic regathering can change the selected connection on the
1456// specified interval and that the peers can communicate over the new
1457// connection. The test is parameterized to test that it works when regathering
1458// is done by the ICE controlling peer and when done by the controlled peer.
1459class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
1460 protected:
1461 void TestWithRoles(IceRole p1_role, IceRole p2_role) {
1462 rtc::ScopedFakeClock clock;
1463 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Yves Gerey665174f2018-06-19 15:03:05 +02001464 kDefaultPortAllocatorFlags);
Steve Anton300bf8e2017-07-14 10:13:10 -07001465 set_force_relay(true);
1466
1467 const int kRegatherInterval = 2000;
1468 const int kNumRegathers = 2;
1469
1470 // Set up peer 1 to auto regather every 2s.
1471 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Yves Gerey665174f2018-06-19 15:03:05 +02001472 config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
1473 kRegatherInterval);
Steve Anton300bf8e2017-07-14 10:13:10 -07001474 IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1475
1476 // Set peer roles.
1477 SetIceRole(0, p1_role);
1478 SetIceRole(1, p2_role);
1479
1480 CreateChannels(config1, config2);
1481
1482 // Wait for initial connection to be made.
Yves Gerey665174f2018-06-19 15:03:05 +02001483 EXPECT_TRUE_SIMULATED_WAIT(
1484 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1485 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1486 kMediumTimeout, clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001487
1488 const Connection* initial_selected = ep1_ch1()->selected_connection();
1489
1490 // Wait long enough for 2 regathering cycles to happen plus some extra so
1491 // the new connection has time to settle.
1492 const int kWaitRegather =
1493 kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
1494 SIMULATED_WAIT(false, kWaitRegather, clock);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001495 EXPECT_EQ(kNumRegathers, GetEndpoint(0)->GetIceRegatheringCountForReason(
1496 IceRegatheringReason::OCCASIONAL_REFRESH));
Steve Anton300bf8e2017-07-14 10:13:10 -07001497
1498 const Connection* new_selected = ep1_ch1()->selected_connection();
1499
1500 // Want the new selected connection to be different.
1501 ASSERT_NE(initial_selected, new_selected);
1502
1503 // Make sure we can communicate over the new connection too.
Steve Antone9324572017-11-29 10:18:21 -08001504 TestSendRecv(&clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001505 }
1506};
1507
1508TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
1509 TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
1510}
1511
1512TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
1513 TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
1514}
1515
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001516// Test that we properly create a connection on a STUN ping from unknown address
1517// when the signaling is slow.
1518TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001519 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001520 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001521 // Emulate no remote parameters coming in.
1522 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001523 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001524 // Only have remote parameters come in for ep2, not ep1.
1525 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001526
1527 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1528 // candidate.
1529 PauseCandidates(1);
1530
Honghai Zhange05bcc22016-08-16 18:19:14 -07001531 // Wait until the callee becomes writable to make sure that a ping request is
1532 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001533 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001534 // Add two sets of remote ICE credentials, so that the ones used by the
1535 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001536 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1537 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001538 // The caller should have the selected connection connected to the peer
1539 // reflexive candidate.
1540 const Connection* selected_connection = nullptr;
1541 ASSERT_TRUE_WAIT(
1542 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001543 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001544 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001545 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1546 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1547 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001548
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001549 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001550 // Verify ep1's selected connection is updated to use the 'local' candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001551 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001552 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001553 kMediumTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001554 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001555 DestroyChannels();
1556}
1557
1558// Test that we properly create a connection on a STUN ping from unknown address
1559// when the signaling is slow and the end points are behind NAT.
1560TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001561 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001562 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001563 // Emulate no remote parameters coming in.
1564 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001565 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001566 // Only have remote parameters come in for ep2, not ep1.
1567 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001568 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1569 // candidate.
1570 PauseCandidates(1);
1571
Honghai Zhange05bcc22016-08-16 18:19:14 -07001572 // Wait until the callee becomes writable to make sure that a ping request is
1573 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001574 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001575 // Add two sets of remote ICE credentials, so that the ones used by the
1576 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001577 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1578 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001579
1580 // The caller's selected connection should be connected to the peer reflexive
1581 // candidate.
1582 const Connection* selected_connection = nullptr;
1583 ASSERT_TRUE_WAIT(
1584 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001585 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001586 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001587 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1588 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1589 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001590
1591 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001592
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001593 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhange05bcc22016-08-16 18:19:14 -07001594 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001595 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001596 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001597 DestroyChannels();
1598}
1599
deadbeef0af180b2016-06-21 13:15:32 -07001600// Test that we properly create a connection on a STUN ping from unknown address
1601// when the signaling is slow, even if the new candidate is created due to the
1602// remote peer doing an ICE restart, pairing this candidate across generations.
1603//
1604// Previously this wasn't working due to a bug where the peer reflexive
1605// candidate was only updated for the newest generation candidate pairs, and
1606// not older-generation candidate pairs created by pairing candidates across
1607// generations. This resulted in the old-generation prflx candidate being
1608// prioritized above new-generation candidate pairs.
1609TEST_F(P2PTransportChannelTest,
1610 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1611 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1612 kDefaultPortAllocatorFlags);
1613 // Only gather relay candidates, so that when the prflx candidate arrives
1614 // it's prioritized above the current candidate pair.
Qingsi Wangc129c352019-04-18 10:41:58 -07001615 GetEndpoint(0)->allocator_->SetCandidateFilter(CF_RELAY);
1616 GetEndpoint(1)->allocator_->SetCandidateFilter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001617 // Setting this allows us to control when SetRemoteIceParameters is called.
1618 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001619 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001620 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001621 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1622 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001623 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1624 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1625 kDefaultTimeout);
1626
1627 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001628 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001629 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001630 ep2_ch1()->SetIceParameters(kIceParams[3]);
1631
1632 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001633 ep2_ch1()->MaybeStartGathering();
1634
Honghai Zhang572b0942016-06-23 12:26:57 -07001635 // The caller should have the selected connection connected to the peer
1636 // reflexive candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001637 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001638 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001639 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001640 const Connection* prflx_selected_connection =
1641 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001642
1643 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001644 ep1_ch1()->SetIceParameters(kIceParams[2]);
1645
1646 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001647 ep1_ch1()->MaybeStartGathering();
1648
1649 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1650 // their information to update the peer reflexive candidate.
1651 ResumeCandidates(1);
1652
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001653 EXPECT_EQ_WAIT(RELAY_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001654 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001655 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001656 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001657 DestroyChannels();
1658}
1659
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001660// Test that if remote candidates don't have ufrag and pwd, we still work.
1661TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001662 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001663 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001664 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001665 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001666 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001667 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001668 // Wait until the callee's connections are created.
Honghai Zhang161a5862016-10-20 11:47:02 -07001669 EXPECT_TRUE_SIMULATED_WAIT(
1670 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1671 kMediumTimeout, clock);
1672 // Wait to make sure the selected connection is not changed.
1673 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1674 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001675 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001676 DestroyChannels();
1677}
1678
1679// Test that a host behind NAT cannot be reached when incoming_only
1680// is set to true.
1681TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
honghaize58d73d2016-10-24 16:38:26 -07001682 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001683 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001684 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001685
1686 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001687 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001688 ep1_ch1()->set_incoming_only(true);
1689
1690 // Pump for 1 second and verify that the channels are not connected.
honghaize58d73d2016-10-24 16:38:26 -07001691 SIMULATED_WAIT(false, kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001692
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001693 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001694 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001695 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001696 EXPECT_FALSE(ep2_ch1()->writable());
1697
1698 DestroyChannels();
1699}
1700
1701// Test that a peer behind NAT can connect to a peer that has
1702// incoming_only flag set.
1703TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
honghaize58d73d2016-10-24 16:38:26 -07001704 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001705 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001706 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001707
1708 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001709 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001710 ep1_ch1()->set_incoming_only(true);
1711
honghaize58d73d2016-10-24 16:38:26 -07001712 EXPECT_TRUE_SIMULATED_WAIT(
1713 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1714 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1715 ep2_ch1()->writable(),
1716 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001717
1718 DestroyChannels();
1719}
1720
deadbeef1ee21252017-06-13 15:49:45 -07001721// Test that two peers can connect when one can only make outgoing TCP
1722// connections. This has been observed in some scenarios involving
1723// VPNs/firewalls.
1724TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
Mirko Bonadei5f4d47b2018-08-22 17:41:22 +00001725 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1726 // application needs this use case to work, since the application must accept
1727 // the tradeoff that more candidates need to be allocated.
1728 //
1729 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1730 // things to ensure extra candidates don't waste resources?
1731 ConfigureEndpoints(
1732 OPEN, OPEN,
1733 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1734 kDefaultPortAllocatorFlags);
deadbeef1ee21252017-06-13 15:49:45 -07001735 // In order to simulate nothing working but outgoing TCP connections, prevent
1736 // the endpoint from binding to its interface's address as well as the
1737 // "any" addresses. It can then only make a connection by using "Connect()".
1738 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1739 kPublicAddrs[0].ipaddr()});
1740 CreateChannels();
1741 // Expect a "prflx" candidate on the side that can only make outgoing
1742 // connections, endpoint 0.
1743 Test(kPrflxTcpToLocalTcp);
1744 DestroyChannels();
1745}
1746
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001747TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
honghaize58d73d2016-10-24 16:38:26 -07001748 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001749 AddAddress(0, kPublicAddrs[0]);
1750 AddAddress(1, kPublicAddrs[1]);
1751
1752 SetAllocationStepDelay(0, kMinimumStepDelay);
1753 SetAllocationStepDelay(1, kMinimumStepDelay);
1754
deadbeef14f97f52016-06-22 17:14:15 -07001755 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1756 PORTALLOCATOR_DISABLE_STUN |
1757 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001758 // Disable all protocols except TCP.
1759 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1760 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1761
1762 SetAllowTcpListen(0, true); // actpass.
1763 SetAllowTcpListen(1, false); // active.
1764
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001765 // We want SetRemoteIceParameters to be called as it normally would.
1766 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001767 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001768 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001769
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001770 // Pause candidate so we could verify the candidate properties.
1771 PauseCandidates(0);
1772 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001773 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001774
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001775 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001776 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1777 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001778
1779 // Resume candidates.
1780 ResumeCandidates(0);
1781 ResumeCandidates(1);
1782
honghaize58d73d2016-10-24 16:38:26 -07001783 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1784 ep2_ch1()->receiving() &&
1785 ep2_ch1()->writable(),
1786 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001787 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1788 ep2_ch1()->selected_connection() &&
1789 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1790 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001791
Steve Antone9324572017-11-29 10:18:21 -08001792 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001793 DestroyChannels();
1794}
1795
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001796TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001797 AddAddress(0, kPublicAddrs[0]);
1798 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001799 TestSignalRoleConflict();
1800}
1801
1802// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1803// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001804TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
honghaize58d73d2016-10-24 16:38:26 -07001805 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001806 AddAddress(0, kPublicAddrs[0]);
1807 AddAddress(1, kPublicAddrs[1]);
1808
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001809 // Give the first connection the higher tiebreaker so its role won't
1810 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001811 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001812 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001813 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001814 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001815
johan02bd5122016-09-20 00:23:27 -07001816 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001817
honghaize58d73d2016-10-24 16:38:26 -07001818 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001819
deadbeef14f97f52016-06-22 17:14:15 -07001820 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001821 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001822 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001823 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001824 }
1825
deadbeef14f97f52016-06-22 17:14:15 -07001826 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001827 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001828
deadbeef14f97f52016-06-22 17:14:15 -07001829 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001830 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001831 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001832 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001833 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001834 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001835 }
1836
honghaize58d73d2016-10-24 16:38:26 -07001837 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1838 ep2_ch1()->receiving() &&
1839 ep2_ch1()->writable(),
1840 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001841
Honghai Zhang572b0942016-06-23 12:26:57 -07001842 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1843 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001844
Steve Antone9324572017-11-29 10:18:21 -08001845 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001846 DestroyChannels();
1847}
1848
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001849// Verify that we can set DSCP value and retrieve properly from P2PTC.
1850TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1851 AddAddress(0, kPublicAddrs[0]);
1852 AddAddress(1, kPublicAddrs[1]);
1853
johan02bd5122016-09-20 00:23:27 -07001854 CreateChannels();
Yves Gerey665174f2018-06-19 15:03:05 +02001855 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1856 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1857 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1858 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1859 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1860 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1861 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1862 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1863 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1864 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001865}
1866
1867// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001868TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
honghaize58d73d2016-10-24 16:38:26 -07001869 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001870 AddAddress(0, kIPv6PublicAddrs[0]);
1871 AddAddress(0, kPublicAddrs[0]);
1872 AddAddress(1, kIPv6PublicAddrs[1]);
1873 AddAddress(1, kPublicAddrs[1]);
1874
1875 SetAllocationStepDelay(0, kMinimumStepDelay);
1876 SetAllocationStepDelay(1, kMinimumStepDelay);
1877
1878 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08001879 SetAllocatorFlags(
1880 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1881 SetAllocatorFlags(
1882 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001883
johan02bd5122016-09-20 00:23:27 -07001884 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001885
honghaize58d73d2016-10-24 16:38:26 -07001886 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1887 ep2_ch1()->receiving() &&
1888 ep2_ch1()->writable(),
1889 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001890 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001891 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001892 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1893 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1894
Steve Antone9324572017-11-29 10:18:21 -08001895 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001896 DestroyChannels();
1897}
1898
1899// Testing forceful TURN connections.
1900TEST_F(P2PTransportChannelTest, TestForceTurn) {
honghaize58d73d2016-10-24 16:38:26 -07001901 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001902 ConfigureEndpoints(
1903 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001904 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1905 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001906 set_force_relay(true);
1907
1908 SetAllocationStepDelay(0, kMinimumStepDelay);
1909 SetAllocationStepDelay(1, kMinimumStepDelay);
1910
johan02bd5122016-09-20 00:23:27 -07001911 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001912
honghaize58d73d2016-10-24 16:38:26 -07001913 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1914 ep2_ch1()->receiving() &&
1915 ep2_ch1()->writable(),
1916 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001917
Honghai Zhang572b0942016-06-23 12:26:57 -07001918 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1919 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001920
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001921 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1922 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1923 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type());
1924 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001925
Steve Antone9324572017-11-29 10:18:21 -08001926 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001927 DestroyChannels();
1928}
1929
honghaiz98db68f2015-09-29 07:58:17 -07001930// Test that if continual gathering is set to true, ICE gathering state will
1931// not change to "Complete", and vice versa.
1932TEST_F(P2PTransportChannelTest, TestContinualGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001933 rtc::ScopedFakeClock clock;
honghaiz98db68f2015-09-29 07:58:17 -07001934 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1935 kDefaultPortAllocatorFlags);
1936 SetAllocationStepDelay(0, kDefaultStepDelay);
1937 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07001938 IceConfig continual_gathering_config =
1939 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07001940 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07001941 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07001942 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07001943
Honghai Zhang161a5862016-10-20 11:47:02 -07001944 EXPECT_TRUE_SIMULATED_WAIT(
1945 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1946 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1947 ep2_ch1()->writable(),
1948 kMediumTimeout, clock);
1949 SIMULATED_WAIT(
1950 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
1951 kShortTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07001952 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07001953 ep1_ch1()->gathering_state());
1954 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07001955 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07001956 ep2_ch1()->gathering_state());
1957
1958 DestroyChannels();
1959}
1960
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001961// Test that a connection succeeds when the P2PTransportChannel uses a pooled
1962// PortAllocatorSession that has not yet finished gathering candidates.
1963TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001964 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001965 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1966 kDefaultPortAllocatorFlags);
1967 // First create a pooled session for each endpoint.
1968 auto& allocator_1 = GetEndpoint(0)->allocator_;
1969 auto& allocator_2 = GetEndpoint(1)->allocator_;
1970 int pool_size = 1;
1971 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001972 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001973 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07001974 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07001975 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001976 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07001977 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001978 allocator_2->GetPooledSession();
1979 ASSERT_NE(nullptr, pooled_session_1);
1980 ASSERT_NE(nullptr, pooled_session_2);
1981 // Sanity check that pooled sessions haven't gathered anything yet.
1982 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
1983 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
1984 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
1985 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
1986 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07001987 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07001988 EXPECT_TRUE_SIMULATED_WAIT(
1989 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1990 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1991 ep2_ch1()->writable(),
1992 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001993 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001994 // Make sure the P2PTransportChannels are actually using ports from the
1995 // pooled sessions.
1996 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
1997 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
Steve Antonae226f62019-01-29 12:47:38 -08001998 EXPECT_THAT(pooled_ports_1,
1999 Contains(ep1_ch1()->selected_connection()->port()));
2000 EXPECT_THAT(pooled_ports_2,
2001 Contains(ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002002}
2003
2004// Test that a connection succeeds when the P2PTransportChannel uses a pooled
2005// PortAllocatorSession that already finished gathering candidates.
2006TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002007 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002008 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2009 kDefaultPortAllocatorFlags);
2010 // First create a pooled session for each endpoint.
2011 auto& allocator_1 = GetEndpoint(0)->allocator_;
2012 auto& allocator_2 = GetEndpoint(1)->allocator_;
2013 int pool_size = 1;
2014 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07002015 allocator_1->turn_servers(), pool_size, false);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002016 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -07002017 allocator_2->turn_servers(), pool_size, false);
deadbeef14f97f52016-06-22 17:14:15 -07002018 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002019 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07002020 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002021 allocator_2->GetPooledSession();
2022 ASSERT_NE(nullptr, pooled_session_1);
2023 ASSERT_NE(nullptr, pooled_session_2);
2024 // Wait for the pooled sessions to finish gathering before the
2025 // P2PTransportChannels try to use them.
Honghai Zhang161a5862016-10-20 11:47:02 -07002026 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
2027 pooled_session_2->CandidatesAllocationDone(),
2028 kDefaultTimeout, clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002029 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07002030 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07002031 EXPECT_TRUE_SIMULATED_WAIT(
2032 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
2033 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2034 ep2_ch1()->writable(),
2035 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08002036 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002037 // Make sure the P2PTransportChannels are actually using ports from the
2038 // pooled sessions.
2039 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2040 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
Steve Antonae226f62019-01-29 12:47:38 -08002041 EXPECT_THAT(pooled_ports_1,
2042 Contains(ep1_ch1()->selected_connection()->port()));
2043 EXPECT_THAT(pooled_ports_2,
2044 Contains(ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002045}
2046
deadbeef14f97f52016-06-22 17:14:15 -07002047// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07002048// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07002049// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07002050// TODO(deadbeef): Move this and other "presumed writable" tests into a test
2051// class that operates on a single P2PTransportChannel, once an appropriate one
2052// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07002053TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
2054 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2055 kDefaultPortAllocatorFlags);
2056 // Only configure one channel so we can control when the remote candidate
2057 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002058 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2059 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07002060 IceConfig config;
2061 config.presume_writable_when_fully_relayed = true;
2062 ep1_ch1()->SetIceConfig(config);
2063 ep1_ch1()->MaybeStartGathering();
2064 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2065 ep1_ch1()->gathering_state(), kDefaultTimeout);
2066 // Add two remote candidates; a host candidate (with higher priority)
2067 // and TURN candidate.
2068 ep1_ch1()->AddRemoteCandidate(
2069 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2070 ep1_ch1()->AddRemoteCandidate(
2071 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2072 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2073 // "probably writable".
Honghai Zhang572b0942016-06-23 12:26:57 -07002074 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07002075 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2076 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2077 // Also expect that the channel instantly indicates that it's writable since
2078 // it has a TURN-TURN pair.
2079 EXPECT_TRUE(ep1_ch1()->writable());
2080 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002081 // Also make sure we can immediately send packets.
2082 const char* data = "test";
2083 int len = static_cast<int>(strlen(data));
2084 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07002085}
2086
Taylor Brandstetteref184702016-06-23 17:35:47 -07002087// Test that a TURN/peer reflexive candidate pair is also presumed writable.
2088TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
2089 rtc::ScopedFakeClock fake_clock;
2090
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002091 // We need to add artificial network delay to verify that the connection
2092 // is presumed writable before it's actually writable. Without this delay
2093 // it would become writable instantly.
2094 virtual_socket_server()->set_delay_mean(50);
2095 virtual_socket_server()->UpdateDelayDistribution();
2096
Taylor Brandstetteref184702016-06-23 17:35:47 -07002097 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2098 kDefaultPortAllocatorFlags);
2099 // We want the remote TURN candidate to show up as prflx. To do this we need
2100 // to configure the server to accept packets from an address we haven't
2101 // explicitly installed permission for.
2102 test_turn_server()->set_enable_permission_checks(false);
2103 IceConfig config;
2104 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002105 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2106 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2107 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2108 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07002109 ep1_ch1()->SetIceConfig(config);
2110 ep2_ch1()->SetIceConfig(config);
2111 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2112 // candidate as peer reflexive.
2113 PauseCandidates(1);
2114 ep1_ch1()->MaybeStartGathering();
2115 ep2_ch1()->MaybeStartGathering();
2116
2117 // Wait for the TURN<->prflx connection.
2118 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002119 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002120 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2121 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2122 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2123 // Make sure that at this point the connection is only presumed writable,
2124 // not fully writable.
2125 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2126
2127 // Now wait for it to actually become writable.
Honghai Zhang161a5862016-10-20 11:47:02 -07002128 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2129 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002130
2131 // Explitly destroy channels, before fake clock is destroyed.
2132 DestroyChannels();
2133}
2134
deadbeef14f97f52016-06-22 17:14:15 -07002135// Test that a presumed-writable TURN<->TURN connection is preferred above an
2136// unreliable connection (one that has failed to be pinged for some time).
2137TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
2138 rtc::ScopedFakeClock fake_clock;
2139
2140 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2141 kDefaultPortAllocatorFlags);
2142 IceConfig config;
2143 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002144 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2145 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2146 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2147 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07002148 ep1_ch1()->SetIceConfig(config);
2149 ep2_ch1()->SetIceConfig(config);
2150 ep1_ch1()->MaybeStartGathering();
2151 ep2_ch1()->MaybeStartGathering();
2152 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07002153 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2154 ep1_ch1()->selected_connection()->writable() &&
2155 ep2_ch1()->receiving() &&
2156 ep2_ch1()->writable() &&
2157 ep2_ch1()->selected_connection()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002158 kShortTimeout, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002159 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07002160 // Destroy the second channel and wait for the current connection on the
2161 // first channel to become "unreliable", making it no longer writable.
2162 GetEndpoint(1)->cd1_.ch_.reset();
Honghai Zhang161a5862016-10-20 11:47:02 -07002163 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2164 fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002165 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002166 // Add a remote TURN candidate. The first channel should still have a TURN
2167 // port available to make a TURN<->TURN pair that's presumed writable.
2168 ep1_ch1()->AddRemoteCandidate(
2169 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2170 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2171 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2172 EXPECT_TRUE(ep1_ch1()->writable());
2173 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07002174 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002175 // Explitly destroy channels, before fake clock is destroyed.
2176 DestroyChannels();
2177}
2178
deadbeefdd7fb432016-09-30 15:16:48 -07002179// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2180// writable" connection. Previously this did not work.
2181TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
2182 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2183 kDefaultPortAllocatorFlags);
2184 // Only test one endpoint, so we can ensure the connection doesn't receive a
2185 // binding response and advance beyond being "presumed" writable.
2186 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2187 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2188 IceConfig config;
2189 config.presume_writable_when_fully_relayed = true;
2190 ep1_ch1()->SetIceConfig(config);
2191 ep1_ch1()->MaybeStartGathering();
2192 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2193 ep1_ch1()->gathering_state(), kDefaultTimeout);
2194 ep1_ch1()->AddRemoteCandidate(
2195 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2196 // Sanity checking the type of the connection.
2197 EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
2198 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2199 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2200
2201 // Tell the socket server to block packets (returning EWOULDBLOCK).
2202 virtual_socket_server()->SetSendingBlocked(true);
2203 const char* data = "test";
2204 int len = static_cast<int>(strlen(data));
2205 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2206
2207 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2208 // should.
2209 GetEndpoint(0)->ready_to_send_ = false;
2210 virtual_socket_server()->SetSendingBlocked(false);
2211 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2212 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2213}
2214
Qingsi Wang2bd41f92018-03-23 14:28:37 -07002215// Test that role conflict error responses are sent as expected when receiving a
2216// ping from an unknown address over a TURN connection. Regression test for
2217// crbug.com/webrtc/9034.
2218TEST_F(P2PTransportChannelTest,
2219 TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict) {
2220 rtc::ScopedFakeClock clock;
2221 // Gather only relay candidates.
2222 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC,
2223 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2224 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP,
2225 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2226 PORTALLOCATOR_DISABLE_STUN |
2227 PORTALLOCATOR_DISABLE_TCP);
2228 // With conflicting ICE roles, endpoint 1 has the higher tie breaker and will
2229 // send a binding error response.
2230 SetIceRole(0, ICEROLE_CONTROLLING);
2231 SetIceTiebreaker(0, kHighTiebreaker);
2232 SetIceRole(1, ICEROLE_CONTROLLING);
2233 SetIceTiebreaker(1, kLowTiebreaker);
2234 // We want the remote TURN candidate to show up as prflx. To do this we need
2235 // to configure the server to accept packets from an address we haven't
2236 // explicitly installed permission for.
2237 test_turn_server()->set_enable_permission_checks(false);
2238 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2239 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2240 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2241 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
2242 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2243 // candidate as peer reflexive.
2244 PauseCandidates(1);
2245 ep1_ch1()->MaybeStartGathering();
2246 ep2_ch1()->MaybeStartGathering();
2247
2248 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
2249 kMediumTimeout, clock);
2250
2251 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2252
2253 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2254 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2255
2256 DestroyChannels();
2257}
2258
Qingsi Wang0894f0f2019-06-18 14:11:36 -07002259// Test that the writability can be established with the piggyback
2260// acknowledgement in the connectivity check from the remote peer.
2261TEST_F(P2PTransportChannelTest,
2262 CanConnectWithPiggybackCheckAcknowledgementWhenCheckResponseBlocked) {
2263 webrtc::test::ScopedFieldTrials field_trials(
2264 "WebRTC-PiggybackCheckAcknowledgement/Enabled/");
2265 rtc::ScopedFakeClock clock;
2266 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
2267 IceConfig ep1_config;
2268 IceConfig ep2_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2269 // Let ep2 be tolerable of the loss of connectivity checks, so that it keeps
2270 // sending pings even after ep1 becomes unwritable as we configure the
2271 // firewall below.
2272 ep2_config.receiving_timeout = 30 * 1000;
2273 ep2_config.ice_unwritable_timeout = 30 * 1000;
2274 ep2_config.ice_unwritable_min_checks = 30;
2275 ep2_config.ice_inactive_timeout = 60 * 1000;
2276
2277 CreateChannels(ep1_config, ep2_config);
2278
2279 // Wait until both sides become writable for the first time.
2280 EXPECT_TRUE_SIMULATED_WAIT(
2281 ep1_ch1() != nullptr && ep2_ch1() != nullptr && ep1_ch1()->receiving() &&
2282 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2283 ep2_ch1()->writable(),
2284 kDefaultTimeout, clock);
2285 // Block the ingress traffic to ep1 so that there is no check response from
2286 // ep2.
2287 ASSERT_NE(nullptr, LocalCandidate(ep1_ch1()));
2288 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_IN,
2289 LocalCandidate(ep1_ch1())->address());
2290 // Wait until ep1 becomes unwritable. At the same time ep2 should be still
2291 // fine so that it will keep sending pings.
2292 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && !ep1_ch1()->writable(),
2293 kDefaultTimeout, clock);
2294 EXPECT_TRUE(ep2_ch1() != nullptr && ep2_ch1()->writable());
2295 // Now let the pings from ep2 to flow but block any pings from ep1, so that
2296 // ep1 can only become writable again after receiving an incoming ping from
2297 // ep2 with piggyback acknowledgement of its previously sent pings. Note
2298 // though that ep1 should have stopped sending pings after becoming unwritable
2299 // in the current design.
2300 fw()->ClearRules();
2301 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_OUT,
2302 LocalCandidate(ep1_ch1())->address());
2303 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && ep1_ch1()->writable(),
2304 kDefaultTimeout, clock);
2305 DestroyChannels();
2306}
2307
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002308// Test what happens when we have 2 users behind the same NAT. This can lead
2309// to interesting behavior because the STUN server will only give out the
2310// address of the outermost NAT.
2311class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2312 protected:
2313 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
kwibergee89e782017-08-09 17:22:01 -07002314 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2315 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
Yves Gerey665174f2018-06-19 15:03:05 +02002316 rtc::NATSocketServer::Translator* outer_nat = nat()->AddTranslator(
2317 kPublicAddrs[0], kNatAddrs[0],
2318 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002319 ConfigureEndpoint(outer_nat, 0, config1);
2320 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002321 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002322 }
2323 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
Yves Gerey665174f2018-06-19 15:03:05 +02002324 int endpoint,
2325 Config config) {
nissec8ee8822017-01-18 07:20:55 -08002326 RTC_CHECK(config <= NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002327 if (config == OPEN) {
2328 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2329 nat->AddClient(kPrivateAddrs[endpoint]);
2330 } else {
2331 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2332 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
Yves Gerey665174f2018-06-19 15:03:05 +02002333 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
2334 ->AddClient(kCascadedPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002335 }
2336 }
2337};
2338
2339TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2340 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002341 Test(
2342 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002343}
2344
2345// Test what happens when we have multiple available pathways.
2346// In the future we will try different RTTs and configs for the different
2347// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2348class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002349 public:
honghaiz7252a002016-11-08 20:04:09 -08002350 const Connection* GetConnectionWithRemoteAddress(
2351 P2PTransportChannel* channel,
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002352 const SocketAddress& address) {
honghaiz7252a002016-11-08 20:04:09 -08002353 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002354 if (conn->remote_candidate().address().EqualIPs(address)) {
2355 return conn;
2356 }
2357 }
2358 return nullptr;
2359 }
2360
honghaiz7252a002016-11-08 20:04:09 -08002361 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2362 const SocketAddress& address) {
2363 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002364 if (conn->local_candidate().address().EqualIPs(address)) {
2365 return conn;
2366 }
2367 }
2368 return nullptr;
2369 }
2370
honghaiz7252a002016-11-08 20:04:09 -08002371 Connection* GetConnection(P2PTransportChannel* channel,
2372 const SocketAddress& local,
2373 const SocketAddress& remote) {
2374 for (Connection* conn : channel->connections()) {
2375 if (conn->local_candidate().address().EqualIPs(local) &&
2376 conn->remote_candidate().address().EqualIPs(remote)) {
2377 return conn;
2378 }
2379 }
2380 return nullptr;
2381 }
2382
2383 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2384 const Connection* selected_connection = channel->selected_connection();
2385 for (Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002386 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002387 conn->Destroy();
2388 }
2389 }
2390 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002391};
2392
2393// Test that we can establish connectivity when both peers are multihomed.
zhihuanga3095d02016-11-10 13:59:46 -08002394TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002395 AddAddress(0, kPublicAddrs[0]);
2396 AddAddress(0, kAlternateAddrs[0]);
2397 AddAddress(1, kPublicAddrs[1]);
2398 AddAddress(1, kAlternateAddrs[1]);
2399 Test(kLocalUdpToLocalUdp);
2400}
2401
Honghai Zhang52dce732016-03-31 12:37:31 -07002402// Test that we can quickly switch links if an interface goes down.
2403// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002404TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002405 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002406 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002407 // Simulate failing over from Wi-Fi to cell interface.
2408 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2409 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002410
2411 // Use only local ports for simplicity.
2412 SetAllocatorFlags(0, kOnlyLocalPorts);
2413 SetAllocatorFlags(1, kOnlyLocalPorts);
2414
deadbeefb60a8192016-08-24 15:15:00 -07002415 // Make the receiving timeout shorter for testing.
2416 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002417 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002418 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002419
honghaiz9ad0db52016-07-14 19:30:28 -07002420 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2421 ep2_ch1()->receiving() &&
2422 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002423 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002424 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2425 ep2_ch1()->selected_connection() &&
2426 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2427 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002428
2429 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002430 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002431 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002432 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002433 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2434 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002435 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002436 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002437 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002438 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002439
honghaiz9ad0db52016-07-14 19:30:28 -07002440 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002441 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002442 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2443 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002444 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002445 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2446 EXPECT_TRUE(
2447 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2448 EXPECT_TRUE(
2449 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2450
2451 DestroyChannels();
2452}
2453
Honghai Zhang52dce732016-03-31 12:37:31 -07002454// Test that we can quickly switch links if an interface goes down.
2455// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002456TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002457 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002458 // Simulate failing over from Wi-Fi to cell interface.
2459 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2460 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiza58ea782015-09-24 08:13:36 -07002461 AddAddress(1, kPublicAddrs[1]);
2462
2463 // Use only local ports for simplicity.
2464 SetAllocatorFlags(0, kOnlyLocalPorts);
2465 SetAllocatorFlags(1, kOnlyLocalPorts);
2466
deadbeefb60a8192016-08-24 15:15:00 -07002467 // Make the receiving timeout shorter for testing.
2468 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002469 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002470 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002471 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2472 ep2_ch1()->receiving() &&
2473 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002474 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002475 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2476 ep2_ch1()->selected_connection() &&
2477 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2478 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002479
2480 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002481 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002482 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002483 // The selected connections will switch, so keep references to them.
2484 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2485 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002486 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002487 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002488 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002489 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002490
honghaiz9ad0db52016-07-14 19:30:28 -07002491 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002492 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002493 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2494 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002495 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002496 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02002497 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
honghaiza58ea782015-09-24 08:13:36 -07002498 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2499 EXPECT_TRUE(
2500 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002501
2502 DestroyChannels();
2503}
2504
honghaiz7252a002016-11-08 20:04:09 -08002505// Tests that we can quickly switch links if an interface goes down when
2506// there are many connections.
2507TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2508 rtc::ScopedFakeClock clock;
2509 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
2510 RelayServerConfig turn_server(RELAY_TURN);
2511 turn_server.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08002512 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
honghaiz7252a002016-11-08 20:04:09 -08002513 GetAllocator(0)->AddTurnServer(turn_server);
2514 GetAllocator(1)->AddTurnServer(turn_server);
2515 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08002516 SetAllocatorFlags(
2517 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2518 SetAllocatorFlags(
2519 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002520 SetAllocationStepDelay(0, kMinimumStepDelay);
2521 SetAllocationStepDelay(1, kMinimumStepDelay);
2522
2523 auto& wifi = kPublicAddrs;
2524 auto& cellular = kAlternateAddrs;
2525 auto& wifiIpv6 = kIPv6PublicAddrs;
2526 auto& cellularIpv6 = kIPv6AlternateAddrs;
2527 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2528 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2529 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2530 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2531 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2532 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2533 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2534 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2535
2536 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2537 // will be created in time.
2538 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2539 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2540 virtual_socket_server()->set_delay_mean(500);
2541 virtual_socket_server()->UpdateDelayDistribution();
2542
2543 // Make the receiving timeout shorter for testing.
2544 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2545 // Create channels and let them go writable, as usual.
2546 CreateChannels(config, config, true /* ice_renomination */);
2547 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2548 ep2_ch1()->receiving() &&
2549 ep2_ch1()->writable(),
2550 kMediumTimeout, clock);
2551 EXPECT_TRUE_SIMULATED_WAIT(
2552 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
2553 LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
2554 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
2555 kMediumTimeout, clock);
2556
2557 // Blackhole any traffic to or from the wifi on endpoint 1.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002558 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz7252a002016-11-08 20:04:09 -08002559 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2560 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2561
2562 // The selected connections may switch, so keep references to them.
2563 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2564 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2565 EXPECT_TRUE_SIMULATED_WAIT(
2566 !selected_connection1->receiving() && !selected_connection2->receiving(),
2567 kMediumTimeout, clock);
2568
2569 // Per-network best connections will be pinged at relatively higher rate when
2570 // the selected connection becomes not receiving.
2571 Connection* per_network_best_connection1 =
2572 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2573 ASSERT_NE(nullptr, per_network_best_connection1);
2574 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2575 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2576 EXPECT_TRUE_SIMULATED_WAIT(
2577 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2578 kMediumTimeout, clock);
2579 int64_t ping_interval1 =
2580 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2581 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2582 constexpr int SCHEDULING_DELAY = 200;
2583 EXPECT_LT(
2584 ping_interval1,
2585 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2586
2587 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2588 // it timed out on writing.
2589 EXPECT_TRUE_SIMULATED_WAIT(
2590 ep1_ch1()->selected_connection()->receiving() &&
2591 ep2_ch1()->selected_connection()->receiving() &&
2592 RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
2593 LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
2594 kMediumTimeout, clock);
2595
2596 DestroyChannels();
2597}
2598
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002599// Test that when the controlling side switches the selected connection,
2600// the nomination of the selected connection on the controlled side will
2601// increase.
2602TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2603 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002604 // Simulate failing over from Wi-Fi to cell interface.
2605 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2606 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002607 AddAddress(1, kPublicAddrs[1]);
2608
2609 // Use only local ports for simplicity.
2610 SetAllocatorFlags(0, kOnlyLocalPorts);
2611 SetAllocatorFlags(1, kOnlyLocalPorts);
2612
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002613 // We want it to set the remote ICE parameters when creating channels.
2614 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002615 // Make the receiving timeout shorter for testing.
2616 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002617 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002618 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002619 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2620 ep2_ch1()->receiving() &&
2621 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002622 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002623 EXPECT_TRUE_SIMULATED_WAIT(
2624 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2625 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2626 kDefaultTimeout, clock);
2627 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2628 Connection* selected_connection2 =
2629 const_cast<Connection*>(ep2_ch1()->selected_connection());
2630 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2631 // |selected_connection2| should not be nominated any more since the previous
2632 // nomination has been acknowledged.
2633 ConnectSignalNominated(selected_connection2);
Honghai Zhang161a5862016-10-20 11:47:02 -07002634 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002635 EXPECT_FALSE(nominated());
2636
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002637 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002638 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002639 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2640
2641 // The selected connection on the controlling side should switch.
2642 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002643 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2644 clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002645 // The connection on the controlled side should be nominated again
2646 // and have an increased nomination.
2647 EXPECT_TRUE_SIMULATED_WAIT(
2648 ep2_ch1()->selected_connection()->remote_nomination() >
2649 remote_nomination2,
2650 kDefaultTimeout, clock);
2651
2652 DestroyChannels();
2653}
2654
honghaiz9ad0db52016-07-14 19:30:28 -07002655// Test that if an interface fails temporarily and then recovers quickly,
2656// the selected connection will not switch.
2657// The case that it will switch over to the backup connection if the selected
2658// connection does not recover after enough time is covered in
2659// TestFailoverControlledSide and TestFailoverControllingSide.
2660TEST_F(P2PTransportChannelMultihomedTest,
2661 TestConnectionSwitchDampeningControlledSide) {
2662 rtc::ScopedFakeClock clock;
2663 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002664 // Simulate failing over from Wi-Fi to cell interface.
2665 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2666 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002667
2668 // Use only local ports for simplicity.
2669 SetAllocatorFlags(0, kOnlyLocalPorts);
2670 SetAllocatorFlags(1, kOnlyLocalPorts);
2671
2672 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002673 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002674
2675 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2676 ep2_ch1()->receiving() &&
2677 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002678 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002679 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2680 ep2_ch1()->selected_connection() &&
2681 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2682 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2683
2684 // Make the receiving timeout shorter for testing.
2685 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2686 ep1_ch1()->SetIceConfig(config);
2687 ep2_ch1()->SetIceConfig(config);
2688 reset_selected_candidate_pair_switches();
2689
2690 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002691 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002692 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2693
2694 // The selected connections may switch, so keep references to them.
2695 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2696 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2697 // We should detect loss of receiving within 1 second or so.
2698 EXPECT_TRUE_SIMULATED_WAIT(
2699 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002700 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002701 // After a short while, the link recovers itself.
2702 SIMULATED_WAIT(false, 10, clock);
2703 fw()->ClearRules();
2704
2705 // We should remain on the public address on both sides and no connection
2706 // switches should have happened.
2707 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2708 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002709 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002710 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2711 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2712 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2713
2714 DestroyChannels();
2715}
2716
2717// Test that if an interface fails temporarily and then recovers quickly,
2718// the selected connection will not switch.
2719TEST_F(P2PTransportChannelMultihomedTest,
2720 TestConnectionSwitchDampeningControllingSide) {
2721 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002722 // Simulate failing over from Wi-Fi to cell interface.
2723 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2724 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002725 AddAddress(1, kPublicAddrs[1]);
2726
2727 // Use only local ports for simplicity.
2728 SetAllocatorFlags(0, kOnlyLocalPorts);
2729 SetAllocatorFlags(1, kOnlyLocalPorts);
2730
2731 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002732 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002733 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2734 ep2_ch1()->receiving() &&
2735 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002736 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002737 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2738 ep2_ch1()->selected_connection() &&
2739 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2740 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2741
2742 // Make the receiving timeout shorter for testing.
2743 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2744 ep1_ch1()->SetIceConfig(config);
2745 ep2_ch1()->SetIceConfig(config);
2746 reset_selected_candidate_pair_switches();
2747
2748 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002749 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002750 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2751 // The selected connections may switch, so keep references to them.
2752 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2753 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2754 // We should detect loss of receiving within 1 second or so.
2755 EXPECT_TRUE_SIMULATED_WAIT(
2756 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002757 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002758 // The link recovers after a short while.
2759 SIMULATED_WAIT(false, 10, clock);
2760 fw()->ClearRules();
2761
2762 // We should not switch to the alternate addr on both sides because of the
2763 // dampening.
2764 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2765 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002766 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002767 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2768 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2769 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2770 DestroyChannels();
2771}
2772
Honghai Zhangfd16da22016-08-17 16:12:46 -07002773// Tests that if the remote side's network failed, it won't cause the local
2774// side to switch connections and networks.
2775TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2776 rtc::ScopedFakeClock clock;
2777 // The interface names are chosen so that |cellular| would have higher
2778 // candidate priority and higher cost.
2779 auto& wifi = kPublicAddrs;
2780 auto& cellular = kAlternateAddrs;
2781 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2782 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2783 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2784
2785 // Use only local ports for simplicity.
2786 SetAllocatorFlags(0, kOnlyLocalPorts);
2787 SetAllocatorFlags(1, kOnlyLocalPorts);
2788 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002789 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002790 // Make the receiving timeout shorter for testing.
2791 // Set the backup connection ping interval to 25s.
2792 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2793 // Ping the best connection more frequently since we don't have traffic.
2794 config.stable_writable_connection_ping_interval = 900;
2795 ep1_ch1()->SetIceConfig(config);
2796 ep2_ch1()->SetIceConfig(config);
2797 // Need to wait to make sure the connections on both networks are writable.
2798 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2799 ep2_ch1()->receiving() &&
2800 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002801 kMediumTimeout, clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002802 EXPECT_TRUE_SIMULATED_WAIT(
2803 ep1_ch1()->selected_connection() &&
2804 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2805 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2806 kDefaultTimeout, clock);
2807 Connection* backup_conn =
2808 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2809 ASSERT_NE(nullptr, backup_conn);
2810 // After a short while, the backup connection will be writable but not
2811 // receiving because backup connection is pinged at a slower rate.
2812 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002813 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
2814 clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002815 reset_selected_candidate_pair_switches();
2816 // Blackhole any traffic to or from the remote WiFi networks.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002817 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhangfd16da22016-08-17 16:12:46 -07002818 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2819
2820 int num_switches = 0;
2821 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2822 20000, clock);
2823 EXPECT_EQ(0, num_switches);
2824 DestroyChannels();
2825}
2826
honghaize1a0c942016-02-16 14:54:56 -08002827// Tests that a Wifi-Wifi connection has the highest precedence.
2828TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2829 // The interface names are chosen so that |cellular| would have higher
2830 // candidate priority if it is not for the network type.
2831 auto& wifi = kAlternateAddrs;
2832 auto& cellular = kPublicAddrs;
2833 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2834 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2835 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2836 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2837
2838 // Use only local ports for simplicity.
2839 SetAllocatorFlags(0, kOnlyLocalPorts);
2840 SetAllocatorFlags(1, kOnlyLocalPorts);
2841
2842 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002843 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002844
2845 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2846 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2847 1000, 1000);
2848 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002849 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002850 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2851 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2852 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002853 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002854 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2855 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2856 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002857 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002858}
2859
2860// Tests that a Wifi-Cellular connection has higher precedence than
2861// a Cellular-Cellular connection.
2862TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2863 // The interface names are chosen so that |cellular| would have higher
2864 // candidate priority if it is not for the network type.
2865 auto& wifi = kAlternateAddrs;
2866 auto& cellular = kPublicAddrs;
2867 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2868 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2869 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2870
2871 // Use only local ports for simplicity.
2872 SetAllocatorFlags(0, kOnlyLocalPorts);
2873 SetAllocatorFlags(1, kOnlyLocalPorts);
2874
2875 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002876 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002877
2878 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2879 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2880 1000, 1000);
2881 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002882 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002883 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2884 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002885 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002886 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2887 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002888 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002889}
2890
Honghai Zhang381b4212015-12-04 12:24:03 -08002891// Test that the backup connection is pinged at a rate no faster than
2892// what was configured.
2893TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2894 AddAddress(0, kPublicAddrs[0]);
2895 // Adding alternate address will make sure |kPublicAddrs| has the higher
2896 // priority than others. This is due to FakeNetwork::AddInterface method.
2897 AddAddress(1, kAlternateAddrs[1]);
2898 AddAddress(1, kPublicAddrs[1]);
2899
2900 // Use only local ports for simplicity.
2901 SetAllocatorFlags(0, kOnlyLocalPorts);
2902 SetAllocatorFlags(1, kOnlyLocalPorts);
2903
2904 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002905 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002906 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2907 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2908 1000, 1000);
2909 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002910 ep2_ch1()->SetIceConfig(
2911 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002912 // After the state becomes COMPLETED, the backup connection will be pinged
2913 // once every |backup_ping_interval| milliseconds.
zhihuangd06adf62017-01-12 15:58:31 -08002914 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
2915 1000);
deadbeef14f97f52016-06-22 17:14:15 -07002916 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002917 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002918 Connection* backup_conn = connections[1];
Honghai Zhang161a5862016-10-20 11:47:02 -07002919 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
honghaiz34b11eb2016-03-16 08:55:44 -07002920 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002921 EXPECT_TRUE_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002922 last_ping_response_ms < backup_conn->last_ping_response_received(),
2923 kDefaultTimeout);
Honghai Zhang381b4212015-12-04 12:24:03 -08002924 int time_elapsed =
2925 backup_conn->last_ping_response_received() - last_ping_response_ms;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002926 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
Honghai Zhang381b4212015-12-04 12:24:03 -08002927 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002928
2929 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002930}
2931
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002932TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002933 rtc::ScopedFakeClock clock;
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002934 AddAddress(0, kAlternateAddrs[0]);
2935 AddAddress(0, kPublicAddrs[0]);
2936 AddAddress(1, kPublicAddrs[1]);
2937 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002938 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002939
2940 // Both transport channels will reach STATE_COMPLETED quickly.
zhihuangd06adf62017-01-12 15:58:31 -08002941 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002942 ep1_ch1()->GetState(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08002943 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07002944 ep2_ch1()->GetState(), kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07002945}
2946
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002947// Tests that when a network interface becomes inactive, if Continual Gathering
2948// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002949// will be removed from the port list of the channel, and the respective
2950// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08002951TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002952 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08002953 AddAddress(0, kPublicAddrs[0]);
2954 AddAddress(1, kPublicAddrs[1]);
2955 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07002956 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
2957 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07002958 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08002959
2960 SetAllocatorFlags(0, kOnlyLocalPorts);
2961 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002962 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2963 ep2_ch1()->receiving() &&
2964 ep2_ch1()->writable(),
2965 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08002966 // More than one port has been created.
2967 EXPECT_LE(1U, ep1_ch1()->ports().size());
2968 // Endpoint 1 enabled continual gathering; the port will be removed
2969 // when the interface is removed.
2970 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002971 EXPECT_TRUE(ep1_ch1()->ports().empty());
2972 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002973 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
2974 clock);
honghaize3c6c822016-02-17 13:00:28 -08002975
2976 size_t num_ports = ep2_ch1()->ports().size();
2977 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002978 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002979 // Endpoint 2 did not enable continual gathering; the local port will still be
2980 // removed when the interface is removed but the remote candidates on the
2981 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08002982 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002983
2984 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
2985 clock);
2986 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002987 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002988
2989 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08002990}
2991
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002992// Tests that continual gathering will create new connections when a new
2993// interface is added.
2994TEST_F(P2PTransportChannelMultihomedTest,
2995 TestContinualGatheringOnNewInterface) {
2996 auto& wifi = kAlternateAddrs;
2997 auto& cellular = kPublicAddrs;
2998 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
2999 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003000 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07003001 IceConfig continual_gathering_config =
3002 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07003003 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003004 SetAllocatorFlags(0, kOnlyLocalPorts);
3005 SetAllocatorFlags(1, kOnlyLocalPorts);
3006 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3007 ep2_ch1()->receiving() && ep2_ch1()->writable(),
3008 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003009
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003010 // Add a new wifi interface on end point 2. We should expect a new connection
3011 // to be created and the new one will be the best connection.
3012 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08003013 const Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003014 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003015 conn->remote_candidate().address().EqualIPs(wifi[1]),
3016 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003017 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003018 conn->local_candidate().address().EqualIPs(wifi[1]),
3019 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003020
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003021 // Add a new cellular interface on end point 1, we should expect a new
3022 // backup connection created using this new interface.
3023 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003024 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08003025 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003026 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3027 nullptr &&
3028 conn != ep1_ch1()->selected_connection() && conn->writable(),
3029 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003030 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08003031 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003032 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
3033 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003034 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003035 kDefaultTimeout);
3036
3037 DestroyChannels();
3038}
3039
3040// Tests that we can switch links via continual gathering.
3041TEST_F(P2PTransportChannelMultihomedTest,
3042 TestSwitchLinksViaContinualGathering) {
3043 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003044 AddAddress(0, kPublicAddrs[0]);
3045 AddAddress(1, kPublicAddrs[1]);
3046 // Use only local ports for simplicity.
3047 SetAllocatorFlags(0, kOnlyLocalPorts);
3048 SetAllocatorFlags(1, kOnlyLocalPorts);
3049
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003050 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07003051 IceConfig continual_gathering_config =
3052 CreateIceConfig(1000, GATHER_CONTINUALLY);
3053 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07003054 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003055 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3056 ep2_ch1()->receiving() &&
3057 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003058 kMediumTimeout, clock);
Yves Gerey665174f2018-06-19 15:03:05 +02003059 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3060 ep2_ch1()->selected_connection() &&
3061 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3062 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003063
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003064 // Add the new address first and then remove the other one.
Mirko Bonadei675513b2017-11-09 11:09:25 +01003065 RTC_LOG(LS_INFO) << "Draining...";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003066 AddAddress(1, kAlternateAddrs[1]);
3067 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003068 // We should switch to use the alternate address after an exchange of pings.
3069 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07003070 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003071 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3072 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07003073 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003074
3075 // Remove one address first and then add another address.
Mirko Bonadei675513b2017-11-09 11:09:25 +01003076 RTC_LOG(LS_INFO) << "Draining again...";
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003077 RemoveAddress(1, kAlternateAddrs[1]);
3078 AddAddress(1, kAlternateAddrs[0]);
3079 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003080 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003081 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3082 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
Honghai Zhang161a5862016-10-20 11:47:02 -07003083 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003084
3085 DestroyChannels();
3086}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003087
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003088// Tests that the backup connection will be restored after it is destroyed.
3089TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3090 rtc::ScopedFakeClock clock;
3091 auto& wifi = kAlternateAddrs;
3092 auto& cellular = kPublicAddrs;
3093 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3094 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3095 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3096 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3097 // Use only local ports for simplicity.
3098 SetAllocatorFlags(0, kOnlyLocalPorts);
3099 SetAllocatorFlags(1, kOnlyLocalPorts);
3100
3101 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003102 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01003103 config.regather_on_failed_networks_interval = 2000;
johan02bd5122016-09-20 00:23:27 -07003104 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003105 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3106 ep2_ch1()->receiving() &&
3107 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003108 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003109 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3110 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003111 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
3112 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
3113
3114 // Destroy all backup connections.
3115 DestroyAllButBestConnection(ep1_ch1());
3116 // Ensure the backup connection is removed first.
3117 EXPECT_TRUE_SIMULATED_WAIT(
3118 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3119 kDefaultTimeout, clock);
honghaiz7252a002016-11-08 20:04:09 -08003120 const Connection* conn;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003121 EXPECT_TRUE_SIMULATED_WAIT(
3122 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3123 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003124 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003125 kDefaultTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003126
3127 DestroyChannels();
3128}
3129
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003130// A collection of tests which tests a single P2PTransportChannel by sending
3131// pings.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003132class P2PTransportChannelPingTest : public ::testing::Test,
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003133 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003134 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003135 P2PTransportChannelPingTest()
deadbeef98e186c2017-05-16 18:00:06 -07003136 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003137
3138 protected:
deadbeef14f97f52016-06-22 17:14:15 -07003139 void PrepareChannel(P2PTransportChannel* ch) {
3140 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003141 ch->SetIceParameters(kIceParams[0]);
3142 ch->SetRemoteIceParameters(kIceParams[1]);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003143 ch->SignalNetworkRouteChanged.connect(
3144 this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07003145 ch->SignalReadyToSend.connect(this,
3146 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07003147 ch->SignalStateChanged.connect(
3148 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003149 }
3150
Sebastian Janssond624c392019-04-17 10:36:03 +02003151 Connection* WaitForConnectionTo(
3152 P2PTransportChannel* ch,
3153 const std::string& ip,
3154 int port_num,
3155 rtc::ThreadProcessingFakeClock* clock = nullptr) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07003156 if (clock == nullptr) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003157 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3158 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003159 } else {
3160 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003161 kMediumTimeout, *clock);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003162 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003163 return GetConnectionTo(ch, ip, port_num);
3164 }
3165
sprang716978d2016-10-11 06:43:28 -07003166 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003167 if (ch->ports().empty()) {
3168 return nullptr;
3169 }
deadbeef14f97f52016-06-22 17:14:15 -07003170 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003171 }
3172
Honghai Zhanga74363c2016-07-28 18:06:15 -07003173 Port* GetPrunedPort(P2PTransportChannel* ch) {
3174 if (ch->pruned_ports().empty()) {
3175 return nullptr;
3176 }
3177 return static_cast<Port*>(ch->pruned_ports()[0]);
3178 }
3179
deadbeef14f97f52016-06-22 17:14:15 -07003180 Connection* GetConnectionTo(P2PTransportChannel* ch,
3181 const std::string& ip,
3182 int port_num) {
sprang716978d2016-10-11 06:43:28 -07003183 Port* port = GetPort(ch);
3184 if (!port) {
3185 return nullptr;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003186 }
sprang716978d2016-10-11 06:43:28 -07003187 return port->GetConnection(rtc::SocketAddress(ip, port_num));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003188 }
3189
deadbeef14f97f52016-06-22 17:14:15 -07003190 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3191 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08003192 if (conn) {
3193 ch->MarkConnectionPinged(conn);
3194 }
3195 return conn;
3196 }
3197
Steve Antone9324572017-11-29 10:18:21 -08003198 int SendData(IceTransportInternal* channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07003199 const char* data,
3200 size_t len,
3201 int packet_id) {
3202 rtc::PacketOptions options;
3203 options.packet_id = packet_id;
Steve Antone9324572017-11-29 10:18:21 -08003204 return channel->SendPacket(data, len, options, 0);
Honghai Zhang52dce732016-03-31 12:37:31 -07003205 }
3206
Steve Antone9324572017-11-29 10:18:21 -08003207 Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
3208 rtc::ScopedFakeClock* clock,
Honghai Zhang572b0942016-06-23 12:26:57 -07003209 const std::string& ip_addr,
3210 int port,
3211 int priority,
3212 bool writable) {
Steve Antone9324572017-11-29 10:18:21 -08003213 channel->AddRemoteCandidate(
Honghai Zhang572b0942016-06-23 12:26:57 -07003214 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3215 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antone9324572017-11-29 10:18:21 -08003216 GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
3217 *clock);
3218 Connection* conn = GetConnectionTo(channel, ip_addr, port);
Honghai Zhang572b0942016-06-23 12:26:57 -07003219
3220 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003221 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07003222 }
3223 return conn;
3224 }
3225
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003226 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3227 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07003228 conn->SignalNominated(conn);
3229 }
3230
Danil Chapovalov00c71832018-06-15 15:58:38 +02003231 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -08003232 last_network_route_ = network_route;
3233 if (last_network_route_) {
3234 last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
3235 }
Honghai Zhang572b0942016-06-23 12:26:57 -07003236 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07003237 }
3238
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003239 void ReceivePingOnConnection(
3240 Connection* conn,
3241 const std::string& remote_ufrag,
3242 int priority,
3243 uint32_t nomination,
3244 const absl::optional<std::string>& piggyback_ping_id) {
deadbeef14f97f52016-06-22 17:14:15 -07003245 IceMessage msg;
3246 msg.SetType(STUN_BINDING_REQUEST);
Karl Wiberg918f50c2018-07-05 11:40:33 +02003247 msg.AddAttribute(absl::make_unique<StunByteStringAttribute>(
deadbeef14f97f52016-06-22 17:14:15 -07003248 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07003249 conn->local_candidate().username() + ":" + remote_ufrag));
zsteinf42cc9d2017-03-27 16:17:19 -07003250 msg.AddAttribute(
Karl Wiberg918f50c2018-07-05 11:40:33 +02003251 absl::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003252 if (nomination != 0) {
Karl Wiberg918f50c2018-07-05 11:40:33 +02003253 msg.AddAttribute(absl::make_unique<StunUInt32Attribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003254 STUN_ATTR_NOMINATION, nomination));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003255 }
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003256 if (piggyback_ping_id) {
3257 msg.AddAttribute(absl::make_unique<StunByteStringAttribute>(
3258 STUN_ATTR_LAST_ICE_CHECK_RECEIVED, piggyback_ping_id.value()));
3259 }
deadbeef14f97f52016-06-22 17:14:15 -07003260 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07003261 msg.AddMessageIntegrity(conn->local_candidate().password());
3262 msg.AddFingerprint();
3263 rtc::ByteBufferWriter buf;
3264 msg.Write(&buf);
Niels Möller15ca5a92018-11-01 14:32:47 +01003265 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::TimeMicros());
honghaiz36f50e82016-06-01 15:57:03 -07003266 }
3267
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003268 void ReceivePingOnConnection(Connection* conn,
3269 const std::string& remote_ufrag,
3270 int priority,
3271 uint32_t nomination = 0) {
3272 ReceivePingOnConnection(conn, remote_ufrag, priority, nomination,
3273 absl::nullopt);
3274 }
3275
deadbeef5bd5ca32017-02-10 11:31:50 -08003276 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07003277 channel_ready_to_send_ = true;
3278 }
zhihuangd06adf62017-01-12 15:58:31 -08003279 void OnChannelStateChanged(IceTransportInternal* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07003280 channel_state_ = channel->GetState();
3281 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003282
Honghai Zhang52dce732016-03-31 12:37:31 -07003283 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003284 bool channel_ready_to_send() { return channel_ready_to_send_; }
3285 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
zhihuangd06adf62017-01-12 15:58:31 -08003286 IceTransportState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07003287 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07003288 int switches = selected_candidate_pair_switches_;
3289 selected_candidate_pair_switches_ = 0;
3290 return switches;
3291 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003292
Zhi Huang942bc2e2017-11-13 13:26:07 -08003293 // Return true if the |pair| matches the last network route.
3294 bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
3295 if (!pair) {
3296 return !last_network_route_.has_value();
3297 } else {
3298 return pair->local_candidate().network_id() ==
3299 last_network_route_->local_network_id &&
3300 pair->remote_candidate().network_id() ==
3301 last_network_route_->remote_network_id;
3302 }
3303 }
3304
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003305 private:
kwiberg3ec46792016-04-27 07:22:53 -07003306 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -07003307 rtc::AutoSocketServerThread thread_;
Honghai Zhang572b0942016-06-23 12:26:57 -07003308 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07003309 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07003310 bool channel_ready_to_send_ = false;
zhihuangd06adf62017-01-12 15:58:31 -08003311 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
Danil Chapovalov00c71832018-06-15 15:58:38 +02003312 absl::optional<rtc::NetworkRoute> last_network_route_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003313};
3314
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003315TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07003316 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3317 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003318 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003319 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003320 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3321 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003322
deadbeef14f97f52016-06-22 17:14:15 -07003323 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3324 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003325 ASSERT_TRUE(conn1 != nullptr);
3326 ASSERT_TRUE(conn2 != nullptr);
3327
3328 // Before a triggered check, the first connection to ping is the
3329 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08003330 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003331
3332 // Receiving a ping causes a triggered check which should make conn1
3333 // be pinged first instead of conn2, even though conn2 has a higher
3334 // priority.
3335 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08003336 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003337}
3338
honghaiz524ecc22016-05-25 12:48:31 -07003339TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07003340 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3341 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07003342 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07003343 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003344 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3345 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07003346
deadbeef14f97f52016-06-22 17:14:15 -07003347 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3348 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07003349 ASSERT_TRUE(conn1 != nullptr);
3350 ASSERT_TRUE(conn2 != nullptr);
3351
3352 // Low-priority connection becomes writable so that the other connection
3353 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003354 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07003355 EXPECT_TRUE_WAIT(
3356 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3357 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3358 kDefaultTimeout);
3359}
3360
zhihuang435264a2016-06-21 11:28:38 -07003361// Verify that the connections are pinged at the right time.
3362TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
3363 rtc::ScopedFakeClock clock;
3364 int RTT_RATIO = 4;
3365 int SCHEDULING_RANGE = 200;
3366 int RTT_RANGE = 10;
3367
deadbeef14f97f52016-06-22 17:14:15 -07003368 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3369 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07003370 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07003371 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003372 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3373 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003374
3375 ASSERT_TRUE(conn != nullptr);
3376 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3377
3378 // Initializing.
3379
3380 int64_t start = clock.TimeNanos();
3381 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3382 kDefaultTimeout, clock);
3383 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3384 rtc::kNumNanosecsPerMillisec /
3385 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003386 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003387
3388 // Stabilizing.
3389
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003390 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003391 int ping_sent_before = conn->num_pings_sent();
3392 start = clock.TimeNanos();
3393 // The connection becomes strong but not stable because we haven't been able
3394 // to converge the RTT.
Honghai Zhang161a5862016-10-20 11:47:02 -07003395 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3396 clock);
zhihuang435264a2016-06-21 11:28:38 -07003397 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003398 EXPECT_GE(ping_interval_ms,
3399 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3400 EXPECT_LE(
3401 ping_interval_ms,
3402 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003403
3404 // Stabilized.
3405
3406 // The connection becomes stable after receiving more than RTT_RATIO rtt
3407 // samples.
3408 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003409 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003410 }
3411 ping_sent_before = conn->num_pings_sent();
3412 start = clock.TimeNanos();
Honghai Zhang161a5862016-10-20 11:47:02 -07003413 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3414 clock);
zhihuang435264a2016-06-21 11:28:38 -07003415 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003416 EXPECT_GE(ping_interval_ms,
3417 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3418 EXPECT_LE(
3419 ping_interval_ms,
3420 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003421
3422 // Destabilized.
3423
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003424 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003425 // Create a in-flight ping.
3426 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3427 start = clock.TimeNanos();
3428 // In-flight ping timeout and the connection will be unstable.
3429 SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003430 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3431 kMediumTimeout, clock);
zhihuang435264a2016-06-21 11:28:38 -07003432 int64_t duration_ms =
3433 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3434 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3435 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3436 // The connection become unstable due to not receiving ping responses.
3437 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003438 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3439 clock);
zhihuang435264a2016-06-21 11:28:38 -07003440 // The interval is expected to be
honghaiz7252a002016-11-08 20:04:09 -08003441 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
zhihuang435264a2016-06-21 11:28:38 -07003442 start = clock.TimeNanos();
3443 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003444 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3445 clock);
zhihuang435264a2016-06-21 11:28:38 -07003446 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003447 EXPECT_GE(ping_interval_ms,
3448 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3449 EXPECT_LE(
3450 ping_interval_ms,
3451 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003452}
3453
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003454// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003455// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003456TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3457 rtc::ScopedFakeClock clock;
3458
3459 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3460 P2PTransportChannel ch("TestChannel", 1, &pa);
3461 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003462 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003463 ch.MaybeStartGathering();
3464 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3465 kDefaultTimeout);
3466
3467 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003468 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003469 IceMessage request;
3470 request.SetType(STUN_BINDING_REQUEST);
Karl Wiberg918f50c2018-07-05 11:40:33 +02003471 request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003472 STUN_ATTR_USERNAME, kIceUfrag[1]));
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003473 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Karl Wiberg918f50c2018-07-05 11:40:33 +02003474 request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
3475 STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003476 Port* port = GetPort(&ch);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003477 ASSERT_NE(nullptr, port);
3478 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3479 &request, kIceUfrag[1], false);
3480 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3481 ASSERT_NE(nullptr, conn);
3482
3483 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003484 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003485 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3486 EXPECT_EQ(0, conn->num_pings_sent());
3487
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003488 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003489 // the first ping is sent as soon as possible, within one simulated clock
3490 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003491 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003492 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3493}
3494
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003495TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003496 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3497 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003498 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003499 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003500 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3501 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003502
deadbeef14f97f52016-06-22 17:14:15 -07003503 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3504 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003505 ASSERT_TRUE(conn1 != nullptr);
3506 ASSERT_TRUE(conn2 != nullptr);
3507
guoweis36f01372016-03-02 18:02:40 -08003508 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3509 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003510 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003511 ASSERT_TRUE(conn1->writable());
3512 conn1->ReceivedPing();
3513
3514 // Ping received, but the connection is already writable, so no
3515 // "triggered check" and conn2 is pinged before conn1 because it has
3516 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003517 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003518}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003519
honghaiz079a7a12016-06-22 16:26:29 -07003520TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003521 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3522 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003523 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003524 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003525 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003526
deadbeef14f97f52016-06-22 17:14:15 -07003527 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003528 ASSERT_TRUE(conn1 != nullptr);
3529
3530 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3531 conn1->Prune(); // A pruned connection may still be pingable.
3532 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3533 conn1->FailAndPrune();
3534 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3535}
3536
Honghai Zhang1590c392016-05-24 13:15:02 -07003537TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003538 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3539 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003540 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003541 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003542 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3543 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003544 ASSERT_TRUE(conn1 != nullptr);
3545 // Pruning the connection reduces the set of active connections and changes
3546 // the channel state.
3547 conn1->Prune();
zhihuangd06adf62017-01-12 15:58:31 -08003548 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3549 kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003550}
3551
honghaiza54a0802015-12-16 18:37:23 -08003552// Test adding remote candidates with different ufrags. If a remote candidate
3553// is added with an old ufrag, it will be discarded. If it is added with a
3554// ufrag that was not seen before, it will be used to create connections
3555// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003556// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003557// ufrag, its pwd and generation will be set properly.
3558TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003559 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3560 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003561 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003562 ch.MaybeStartGathering();
3563 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003564 ch.AddRemoteCandidate(
3565 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3566 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003567 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003568 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003569 EXPECT_EQ(kIceUfrag[2], candidate.username());
3570 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003571 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003572
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003573 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003574 // This should set the ICE pwd in the remote candidate of |conn1|, making
3575 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003576 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003577 EXPECT_EQ(kIceUfrag[2], candidate.username());
3578 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003579 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003580
3581 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003582 ch.AddRemoteCandidate(
3583 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003584 rtc::Thread::Current()->ProcessMessages(500);
3585 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3586
3587 // Add a candidate with the current ufrag, its pwd and generation will be
3588 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003589 ch.AddRemoteCandidate(
3590 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3591 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003592 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003593 kMediumTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07003594 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003595 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3596 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003597
3598 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003599 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003600 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3601 candidate.username() == kIceUfrag[2]);
3602 if (candidate.username() == kIceUfrag[1]) {
3603 EXPECT_EQ(kIcePwd[1], candidate.password());
3604 } else if (candidate.username() == kIceUfrag[2]) {
3605 EXPECT_EQ(kIcePwd[2], candidate.password());
3606 }
3607 }
honghaiza54a0802015-12-16 18:37:23 -08003608}
3609
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003610TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003611 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3612 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003613 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003614 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003615
3616 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003617 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3618 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003619 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003620 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003621
3622 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003623 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003624 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3625 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003626 ASSERT_TRUE(conn2 != nullptr);
3627 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003628 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003629
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003630 // Wait for conn1 to be pruned.
Honghai Zhang161a5862016-10-20 11:47:02 -07003631 EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003632 // Destroy the connection to test SignalUnknownAddress.
3633 conn1->Destroy();
honghaize58d73d2016-10-24 16:38:26 -07003634 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
3635 kMediumTimeout);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003636
3637 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003638 IceMessage request;
3639 request.SetType(STUN_BINDING_REQUEST);
Karl Wiberg918f50c2018-07-05 11:40:33 +02003640 request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003641 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003642 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Karl Wiberg918f50c2018-07-05 11:40:33 +02003643 request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
3644 STUN_ATTR_PRIORITY, prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003645 EXPECT_NE(prflx_priority, remote_priority);
3646
sprang716978d2016-10-11 06:43:28 -07003647 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003648 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003649 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3650 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003651 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3652 ASSERT_TRUE(conn1 != nullptr);
3653 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3654
3655 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003656 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3657 &request, kIceUfrag[1], false);
3658 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003659 ASSERT_TRUE(conn3 != nullptr);
3660 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3661}
Peter Thatcher54360512015-07-08 11:08:35 -07003662
3663TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
honghaize58d73d2016-10-24 16:38:26 -07003664 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003665 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3666 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003667 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003668 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003669 // small.
Qingsi Wang866e08d2018-03-22 17:54:23 -07003670 EXPECT_LE(1000, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003671 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003672 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Qingsi Wang866e08d2018-03-22 17:54:23 -07003673 EXPECT_EQ(500, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003674 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003675 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003676 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaize58d73d2016-10-24 16:38:26 -07003677 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003678 ASSERT_TRUE(conn1 != nullptr);
3679
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003680 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Peter Thatcher54360512015-07-08 11:08:35 -07003681 conn1->ReceivedPing();
Niels Möller15ca5a92018-11-01 14:32:47 +01003682 conn1->OnReadPacket("ABC", 3, rtc::TimeMicros());
honghaize58d73d2016-10-24 16:38:26 -07003683 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
3684 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003685}
honghaiz5a3acd82015-08-20 15:53:17 -07003686
Honghai Zhang572b0942016-06-23 12:26:57 -07003687// The controlled side will select a connection as the "selected connection"
3688// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003689// point the controlled side will select that connection as the
Zhi Huang942bc2e2017-11-13 13:26:07 -08003690// "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
Honghai Zhang572b0942016-06-23 12:26:57 -07003691// selected connection changes and SignalReadyToSend will be fired if the new
3692// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003693TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003694 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3695 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003696 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003697 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003698 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003699 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3700 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003701 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003702 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003703 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003704 int last_packet_id = 0;
3705 const char* data = "ABCDEFGH";
3706 int len = static_cast<int>(strlen(data));
Steve Antone9324572017-11-29 10:18:21 -08003707 EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003708 EXPECT_EQ(-1, last_sent_packet_id());
3709
3710 // A connection needs to be writable before it is selected for transmission.
3711 conn1->ReceivedPingResponse(LOW_RTT, "id");
3712 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003713 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Steve Antone9324572017-11-29 10:18:21 -08003714 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003715
honghaiz5a3acd82015-08-20 15:53:17 -07003716 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003717 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003718 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3719 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003720 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003721 conn2->ReceivedPingResponse(LOW_RTT, "id");
3722 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003723 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003724 EXPECT_TRUE(channel_ready_to_send());
3725 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003726
3727 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003728 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003729 // its priority is lower.
Steve Antone9324572017-11-29 10:18:21 -08003730 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003731 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3732 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003733 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003734 // Because it has a lower priority, the selected connection is still conn2.
3735 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003736 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003737 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003738 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003739 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003740 EXPECT_EQ(conn3, ch.selected_connection());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003741 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003742 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003743 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003744
Honghai Zhang572b0942016-06-23 12:26:57 -07003745 // Even if another higher priority candidate arrives, it will not be set as
3746 // the selected connection because the selected connection is nominated by
3747 // the controlling side.
Steve Antone9324572017-11-29 10:18:21 -08003748 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003749 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3750 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003751 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003752 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003753 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003754 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003755 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003756 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003757 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003758 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003759 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003760 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003761 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003762 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
Honghai Zhang52dce732016-03-31 12:37:31 -07003763 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003764 // SignalReadyToSend is fired again because conn4 is writable.
3765 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003766}
3767
Honghai Zhang572b0942016-06-23 12:26:57 -07003768// The controlled side will select a connection as the "selected connection"
3769// based on requests from an unknown address before the controlling side
3770// nominates a connection, and will nominate a connection from an unknown
3771// address if the request contains the use_candidate attribute. Plus, it will
3772// also sends back a ping response and set the ICE pwd in the remote candidate
3773// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003774TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003775 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3776 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003777 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003778 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003779 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003780 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003781 IceMessage request;
3782 request.SetType(STUN_BINDING_REQUEST);
Karl Wiberg918f50c2018-07-05 11:40:33 +02003783 request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003784 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003785 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Karl Wiberg918f50c2018-07-05 11:40:33 +02003786 request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
3787 STUN_ATTR_PRIORITY, prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003788 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
deadbeef14f97f52016-06-22 17:14:15 -07003789 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3790 &request, kIceUfrag[1], false);
3791 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003792 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003793 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003794 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003795 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003796 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003797 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003798
3799 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003800 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3801 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003802 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003803 // Because it has a lower priority, the selected connection is still conn1.
3804 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003805 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003806 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003807 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3808 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003809 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003810
Honghai Zhang572b0942016-06-23 12:26:57 -07003811 // Another request with unknown address, it will not be set as the selected
3812 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003813 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003814 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3815 &request, kIceUfrag[1], false);
3816 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003817 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003818 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003819 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003820 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003821 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003822
3823 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003824 // selected as the selected connection.
zsteinf42cc9d2017-03-27 16:17:19 -07003825 request.AddAttribute(
Karl Wiberg918f50c2018-07-05 11:40:33 +02003826 absl::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
deadbeef14f97f52016-06-22 17:14:15 -07003827 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3828 &request, kIceUfrag[1], false);
3829 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003830 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003831 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003832 // conn4 is not the selected connection yet because it is not writable.
3833 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003834 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003835 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003836
3837 // Test that the request from an unknown address contains a ufrag from an old
3838 // generation.
3839 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003840 ch.SetRemoteIceParameters(kIceParams[2]);
3841 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003842 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3843 &request, kIceUfrag[2], false);
3844 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003845 ASSERT_TRUE(conn5 != nullptr);
3846 EXPECT_TRUE(port->sent_binding_response());
3847 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003848}
3849
Honghai Zhang572b0942016-06-23 12:26:57 -07003850// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003851// based on media received until the controlling side nominates a connection,
3852// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003853// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003854TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003855 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3856 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003857 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003858 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003859 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003860 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3861 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003862 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003863 conn1->ReceivedPingResponse(LOW_RTT, "id");
3864 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003865
Honghai Zhang572b0942016-06-23 12:26:57 -07003866 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003867 // switch to conn2 because the controlled side must mirror the media path
3868 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003869 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3870 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003871 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003872 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
Niels Möller15ca5a92018-11-01 14:32:47 +01003873 conn2->OnReadPacket("ABC", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07003874 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003875 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003876
3877 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003878 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003879 IceMessage request;
3880 request.SetType(STUN_BINDING_REQUEST);
Karl Wiberg918f50c2018-07-05 11:40:33 +02003881 request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003882 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003883 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Karl Wiberg918f50c2018-07-05 11:40:33 +02003884 request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
3885 STUN_ATTR_PRIORITY, prflx_priority));
deadbeef14f97f52016-06-22 17:14:15 -07003886 request.AddAttribute(
Karl Wiberg918f50c2018-07-05 11:40:33 +02003887 absl::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
sprang716978d2016-10-11 06:43:28 -07003888 Port* port = GetPort(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003889 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3890 &request, kIceUfrag[1], false);
3891 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003892 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003893 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003894 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003895 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003896
Honghai Zhang572b0942016-06-23 12:26:57 -07003897 // Now another data packet will not switch the selected connection because the
3898 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003899 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003900 conn2->ReceivedPingResponse(LOW_RTT, "id");
Niels Möller15ca5a92018-11-01 14:32:47 +01003901 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07003902 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
3903}
3904
3905TEST_F(P2PTransportChannelPingTest,
3906 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
3907 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003908 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003909 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3910 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3911 PrepareChannel(&ch);
3912 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003913 ch.MaybeStartGathering();
3914 // The connections have decreasing priority.
3915 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003916 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003917 ASSERT_TRUE(conn1 != nullptr);
3918 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003919 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003920 ASSERT_TRUE(conn2 != nullptr);
3921
3922 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07003923 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003924 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003925
3926 // conn2 receives data; it becomes selected.
3927 // Advance the clock by 1ms so that the last data receiving timestamp of
3928 // conn2 is larger.
3929 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01003930 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07003931 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003932 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003933
3934 // conn1 also receives data; it becomes selected due to priority again.
Niels Möller15ca5a92018-11-01 14:32:47 +01003935 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07003936 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003937 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003938
Honghai Zhange05bcc22016-08-16 18:19:14 -07003939 // conn2 received data more recently; it is selected now because it
3940 // received data more recently.
3941 SIMULATED_WAIT(false, 1, clock);
3942 // Need to become writable again because it was pruned.
3943 conn2->ReceivedPingResponse(LOW_RTT, "id");
Niels Möller15ca5a92018-11-01 14:32:47 +01003944 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003945 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003946 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003947
Honghai Zhang572b0942016-06-23 12:26:57 -07003948 // Make sure sorting won't reselect candidate pair.
3949 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003950 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003951}
3952
3953TEST_F(P2PTransportChannelPingTest,
3954 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3955 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003956 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003957
3958 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3959 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3960 PrepareChannel(&ch);
3961 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07003962 ch.MaybeStartGathering();
3963 // The connections have decreasing priority.
3964 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08003965 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003966 ASSERT_TRUE(conn1 != nullptr);
3967 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08003968 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07003969 ASSERT_TRUE(conn2 != nullptr);
3970
3971 // conn1 received data; it is the selected connection.
3972 // Advance the clock to have a non-zero last-data-receiving time.
3973 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01003974 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07003975 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003976 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07003977
3978 // conn2 is nominated; it becomes the selected connection.
3979 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07003980 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003981 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003982
Honghai Zhange05bcc22016-08-16 18:19:14 -07003983 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07003984 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07003985 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003986 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07003987
Honghai Zhang572b0942016-06-23 12:26:57 -07003988 // Make sure sorting won't reselect candidate pair.
3989 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07003990 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07003991}
3992
3993TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003994 TestControlledAgentSelectsConnectionWithHigherNomination) {
3995 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003996 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003997
3998 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3999 P2PTransportChannel ch("test", 1, &pa);
4000 PrepareChannel(&ch);
4001 ch.SetIceRole(ICEROLE_CONTROLLED);
4002 ch.MaybeStartGathering();
4003 // The connections have decreasing priority.
4004 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004005 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004006 ASSERT_TRUE(conn1 != nullptr);
4007 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004008 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004009 ASSERT_TRUE(conn2 != nullptr);
4010
4011 // conn1 is the selected connection because it has a higher priority,
Zhi Huang942bc2e2017-11-13 13:26:07 -08004012 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4013 clock);
4014 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004015 reset_selected_candidate_pair_switches();
4016
4017 // conn2 is nominated; it becomes selected.
4018 NominateConnection(conn2);
4019 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004020 EXPECT_EQ(conn2, ch.selected_connection());
4021 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004022
4023 // conn1 is selected because of its priority.
4024 NominateConnection(conn1);
4025 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004026 EXPECT_EQ(conn1, ch.selected_connection());
4027 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004028
4029 // conn2 gets higher remote nomination; it is selected again.
4030 NominateConnection(conn2, 2U);
4031 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004032 EXPECT_EQ(conn2, ch.selected_connection());
4033 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004034
4035 // Make sure sorting won't reselect candidate pair.
4036 SIMULATED_WAIT(false, 100, clock);
4037 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4038}
4039
4040TEST_F(P2PTransportChannelPingTest,
4041 TestControlledAgentIgnoresSmallerNomination) {
4042 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004043 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07004044
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004045 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4046 P2PTransportChannel ch("test", 1, &pa);
4047 PrepareChannel(&ch);
4048 ch.SetIceRole(ICEROLE_CONTROLLED);
4049 ch.MaybeStartGathering();
4050 Connection* conn =
Steve Antone9324572017-11-29 10:18:21 -08004051 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004052 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
4053 EXPECT_EQ(2U, conn->remote_nomination());
4054 // Smaller nomination is ignored.
4055 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
4056 EXPECT_EQ(2U, conn->remote_nomination());
4057}
4058
4059TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07004060 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
4061 rtc::ScopedFakeClock clock;
4062
4063 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4064 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
4065 PrepareChannel(&ch);
4066 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004067 ch.MaybeStartGathering();
4068 // The connections have decreasing priority.
4069 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004070 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004071 ASSERT_TRUE(conn1 != nullptr);
4072 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004073 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004074 ASSERT_TRUE(conn2 != nullptr);
4075
4076 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004077 // There is no selected connection because no connection is writable.
4078 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07004079
4080 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004081 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07004082 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07004083 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08004084 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4085 clock);
4086 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004087
4088 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004089 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07004090 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07004091 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08004092 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4093 clock);
4094 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004095
4096 // Make sure sorting won't reselect candidate pair.
4097 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07004098 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07004099}
honghaiz89374372015-09-24 13:14:47 -07004100
honghaiz36f50e82016-06-01 15:57:03 -07004101// Test that if a new remote candidate has the same address and port with
4102// an old one, it will be used to create a new connection.
4103TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07004104 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4105 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07004106 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07004107 ch.MaybeStartGathering();
4108 const std::string host_address = "1.1.1.1";
4109 const int port_num = 1;
4110
4111 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07004112 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4113 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07004114 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004115 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004116 ASSERT_TRUE(conn1 != nullptr);
4117 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4118
4119 // Simply adding the same candidate again won't create a new connection.
4120 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004121 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004122 EXPECT_EQ(conn1, conn2);
4123
4124 // Update the ufrag of the candidate and add it again.
4125 candidate.set_username(kIceUfrag[2]);
4126 ch.AddRemoteCandidate(candidate);
4127 conn2 = GetConnectionTo(&ch, host_address, port_num);
4128 EXPECT_NE(conn1, conn2);
4129 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4130 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4131
4132 // Verify that a ping with the new ufrag can be received on the new
4133 // connection.
4134 EXPECT_EQ(0, conn2->last_ping_received());
4135 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
Steve Antone9324572017-11-29 10:18:21 -08004136 EXPECT_GT(conn2->last_ping_received(), 0);
honghaiz36f50e82016-06-01 15:57:03 -07004137}
4138
Honghai Zhang572b0942016-06-23 12:26:57 -07004139// When the current selected connection is strong, lower-priority connections
4140// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07004141TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004142 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004143 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004144 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4145 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07004146 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004147 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07004148 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004149 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4150 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07004151 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004152 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004153 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07004154
4155 // When a higher-priority, nominated candidate comes in, the connections with
4156 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07004157 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004158 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07004159 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004160 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4161 NominateConnection(conn2);
Honghai Zhang161a5862016-10-20 11:47:02 -07004162 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004163
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004164 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07004165 // Wait until conn2 becomes not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004166 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004167
deadbeef14f97f52016-06-22 17:14:15 -07004168 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004169 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07004170 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07004171 // The selected connection should still be conn2. Even through conn3 has lower
4172 // priority and is not receiving/writable, it is not pruned because the
4173 // selected connection is not receiving.
honghaize58d73d2016-10-24 16:38:26 -07004174 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004175 EXPECT_FALSE(conn3->pruned());
4176}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004177
Honghai Zhang572b0942016-06-23 12:26:57 -07004178TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4179 rtc::ScopedFakeClock clock;
4180 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4181 P2PTransportChannel ch("test channel", 1, &pa);
4182 PrepareChannel(&ch);
4183 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004184 ch.MaybeStartGathering();
4185 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004186 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004187 ASSERT_TRUE(conn1 != nullptr);
4188 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004189 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004190 ASSERT_TRUE(conn2 != nullptr);
4191 // Even if conn1 is writable, nominated, receiving data, it should not prune
4192 // conn2.
4193 NominateConnection(conn1);
4194 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01004195 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07004196 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4197 EXPECT_FALSE(conn2->pruned());
4198}
4199
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004200// Test that GetState returns the state correctly.
4201TEST_F(P2PTransportChannelPingTest, TestGetState) {
honghaize58d73d2016-10-24 16:38:26 -07004202 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004203 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004204 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4205 P2PTransportChannel ch("test channel", 1, &pa);
Jonas Olsson81125f02018-10-09 10:52:04 +02004206 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004207 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004208 ch.MaybeStartGathering();
Seth Hampson98335f82019-02-22 17:50:03 -08004209 // After gathering we are still in the kNew state because we aren't checking
4210 // any connections yet.
4211 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
zhihuangd06adf62017-01-12 15:58:31 -08004212 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
deadbeef14f97f52016-06-22 17:14:15 -07004213 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4214 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Seth Hampson98335f82019-02-22 17:50:03 -08004215 // Checking candidates that have been added with gathered candidates.
4216 ASSERT_GT(ch.connections().size(), 0u);
4217 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
honghaize58d73d2016-10-24 16:38:26 -07004218 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4219 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004220 ASSERT_TRUE(conn1 != nullptr);
4221 ASSERT_TRUE(conn2 != nullptr);
4222 // Now there are two connections, so the transport channel is connecting.
zhihuangd06adf62017-01-12 15:58:31 -08004223 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Seth Hampson98335f82019-02-22 17:50:03 -08004224 // No connections are writable yet, so we should still be in the kChecking
4225 // state.
4226 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004227 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004228 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaize58d73d2016-10-24 16:38:26 -07004229 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004230 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Seth Hampson98335f82019-02-22 17:50:03 -08004231 EXPECT_EQ(webrtc::IceTransportState::kConnected, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004232 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08004233 // Need to wait until the channel state is updated.
zhihuangd06adf62017-01-12 15:58:31 -08004234 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
honghaize58d73d2016-10-24 16:38:26 -07004235 kShortTimeout, clock);
Jonas Olsson81125f02018-10-09 10:52:04 +02004236 EXPECT_EQ(webrtc::IceTransportState::kFailed, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004237}
4238
4239// Test that when a low-priority connection is pruned, it is not deleted
4240// right away, and it can become active and be pruned again.
4241TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004242 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004243 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07004244
deadbeef14f97f52016-06-22 17:14:15 -07004245 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4246 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004247 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07004248 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01004249 config.receiving_switching_delay = 800;
honghaiz9ad0db52016-07-14 19:30:28 -07004250 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004251 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004252 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004253 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004254 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004255 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004256 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07004257 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4258 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004259
4260 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07004261 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004262 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07004263 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004264 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004265 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004266 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004267 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004268 // |conn2| should not send a ping yet.
hbos06495bc2017-01-02 08:08:18 -08004269 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
zhihuangd06adf62017-01-12 15:58:31 -08004270 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004271 // Wait for |conn1| becoming not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004272 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004273 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07004274 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004275 ASSERT_TRUE(conn2 != nullptr);
hbos06495bc2017-01-02 08:08:18 -08004276 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
Honghai Zhange05bcc22016-08-16 18:19:14 -07004277 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004278 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004279 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4280 clock);
zhihuangd06adf62017-01-12 15:58:31 -08004281 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004282
4283 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004284 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004285 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4286 clock);
4287 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004288 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004289}
honghaiz77d0d6e2015-10-27 11:34:45 -07004290
4291// Test that if all connections in a channel has timed out on writing, they
4292// will all be deleted. We use Prune to simulate write_time_out.
4293TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
honghaize58d73d2016-10-24 16:38:26 -07004294 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07004295 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4296 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07004297 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07004298 ch.MaybeStartGathering();
4299 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07004300 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
honghaize58d73d2016-10-24 16:38:26 -07004301 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004302 ASSERT_TRUE(conn1 != nullptr);
4303 conn1->ReceivedPing(); // Becomes receiving
4304 conn1->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004305 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004306
4307 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07004308 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004309 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004310 ASSERT_TRUE(conn2 != nullptr);
4311 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07004312 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
honghaize58d73d2016-10-24 16:38:26 -07004313 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004314 ASSERT_TRUE(conn3 != nullptr);
4315 conn3->ReceivedPing(); // Becomes receiving
4316 // Now prune both conn2 and conn3; they will be deleted soon.
4317 conn2->Prune();
4318 conn3->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004319 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004320}
honghaiz9b669572015-11-04 12:07:44 -08004321
Honghai Zhang5a246372016-05-02 17:28:35 -07004322// Tests that after a port allocator session is started, it will be stopped
4323// when a new connection becomes writable and receiving. Also tests that if a
4324// connection belonging to an old session becomes writable, it won't stop
4325// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08004326TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07004327 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4328 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08004329 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004330 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08004331 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004332 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4333 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08004334 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004335 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004336 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4337
Honghai Zhang5a246372016-05-02 17:28:35 -07004338 // Start a new session. Even though conn1, which belongs to an older
4339 // session, becomes unwritable and writable again, it should not stop the
4340 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004341 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08004342 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07004343 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004344 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07004345 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4346
4347 // But if a new connection created from the new session becomes writable,
4348 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07004349 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4350 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08004351 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004352 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004353 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4354}
guoweis36f01372016-03-02 18:02:40 -08004355
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004356// Test that the ICE role is updated even on ports that has been removed.
4357// These ports may still have connections that need a correct role, in case that
4358// the connections on it may still receive stun pings.
4359TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07004360 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4361 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004362 // Starts with ICEROLE_CONTROLLING.
4363 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004364 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07004365 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07004366 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004367 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004368
deadbeef14f97f52016-06-22 17:14:15 -07004369 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004370 ASSERT_TRUE(conn != nullptr);
4371
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004372 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4373 // change the ICE role and expect it to be updated.
4374 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07004375 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07004376 ch.SetIceRole(ICEROLE_CONTROLLED);
4377 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004378}
4379
4380// Test that the ICE role is updated even on ports with inactive networks.
4381// These ports may still have connections that need a correct role, for the
4382// pings sent by those connections until they're replaced by newer-generation
4383// connections.
4384TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07004385 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4386 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004387 // Starts with ICEROLE_CONTROLLING.
4388 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07004389 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004390 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004391
deadbeef14f97f52016-06-22 17:14:15 -07004392 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004393 ASSERT_TRUE(conn != nullptr);
4394
4395 // Do an ICE restart, change the role, and expect the old port to have its
4396 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004397 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07004398 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004399 ch.SetIceRole(ICEROLE_CONTROLLED);
4400 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004401}
4402
4403// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07004404// will be destroyed. The port will only be destroyed after it is marked as
4405// "pruned."
4406TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07004407 rtc::ScopedFakeClock fake_clock;
4408
deadbeef14f97f52016-06-22 17:14:15 -07004409 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4410 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004411 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004412 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07004413 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004414 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004415
deadbeef14f97f52016-06-22 17:14:15 -07004416 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004417 ASSERT_TRUE(conn != nullptr);
4418
4419 // Simulate 2 minutes going by. This should be enough time for the port to
4420 // time out.
4421 for (int second = 0; second < 120; ++second) {
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004422 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeefdfc42442016-06-21 14:19:48 -07004423 }
4424 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004425 // Port will not be removed because it is not pruned yet.
sprang716978d2016-10-11 06:43:28 -07004426 PortInterface* port = GetPort(&ch);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004427 ASSERT_NE(nullptr, port);
4428
4429 // If the session prunes all ports, the port will be destroyed.
4430 ch.allocator_session()->PruneAllPorts();
sprang716978d2016-10-11 06:43:28 -07004431 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004432 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004433}
4434
guoweis36f01372016-03-02 18:02:40 -08004435class P2PTransportChannelMostLikelyToWorkFirstTest
4436 : public P2PTransportChannelPingTest {
4437 public:
4438 P2PTransportChannelMostLikelyToWorkFirstTest()
4439 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4440 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004441 allocator_.reset(
4442 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4443 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004444 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4445 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004446 allocator_->set_step_delay(kMinimumStepDelay);
4447 }
4448
deadbeef14f97f52016-06-22 17:14:15 -07004449 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004450 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004451 int stable_writable_connection_ping_interval) {
deadbeef49f34fd2016-12-06 16:22:06 -08004452 channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
deadbeef14f97f52016-06-22 17:14:15 -07004453 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004454 config.prioritize_most_likely_candidate_pairs =
4455 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004456 config.stable_writable_connection_ping_interval =
4457 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004458 channel_->SetIceConfig(config);
4459 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004460 channel_->MaybeStartGathering();
4461 return *channel_.get();
4462 }
4463
deadbeef14f97f52016-06-22 17:14:15 -07004464 BasicPortAllocator* allocator() { return allocator_.get(); }
4465 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004466
4467 // This verifies the next pingable connection has the expected candidates'
4468 // types and, for relay local candidate, the expected relay protocol and ping
4469 // it.
4470 void VerifyNextPingableConnection(
4471 const std::string& local_candidate_type,
4472 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004473 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4474 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004475 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004476 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004477 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4478 }
4479 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4480 }
4481
guoweis36f01372016-03-02 18:02:40 -08004482 private:
deadbeef14f97f52016-06-22 17:14:15 -07004483 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004484 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004485 TestTurnServer turn_server_;
4486 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004487};
4488
4489// Test that Relay/Relay connections will be pinged first when no other
4490// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004491// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004492TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4493 TestRelayRelayFirstWhenNothingPingedYet) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004494 const int max_strong_interval = 500;
deadbeef14f97f52016-06-22 17:14:15 -07004495 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
Honghai Zhang161a5862016-10-20 11:47:02 -07004496 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004497 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4498 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004499
deadbeef14f97f52016-06-22 17:14:15 -07004500 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4501 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004502
Honghai Zhang161a5862016-10-20 11:47:02 -07004503 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004504
4505 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004506 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4507 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4508 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004509
4510 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004511 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4512 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4513 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004514 conn2->ReceivedPing();
4515 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4516
Honghai Zhang572b0942016-06-23 12:26:57 -07004517 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004518 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4519 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4520 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004521 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004522 ASSERT_TRUE(conn3->writable());
4523 conn3->ReceivedPing();
4524
honghaiz524ecc22016-05-25 12:48:31 -07004525 /*
4526
4527 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4528 the flakiness. The following test becomes flaky because we now ping the
4529 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004530 times. The selected connection may have been pinged before
4531 |max_strong_interval|, so it may not be the next connection to be pinged as
4532 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004533
Honghai Zhang572b0942016-06-23 12:26:57 -07004534 // Verify that conn3 will be the "selected connection" since it is readable
4535 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004536 // pingable connection.
Honghai Zhang161a5862016-10-20 11:47:02 -07004537 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004538 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004539 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004540 ASSERT_TRUE(conn3->writable());
4541 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004542
4543 */
guoweis36f01372016-03-02 18:02:40 -08004544}
4545
4546// Test that Relay/Relay connections will be pinged first when everything has
4547// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4548// in the first round.
4549TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4550 TestRelayRelayFirstWhenEverythingPinged) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004551 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004552 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004553 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4554 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004555
deadbeef14f97f52016-06-22 17:14:15 -07004556 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004557 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004558
4559 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004560 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4561 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004562
4563 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004564 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004565 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004566
4567 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004568 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004569
4570 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004571 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004572
4573 // Now, every connection has been pinged once. The next one should be
4574 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004575 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004576}
4577
4578// Test that when we receive a new remote candidate, they will be tried first
4579// before we re-ping Relay/Relay connections again.
4580TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4581 TestNoStarvationOnNonRelayConnection) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004582 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004583 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004584 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4585 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004586
deadbeef14f97f52016-06-22 17:14:15 -07004587 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004588 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004589
4590 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004591 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004592
4593 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004594 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004595
4596 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004597 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004598 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004599
4600 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004601 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004602
4603 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004604 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004605
4606 // Now, every connection has been pinged once. The next one should be
4607 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004608 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004609}
4610
4611// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4612// followed by the rest.
4613TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4614 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004615 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
4616 RelayServerConfig config(RELAY_TURN);
guoweis36f01372016-03-02 18:02:40 -08004617 config.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08004618 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
guoweis36f01372016-03-02 18:02:40 -08004619 allocator()->AddTurnServer(config);
4620
Qingsi Wangdea68892018-03-27 10:55:21 -07004621 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004622 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004623 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4624 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4625 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004626
4627 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004628 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004629 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004630
4631 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004632 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004633
4634 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004635 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4636 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004637
4638 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004639 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004640}
deadbeef14f97f52016-06-22 17:14:15 -07004641
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004642// Test that a resolver is created, asked for a result, and destroyed
Zach Stein5ec2c942018-11-27 16:58:08 -08004643// when the address is a hostname. The destruction should happen even
4644// if the channel is not destroyed.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004645TEST(P2PTransportChannelResolverTest, HostnameCandidateIsResolved) {
4646 rtc::MockAsyncResolver mock_async_resolver;
4647 EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
4648 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4649 .WillOnce(Return(true));
Zach Stein5ec2c942018-11-27 16:58:08 -08004650 // Destroy is called asynchronously after the address is resolved,
4651 // so we need a variable to wait on.
4652 bool destroy_called = false;
4653 EXPECT_CALL(mock_async_resolver, Destroy(_))
4654 .WillOnce(Assign(&destroy_called, true));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004655 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4656 EXPECT_CALL(mock_async_resolver_factory, Create())
4657 .WillOnce(Return(&mock_async_resolver));
4658
Qingsi Wangc129c352019-04-18 10:41:58 -07004659 FakePortAllocator allocator(rtc::Thread::Current(), nullptr);
4660 P2PTransportChannel channel("tn", 0, &allocator,
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004661 &mock_async_resolver_factory);
4662 Candidate hostname_candidate;
4663 SocketAddress hostname_address("fake.test", 1000);
4664 hostname_candidate.set_address(hostname_address);
4665 channel.AddRemoteCandidate(hostname_candidate);
4666
4667 ASSERT_EQ_WAIT(1u, channel.remote_candidates().size(), kDefaultTimeout);
4668 const RemoteCandidate& candidate = channel.remote_candidates()[0];
4669 EXPECT_FALSE(candidate.address().IsUnresolvedIP());
Zach Stein5ec2c942018-11-27 16:58:08 -08004670 WAIT(destroy_called, kShortTimeout);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004671}
4672
Qingsi Wang09619332018-09-12 22:51:55 -07004673// Test that if we signal a hostname candidate after the remote endpoint
4674// discovers a prflx remote candidate with the same underlying IP address, the
4675// prflx candidate is updated to a host candidate after the name resolution is
4676// done.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004677TEST_F(P2PTransportChannelTest,
Qingsi Wang7852d292018-10-31 11:17:07 -07004678 PeerReflexiveCandidateBeforeSignalingWithMdnsName) {
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004679 rtc::MockAsyncResolver mock_async_resolver;
4680 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4681 EXPECT_CALL(mock_async_resolver_factory, Create())
4682 .WillOnce(Return(&mock_async_resolver));
4683
Qingsi Wang09619332018-09-12 22:51:55 -07004684 // ep1 and ep2 will only gather host candidates with addresses
4685 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004686 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
Qingsi Wang09619332018-09-12 22:51:55 -07004687 // ICE parameter will be set up when creating the channels.
4688 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004689 GetEndpoint(0)->network_manager_.set_mdns_responder(
4690 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004691 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004692 CreateChannels();
Qingsi Wang09619332018-09-12 22:51:55 -07004693 // Pause sending candidates from both endpoints until we find out what port
4694 // number is assgined to ep1's host candidate.
4695 PauseCandidates(0);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004696 PauseCandidates(1);
Qingsi Wang09619332018-09-12 22:51:55 -07004697 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4698 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
4699 const auto& local_candidate =
4700 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4701 // The IP address of ep1's host candidate should be obfuscated.
4702 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
4703 // This is the underlying private IP address of the same candidate at ep1.
4704 const auto local_address = rtc::SocketAddress(
4705 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
4706 // Let ep2 signal its candidate to ep1. ep1 should form a candidate
4707 // pair and start to ping. After receiving the ping, ep2 discovers a prflx
4708 // remote candidate and form a candidate pair as well.
4709 ResumeCandidates(1);
4710 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
4711 // ep2 should have the selected connection connected to the prflx remote
4712 // candidate.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004713 const Connection* selected_connection = nullptr;
4714 ASSERT_TRUE_WAIT(
Qingsi Wang09619332018-09-12 22:51:55 -07004715 (selected_connection = ep2_ch1()->selected_connection()) != nullptr,
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004716 kMediumTimeout);
4717 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Qingsi Wang09619332018-09-12 22:51:55 -07004718 EXPECT_EQ(kIceUfrag[0], selected_connection->remote_candidate().username());
4719 EXPECT_EQ(kIcePwd[0], selected_connection->remote_candidate().password());
4720 // Set expectation before ep1 signals a hostname candidate.
4721 {
4722 InSequence sequencer;
4723 EXPECT_CALL(mock_async_resolver, Start(_));
4724 EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
4725 // Let the mock resolver of ep2 receives the correct resolution.
4726 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4727 .WillOnce(DoAll(SetArgPointee<1>(local_address), Return(true)));
4728 }
Zach Stein5ec2c942018-11-27 16:58:08 -08004729 // Destroy is called asynchronously after the address is resolved,
4730 // so we need a variable to wait on.
4731 bool destroy_called = false;
4732 EXPECT_CALL(mock_async_resolver, Destroy(_))
4733 .WillOnce(Assign(&destroy_called, true));
Qingsi Wang09619332018-09-12 22:51:55 -07004734 ResumeCandidates(0);
4735 // Verify ep2's selected connection is updated to use the 'local' candidate.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004736 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
Qingsi Wang09619332018-09-12 22:51:55 -07004737 ep2_ch1()->selected_connection()->remote_candidate().type(),
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004738 kMediumTimeout);
Qingsi Wang09619332018-09-12 22:51:55 -07004739 EXPECT_EQ(selected_connection, ep2_ch1()->selected_connection());
4740
Zach Stein5ec2c942018-11-27 16:58:08 -08004741 WAIT(destroy_called, kShortTimeout);
Qingsi Wang09619332018-09-12 22:51:55 -07004742 DestroyChannels();
4743}
4744
4745// Test that if we discover a prflx candidate during the process of name
4746// resolution for a remote hostname candidate, we update the prflx candidate to
4747// a host candidate if the hostname candidate turns out to have the same IP
4748// address after the resolution completes.
4749TEST_F(P2PTransportChannelTest,
Qingsi Wang7852d292018-10-31 11:17:07 -07004750 PeerReflexiveCandidateDuringResolvingHostCandidateWithMdnsName) {
Qingsi Wang09619332018-09-12 22:51:55 -07004751 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
4752 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4753 EXPECT_CALL(mock_async_resolver_factory, Create())
4754 .WillOnce(Return(&mock_async_resolver));
4755
4756 // ep1 and ep2 will only gather host candidates with addresses
4757 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
4758 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
4759 // ICE parameter will be set up when creating the channels.
4760 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004761 GetEndpoint(0)->network_manager_.set_mdns_responder(
4762 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004763 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
4764 CreateChannels();
4765 // Pause sending candidates from both endpoints until we find out what port
4766 // number is assgined to ep1's host candidate.
4767 PauseCandidates(0);
4768 PauseCandidates(1);
4769 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4770 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
4771 const auto& local_candidate =
4772 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4773 // The IP address of ep1's host candidate should be obfuscated.
4774 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
4775 // This is the underlying private IP address of the same candidate at ep1.
4776 const auto local_address = rtc::SocketAddress(
4777 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
4778 bool mock_async_resolver_started = false;
4779 // Not signaling done yet, and only make sure we are in the process of
4780 // resolution.
4781 EXPECT_CALL(mock_async_resolver, Start(_))
4782 .WillOnce(InvokeWithoutArgs([&mock_async_resolver_started]() {
4783 mock_async_resolver_started = true;
4784 }));
4785 // Let ep1 signal its hostname candidate to ep2.
4786 ResumeCandidates(0);
4787 EXPECT_TRUE_WAIT(mock_async_resolver_started, kMediumTimeout);
4788 // Now that ep2 is in the process of resolving the hostname candidate signaled
4789 // by ep1. Let ep2 signal its host candidate with an IP address to ep1, so
4790 // that ep1 can form a candidate pair, select it and start to ping ep2.
4791 ResumeCandidates(1);
4792 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
4793 // Let the mock resolver of ep2 receives the correct resolution.
4794 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4795 .WillOnce(DoAll(SetArgPointee<1>(local_address), Return(true)));
4796 // Upon receiving a ping from ep1, ep2 adds a prflx candidate from the
4797 // unknown address and establishes a connection.
4798 //
4799 // There is a caveat in our implementation associated with this expectation.
4800 // See the big comment in P2PTransportChannel::OnUnknownAddress.
4801 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
4802 EXPECT_EQ(PRFLX_PORT_TYPE,
4803 ep2_ch1()->selected_connection()->remote_candidate().type());
4804 // ep2 should also be able resolve the hostname candidate. The resolved remote
4805 // host candidate should be merged with the prflx remote candidate.
4806 mock_async_resolver.SignalDone(&mock_async_resolver);
4807 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
4808 ep2_ch1()->selected_connection()->remote_candidate().type(),
4809 kMediumTimeout);
4810 EXPECT_EQ(1u, ep2_ch1()->remote_candidates().size());
4811
4812 DestroyChannels();
4813}
4814
4815// Test that if we only gather and signal a host candidate, the IP address of
4816// which is obfuscated by an mDNS name, and if the peer can complete the name
4817// resolution with the correct IP address, we can have a p2p connection.
Qingsi Wang7852d292018-10-31 11:17:07 -07004818TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) {
Qingsi Wang09619332018-09-12 22:51:55 -07004819 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
4820 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4821 EXPECT_CALL(mock_async_resolver_factory, Create())
4822 .WillOnce(Return(&mock_async_resolver));
4823
4824 // ep1 and ep2 will only gather host candidates with addresses
4825 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
4826 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
4827 // ICE parameter will be set up when creating the channels.
4828 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004829 GetEndpoint(0)->network_manager_.set_mdns_responder(
4830 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004831 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
4832 CreateChannels();
4833 // Pause sending candidates from both endpoints until we find out what port
4834 // number is assgined to ep1's host candidate.
4835 PauseCandidates(0);
4836 PauseCandidates(1);
4837 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4838 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004839 const auto& local_candidate_ep1 =
Qingsi Wang09619332018-09-12 22:51:55 -07004840 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4841 // The IP address of ep1's host candidate should be obfuscated.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004842 EXPECT_TRUE(local_candidate_ep1.address().IsUnresolvedIP());
Qingsi Wang09619332018-09-12 22:51:55 -07004843 // This is the underlying private IP address of the same candidate at ep1,
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004844 // and let the mock resolver of ep2 receive the correct resolution.
4845 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
4846 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
Qingsi Wang09619332018-09-12 22:51:55 -07004847
4848 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004849 .WillOnce(DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true)));
Qingsi Wang09619332018-09-12 22:51:55 -07004850 // Let ep1 signal its hostname candidate to ep2.
4851 ResumeCandidates(0);
4852
4853 // We should be able to receive a ping from ep2 and establish a connection
4854 // with a peer reflexive candidate from ep2.
4855 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
4856 kMediumTimeout);
Qingsi Wangb49b8f12018-09-16 17:48:10 -07004857 EXPECT_EQ(LOCAL_PORT_TYPE,
4858 ep1_ch1()->selected_connection()->local_candidate().type());
Qingsi Wang09619332018-09-12 22:51:55 -07004859 EXPECT_EQ(PRFLX_PORT_TYPE,
4860 ep1_ch1()->selected_connection()->remote_candidate().type());
4861
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004862 DestroyChannels();
4863}
4864
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004865// Test that when the IP of a host candidate is concealed by an mDNS name, the
4866// stats from the gathering ICE endpoint do not reveal the address of this local
4867// host candidate or the related address of a local srflx candidate from the
4868// same endpoint. Also, the remote ICE endpoint that successfully resolves a
4869// signaled host candidate with an mDNS name should not reveal the address of
4870// this remote host candidate in stats.
4871TEST_F(P2PTransportChannelTest,
4872 CandidatesSanitizedInStatsWhenMdnsObfuscationEnabled) {
4873 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
4874 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4875 EXPECT_CALL(mock_async_resolver_factory, Create())
4876 .WillOnce(Return(&mock_async_resolver));
4877
4878 // ep1 and ep2 will gather host candidates with addresses
4879 // kPublicAddrs[0] and kPublicAddrs[1], respectively. ep1 also gathers a srflx
4880 // and a relay candidates.
4881 ConfigureEndpoints(OPEN, OPEN,
4882 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_TCP,
4883 kOnlyLocalPorts);
4884 // ICE parameter will be set up when creating the channels.
4885 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004886 GetEndpoint(0)->network_manager_.set_mdns_responder(
4887 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004888 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
4889 CreateChannels();
4890 // Pause sending candidates from both endpoints until we find out what port
4891 // number is assigned to ep1's host candidate.
4892 PauseCandidates(0);
4893 PauseCandidates(1);
4894 // Ep1 has a UDP host, a srflx and a relay candidates.
4895 ASSERT_EQ_WAIT(3u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4896 ASSERT_EQ_WAIT(1u, GetEndpoint(1)->saved_candidates_.size(), kMediumTimeout);
4897
4898 for (const auto& candidates_data : GetEndpoint(0)->saved_candidates_) {
4899 ASSERT_EQ(1u, candidates_data->candidates.size());
4900 const auto& local_candidate_ep1 = candidates_data->candidates[0];
4901 if (local_candidate_ep1.type() == LOCAL_PORT_TYPE) {
4902 // This is the underlying private IP address of the same candidate at ep1,
4903 // and let the mock resolver of ep2 receive the correct resolution.
4904 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
4905 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
4906 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4907 .WillOnce(
4908 DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true)));
4909 break;
4910 }
4911 }
4912 ResumeCandidates(0);
4913 ResumeCandidates(1);
4914
4915 ASSERT_EQ_WAIT(kIceGatheringComplete, ep1_ch1()->gathering_state(),
4916 kMediumTimeout);
4917 // We should have the following candidate pairs on both endpoints:
4918 // ep1_host <-> ep2_host, ep1_srflx <-> ep2_host, ep1_relay <-> ep2_host
4919 ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout);
4920 ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout);
4921
4922 ConnectionInfos connection_infos_ep1;
4923 CandidateStatsList candidate_stats_list_ep1;
4924 ConnectionInfos connection_infos_ep2;
4925 CandidateStatsList candidate_stats_list_ep2;
4926 ep1_ch1()->GetStats(&connection_infos_ep1, &candidate_stats_list_ep1);
4927 ep2_ch1()->GetStats(&connection_infos_ep2, &candidate_stats_list_ep2);
4928 EXPECT_EQ(3u, connection_infos_ep1.size());
4929 EXPECT_EQ(3u, candidate_stats_list_ep1.size());
4930 EXPECT_EQ(3u, connection_infos_ep2.size());
4931 // Check the stats of ep1 seen by ep1.
4932 for (const auto& connection_info : connection_infos_ep1) {
4933 const auto& local_candidate = connection_info.local_candidate;
4934 if (local_candidate.type() == LOCAL_PORT_TYPE) {
4935 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
4936 } else if (local_candidate.type() == STUN_PORT_TYPE) {
4937 EXPECT_TRUE(local_candidate.related_address().IsAnyIP());
4938 } else if (local_candidate.type() == RELAY_PORT_TYPE) {
4939 // The related address of the relay candidate should be equal to the
4940 // srflx address. Note that NAT is not configured, hence the following
4941 // expectation.
4942 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
4943 local_candidate.related_address().ipaddr());
4944 } else {
4945 FAIL();
4946 }
4947 }
4948 // Check the stats of ep1 seen by ep2.
4949 for (const auto& connection_info : connection_infos_ep2) {
4950 const auto& remote_candidate = connection_info.remote_candidate;
4951 if (remote_candidate.type() == LOCAL_PORT_TYPE) {
4952 EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP());
4953 } else if (remote_candidate.type() == STUN_PORT_TYPE) {
4954 EXPECT_TRUE(remote_candidate.related_address().IsAnyIP());
4955 } else if (remote_candidate.type() == RELAY_PORT_TYPE) {
4956 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
4957 remote_candidate.related_address().ipaddr());
4958 } else {
4959 FAIL();
4960 }
4961 }
4962 DestroyChannels();
4963}
4964
Qingsi Wangecd30542019-05-22 14:34:56 -07004965class MockMdnsResponder : public webrtc::MdnsResponderInterface {
4966 public:
4967 MOCK_METHOD2(CreateNameForAddress,
4968 void(const rtc::IPAddress&, NameCreatedCallback));
4969 MOCK_METHOD2(RemoveNameForAddress,
4970 void(const rtc::IPAddress&, NameRemovedCallback));
4971};
4972
4973TEST_F(P2PTransportChannelTest,
4974 SrflxCandidateCanBeGatheredBeforeMdnsCandidateToCreateConnection) {
4975 // ep1 and ep2 will only gather host and srflx candidates with base addresses
4976 // kPublicAddrs[0] and kPublicAddrs[1], respectively, and we use a shared
4977 // socket in gathering.
4978 const auto kOnlyLocalAndStunPorts =
4979 cricket::PORTALLOCATOR_DISABLE_RELAY |
4980 cricket::PORTALLOCATOR_DISABLE_TCP |
4981 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET;
4982 // ep1 is configured with a NAT so that we do gather a srflx candidate.
4983 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kOnlyLocalAndStunPorts,
4984 kOnlyLocalAndStunPorts);
4985 // ICE parameter will be set up when creating the channels.
4986 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
4987 // Use a mock mDNS responder, which does not complete the name registration by
4988 // ignoring the completion callback.
4989 auto mock_mdns_responder = absl::make_unique<MockMdnsResponder>();
4990 EXPECT_CALL(*mock_mdns_responder, CreateNameForAddress(_, _))
4991 .Times(1)
4992 .WillOnce(Return());
4993 GetEndpoint(0)->network_manager_.set_mdns_responder(
4994 std::move(mock_mdns_responder));
4995
4996 CreateChannels();
4997
4998 // We should be able to form a srflx-host connection to ep2.
4999 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
5000 kMediumTimeout);
5001 EXPECT_EQ(STUN_PORT_TYPE,
5002 ep1_ch1()->selected_connection()->local_candidate().type());
5003 EXPECT_EQ(LOCAL_PORT_TYPE,
5004 ep1_ch1()->selected_connection()->remote_candidate().type());
5005
5006 DestroyChannels();
5007}
5008
Qingsi Wangc129c352019-04-18 10:41:58 -07005009// Test that after changing the candidate filter from relay-only to allowing all
5010// types of candidates when doing continual gathering, we can gather without ICE
5011// restart the other types of candidates that are now enabled and form candidate
5012// pairs. Also, we verify that the relay candidates gathered previously are not
5013// removed and are still usable for necessary route switching.
5014TEST_F(P2PTransportChannelTest,
5015 SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005016 rtc::ScopedFakeClock clock;
5017
5018 ConfigureEndpoints(
5019 OPEN, OPEN,
5020 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5021 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5022 auto* ep1 = GetEndpoint(0);
5023 auto* ep2 = GetEndpoint(1);
5024 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5025 ep2->allocator_->SetCandidateFilter(CF_RELAY);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005026 // Enable continual gathering and also resurfacing gathered candidates upon
5027 // the candidate filter changed in the ICE configuration.
5028 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5029 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5030 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005031 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5032 kDefaultTimeout, clock);
5033 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5034 kDefaultTimeout, clock);
5035 EXPECT_EQ(RELAY_PORT_TYPE,
5036 ep1_ch1()->selected_connection()->local_candidate().type());
5037 EXPECT_EQ(RELAY_PORT_TYPE,
5038 ep2_ch1()->selected_connection()->local_candidate().type());
5039
5040 // Loosen the candidate filter at ep1.
5041 ep1->allocator_->SetCandidateFilter(CF_ALL);
5042 EXPECT_TRUE_SIMULATED_WAIT(
5043 ep1_ch1()->selected_connection() != nullptr &&
5044 ep1_ch1()->selected_connection()->local_candidate().type() ==
5045 LOCAL_PORT_TYPE,
5046 kDefaultTimeout, clock);
5047 EXPECT_EQ(RELAY_PORT_TYPE,
5048 ep1_ch1()->selected_connection()->remote_candidate().type());
5049
5050 // Loosen the candidate filter at ep2.
5051 ep2->allocator_->SetCandidateFilter(CF_ALL);
5052 EXPECT_TRUE_SIMULATED_WAIT(
5053 ep2_ch1()->selected_connection() != nullptr &&
5054 ep2_ch1()->selected_connection()->local_candidate().type() ==
5055 LOCAL_PORT_TYPE,
5056 kDefaultTimeout, clock);
5057 // We have migrated to a host-host candidate pair.
5058 EXPECT_EQ(LOCAL_PORT_TYPE,
5059 ep2_ch1()->selected_connection()->remote_candidate().type());
5060
5061 // Block the traffic over non-relay-to-relay routes and expect a route change.
5062 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kPublicAddrs[1]);
5063 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kPublicAddrs[0]);
5064 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kTurnUdpExtAddr);
5065 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kTurnUdpExtAddr);
5066 // We should be able to reuse the previously gathered relay candidates.
5067 EXPECT_EQ_SIMULATED_WAIT(
5068 RELAY_PORT_TYPE,
5069 ep1_ch1()->selected_connection()->local_candidate().type(),
5070 kDefaultTimeout, clock);
5071 EXPECT_EQ(RELAY_PORT_TYPE,
5072 ep1_ch1()->selected_connection()->remote_candidate().type());
5073}
5074
5075// A similar test as SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll,
5076// and we should surface server-reflexive candidates that are enabled after
5077// changing the candidate filter.
5078TEST_F(P2PTransportChannelTest,
5079 SurfaceSrflxCandidateOnCandidateFilterChangeFromRelayToNoHost) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005080 rtc::ScopedFakeClock clock;
5081 // We need an actual NAT so that the host candidate is not equivalent to the
5082 // srflx candidate; otherwise, the host candidate would still surface even
5083 // though we disable it via the candidate filter below. This is a result of
5084 // the following limitation in the current implementation:
5085 // 1. We don't generate the srflx candidate when we have public IP.
5086 // 2. We keep the host candidate in this case in CheckCandidateFilter even
5087 // though we intend to filter them.
5088 ConfigureEndpoints(
5089 NAT_FULL_CONE, NAT_FULL_CONE,
5090 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5091 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5092 auto* ep1 = GetEndpoint(0);
5093 auto* ep2 = GetEndpoint(1);
5094 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5095 ep2->allocator_->SetCandidateFilter(CF_RELAY);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005096 // Enable continual gathering and also resurfacing gathered candidates upon
5097 // the candidate filter changed in the ICE configuration.
5098 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5099 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5100 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005101 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5102 kDefaultTimeout, clock);
5103 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5104 kDefaultTimeout, clock);
5105 const uint32_t kCandidateFilterNoHost = CF_ALL & ~CF_HOST;
5106 // Loosen the candidate filter at ep1.
5107 ep1->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5108 EXPECT_TRUE_SIMULATED_WAIT(
5109 ep1_ch1()->selected_connection() != nullptr &&
5110 ep1_ch1()->selected_connection()->local_candidate().type() ==
5111 STUN_PORT_TYPE,
5112 kDefaultTimeout, clock);
5113 EXPECT_EQ(RELAY_PORT_TYPE,
5114 ep1_ch1()->selected_connection()->remote_candidate().type());
5115
5116 // Loosen the candidate filter at ep2.
5117 ep2->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5118 EXPECT_TRUE_SIMULATED_WAIT(
5119 ep2_ch1()->selected_connection() != nullptr &&
5120 ep2_ch1()->selected_connection()->local_candidate().type() ==
5121 STUN_PORT_TYPE,
5122 kDefaultTimeout, clock);
5123 // We have migrated to a srflx-srflx candidate pair.
5124 EXPECT_EQ(STUN_PORT_TYPE,
5125 ep2_ch1()->selected_connection()->remote_candidate().type());
5126
5127 // Block the traffic over non-relay-to-relay routes and expect a route change.
5128 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kPublicAddrs[1]);
5129 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kPublicAddrs[0]);
5130 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kTurnUdpExtAddr);
5131 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kTurnUdpExtAddr);
5132 // We should be able to reuse the previously gathered relay candidates.
5133 EXPECT_EQ_SIMULATED_WAIT(
5134 RELAY_PORT_TYPE,
5135 ep1_ch1()->selected_connection()->local_candidate().type(),
5136 kDefaultTimeout, clock);
5137 EXPECT_EQ(RELAY_PORT_TYPE,
5138 ep1_ch1()->selected_connection()->remote_candidate().type());
5139}
5140
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005141// This is the complement to
5142// SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll, and instead of
5143// gathering continually we only gather once, which makes the config
5144// |surface_ice_candidates_on_ice_transport_type_changed| ineffective after the
5145// gathering stopped.
5146TEST_F(P2PTransportChannelTest,
5147 CannotSurfaceTheNewlyAllowedOnFilterChangeIfNotGatheringContinually) {
5148 rtc::ScopedFakeClock clock;
5149
5150 ConfigureEndpoints(
5151 OPEN, OPEN,
5152 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5153 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5154 auto* ep1 = GetEndpoint(0);
5155 auto* ep2 = GetEndpoint(1);
5156 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5157 ep2->allocator_->SetCandidateFilter(CF_RELAY);
5158 // Only gather once.
5159 IceConfig ice_config = CreateIceConfig(1000, GATHER_ONCE);
5160 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5161 CreateChannels(ice_config, ice_config);
5162 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5163 kDefaultTimeout, clock);
5164 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5165 kDefaultTimeout, clock);
5166 // Loosen the candidate filter at ep1.
5167 ep1->allocator_->SetCandidateFilter(CF_ALL);
5168 // Wait for a period for any potential surfacing of new candidates.
5169 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5170 EXPECT_EQ(RELAY_PORT_TYPE,
5171 ep1_ch1()->selected_connection()->local_candidate().type());
5172
5173 // Loosen the candidate filter at ep2.
5174 ep2->allocator_->SetCandidateFilter(CF_ALL);
5175 EXPECT_EQ(RELAY_PORT_TYPE,
5176 ep2_ch1()->selected_connection()->local_candidate().type());
5177}
5178
Qingsi Wangc129c352019-04-18 10:41:58 -07005179// Test that when the candidate filter is updated to be more restrictive,
5180// candidates that 1) have already been gathered and signaled 2) but no longer
5181// match the filter, are not removed.
5182TEST_F(P2PTransportChannelTest,
5183 RestrictingCandidateFilterDoesNotRemoveRegatheredCandidates) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005184 rtc::ScopedFakeClock clock;
5185
5186 ConfigureEndpoints(
5187 OPEN, OPEN,
5188 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5189 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5190 auto* ep1 = GetEndpoint(0);
5191 auto* ep2 = GetEndpoint(1);
5192 ep1->allocator_->SetCandidateFilter(CF_ALL);
5193 ep2->allocator_->SetCandidateFilter(CF_ALL);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005194 // Enable continual gathering and also resurfacing gathered candidates upon
5195 // the candidate filter changed in the ICE configuration.
5196 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5197 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005198 // Pause candidates so we can gather all types of candidates. See
5199 // P2PTransportChannel::OnConnectionStateChange, where we would stop the
5200 // gathering when we have a strongly connected candidate pair.
5201 PauseCandidates(0);
5202 PauseCandidates(1);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005203 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005204
5205 // We have gathered host, srflx and relay candidates.
5206 EXPECT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 3u,
5207 kDefaultTimeout, clock);
5208 ResumeCandidates(0);
5209 ResumeCandidates(1);
5210 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5211 kDefaultTimeout, clock);
5212 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5213 kDefaultTimeout, clock);
5214 // Test that we have a host-host candidate pair selected and the number of
5215 // candidates signaled to the remote peer stays the same.
5216 auto test_invariants = [this]() {
5217 EXPECT_EQ(LOCAL_PORT_TYPE,
5218 ep1_ch1()->selected_connection()->local_candidate().type());
5219 EXPECT_EQ(LOCAL_PORT_TYPE,
5220 ep1_ch1()->selected_connection()->remote_candidate().type());
5221 EXPECT_THAT(ep2_ch1()->remote_candidates(), SizeIs(3));
5222 };
5223
5224 test_invariants();
5225
5226 // Set a more restrictive candidate filter at ep1.
5227 ep1->allocator_->SetCandidateFilter(CF_HOST | CF_REFLEXIVE);
5228 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5229 test_invariants();
5230
5231 ep1->allocator_->SetCandidateFilter(CF_HOST);
5232 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5233 test_invariants();
5234
5235 ep1->allocator_->SetCandidateFilter(CF_NONE);
5236 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5237 test_invariants();
5238}
5239
Steve Antone9324572017-11-29 10:18:21 -08005240} // namespace cricket