blob: 76030189ffbc160ca2ae3764f7b7cced3ceeffae [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "p2p/base/p2p_transport_channel.h"
12
Steve Antone9324572017-11-29 10:18:21 -080013#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070014#include <memory>
Qingsi Wangecd30542019-05-22 14:34:56 -070015#include <utility>
kwiberg3ec46792016-04-27 07:22:53 -070016
Jonas Orelande8e7d7b2019-05-29 09:30:55 +020017#include "p2p/base/connection.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "p2p/base/fake_port_allocator.h"
19#include "p2p/base/ice_transport_internal.h"
20#include "p2p/base/mock_async_resolver.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "p2p/base/packet_transport_internal.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "p2p/base/test_stun_server.h"
23#include "p2p/base/test_turn_server.h"
24#include "p2p/client/basic_port_allocator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/checks.h"
26#include "rtc_base/dscp.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070028#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/fake_network.h"
30#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/gunit.h"
32#include "rtc_base/helpers.h"
33#include "rtc_base/logging.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070034#include "rtc_base/mdns_responder_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "rtc_base/nat_server.h"
36#include "rtc_base/nat_socket_factory.h"
37#include "rtc_base/proxy_server.h"
38#include "rtc_base/socket_address.h"
39#include "rtc_base/ssl_adapter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080041#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020042#include "system_wrappers/include/metrics.h"
Qingsi Wangc129c352019-04-18 10:41:58 -070043#include "test/field_trial.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044
deadbeef14f97f52016-06-22 17:14:15 -070045namespace {
46
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047using rtc::SocketAddress;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070048using ::testing::_;
Zach Stein5ec2c942018-11-27 16:58:08 -080049using ::testing::Assign;
Steve Antonae226f62019-01-29 12:47:38 -080050using ::testing::Contains;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070051using ::testing::DoAll;
Qingsi Wang09619332018-09-12 22:51:55 -070052using ::testing::InSequence;
53using ::testing::InvokeWithoutArgs;
54using ::testing::NiceMock;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070055using ::testing::Return;
56using ::testing::SetArgPointee;
Qingsi Wangc129c352019-04-18 10:41:58 -070057using ::testing::SizeIs;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000058
deadbeef14f97f52016-06-22 17:14:15 -070059// Default timeout for tests in this file.
60// Should be large enough for slow buildbots to run the tests reliably.
61static const int kDefaultTimeout = 10000;
Honghai Zhang161a5862016-10-20 11:47:02 -070062static const int kMediumTimeout = 3000;
63static const int kShortTimeout = 1000;
deadbeef14f97f52016-06-22 17:14:15 -070064
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
66 cricket::PORTALLOCATOR_DISABLE_RELAY |
67 cricket::PORTALLOCATOR_DISABLE_TCP;
zhihuang435264a2016-06-21 11:28:38 -070068static const int LOW_RTT = 20;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000069// Addresses on the public internet.
Yves Gerey665174f2018-06-19 15:03:05 +020070static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
71 SocketAddress("22.22.22.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072// IPv6 Addresses on the public internet.
73static const SocketAddress kIPv6PublicAddrs[2] = {
74 SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
honghaiz7252a002016-11-08 20:04:09 -080075 SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000076// For configuring multihomed clients.
Honghai Zhangfd16da22016-08-17 16:12:46 -070077static const SocketAddress kAlternateAddrs[2] = {
78 SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
honghaiz7252a002016-11-08 20:04:09 -080079static const SocketAddress kIPv6AlternateAddrs[2] = {
80 SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
81 SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
deadbeeff137e972017-03-23 15:45:49 -070082// Addresses for HTTP proxy servers.
Yves Gerey665174f2018-06-19 15:03:05 +020083static const SocketAddress kHttpsProxyAddrs[2] = {
84 SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443)};
deadbeeff137e972017-03-23 15:45:49 -070085// Addresses for SOCKS proxy servers.
Yves Gerey665174f2018-06-19 15:03:05 +020086static const SocketAddress kSocksProxyAddrs[2] = {
87 SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000088// Internal addresses for NAT boxes.
Yves Gerey665174f2018-06-19 15:03:05 +020089static const SocketAddress kNatAddrs[2] = {SocketAddress("192.168.1.1", 0),
90 SocketAddress("192.168.2.1", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000091// Private addresses inside the NAT private networks.
Yves Gerey665174f2018-06-19 15:03:05 +020092static const SocketAddress kPrivateAddrs[2] = {
93 SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000094// For cascaded NATs, the internal addresses of the inner NAT boxes.
Yves Gerey665174f2018-06-19 15:03:05 +020095static const SocketAddress kCascadedNatAddrs[2] = {
96 SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097// For cascaded NATs, private addresses inside the inner private networks.
Yves Gerey665174f2018-06-19 15:03:05 +020098static const SocketAddress kCascadedPrivateAddrs[2] = {
99 SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0)};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000100// The address of the public STUN server.
101static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102// The addresses for the public turn server.
Honghai Zhangb73d2692016-09-29 22:46:09 -0700103static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104 cricket::STUN_SERVER_PORT);
guoweis36f01372016-03-02 18:02:40 -0800105static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
106 cricket::STUN_SERVER_PORT + 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000107static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
108static const cricket::RelayCredentials kRelayCredentials("test", "test");
109
110// Based on ICE_UFRAG_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700111const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000112// Based on ICE_PWD_LENGTH
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700113const char* kIcePwd[4] = {
114 "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
115 "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
116const cricket::IceParameters kIceParams[4] = {
117 {kIceUfrag[0], kIcePwd[0], false},
118 {kIceUfrag[1], kIcePwd[1], false},
119 {kIceUfrag[2], kIcePwd[2], false},
120 {kIceUfrag[3], kIcePwd[3], false}};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000121
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700122const uint64_t kLowTiebreaker = 11111;
123const uint64_t kHighTiebreaker = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000124
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700125enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000126
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700127cricket::IceConfig CreateIceConfig(
128 int receiving_timeout,
129 cricket::ContinualGatheringPolicy continual_gathering_policy,
Danil Chapovalov00c71832018-06-15 15:58:38 +0200130 absl::optional<int> backup_ping_interval = absl::nullopt) {
honghaiz1f429e32015-09-28 07:57:34 -0700131 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800132 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700133 config.continual_gathering_policy = continual_gathering_policy;
Honghai Zhang381b4212015-12-04 12:24:03 -0800134 config.backup_connection_ping_interval = backup_ping_interval;
honghaiz1f429e32015-09-28 07:57:34 -0700135 return config;
136}
137
deadbeef14f97f52016-06-22 17:14:15 -0700138cricket::Candidate CreateUdpCandidate(const std::string& type,
139 const std::string& ip,
140 int port,
141 int priority,
142 const std::string& ufrag = "") {
143 cricket::Candidate c;
144 c.set_address(rtc::SocketAddress(ip, port));
145 c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
146 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
147 c.set_priority(priority);
148 c.set_username(ufrag);
149 c.set_type(type);
150 return c;
151}
152
Honghai Zhangb73d2692016-09-29 22:46:09 -0700153cricket::BasicPortAllocator* CreateBasicPortAllocator(
154 rtc::NetworkManager* network_manager,
155 const cricket::ServerAddresses& stun_servers,
156 const rtc::SocketAddress& turn_server_udp,
157 const rtc::SocketAddress& turn_server_tcp) {
Niels Möller191e38f2019-11-04 08:49:12 +0100158 cricket::RelayServerConfig turn_server;
Honghai Zhangb73d2692016-09-29 22:46:09 -0700159 turn_server.credentials = kRelayCredentials;
160 if (!turn_server_udp.IsNil()) {
161 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800162 cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700163 }
164 if (!turn_server_tcp.IsNil()) {
165 turn_server.ports.push_back(
hnsl277b2502016-12-13 05:17:23 -0800166 cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
Honghai Zhangb73d2692016-09-29 22:46:09 -0700167 }
168 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
169
170 cricket::BasicPortAllocator* allocator =
171 new cricket::BasicPortAllocator(network_manager);
Qingsi Wanga2d60672018-04-11 16:57:45 -0700172 allocator->Initialize();
Honghai Zhangf8998cf2019-10-14 11:27:50 -0700173 allocator->SetConfiguration(stun_servers, turn_servers, 0, webrtc::NO_PRUNE);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700174 return allocator;
175}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700176} // namespace
deadbeef14f97f52016-06-22 17:14:15 -0700177
178namespace cricket {
179
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180// This test simulates 2 P2P endpoints that want to establish connectivity
181// with each other over various network topologies and conditions, which can be
182// specified in each individial test.
183// A virtual network (via VirtualSocketServer) along with virtual firewalls and
184// NATs (via Firewall/NATSocketServer) are used to simulate the various network
185// conditions. We can configure the IP addresses of the endpoints,
186// block various types of connectivity, or add arbitrary levels of NAT.
187// We also run a STUN server and a relay server on the virtual network to allow
188// our typical P2P mechanisms to do their thing.
189// For each case, we expect the P2P stack to eventually settle on a specific
190// form of connectivity to the other side. The test checks that the P2P
191// negotiation successfully establishes connectivity within a certain time,
192// and that the result is what we expect.
193// Note that this class is a base class for use by other tests, who will provide
194// specialized test behavior.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200195class P2PTransportChannelTestBase : public ::testing::Test,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000196 public rtc::MessageHandler,
197 public sigslot::has_slots<> {
198 public:
199 P2PTransportChannelTestBase()
deadbeef98e186c2017-05-16 18:00:06 -0700200 : vss_(new rtc::VirtualSocketServer()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000201 nss_(new rtc::NATSocketServer(vss_.get())),
202 ss_(new rtc::FirewallSocketServer(nss_.get())),
nisse7eaa4ea2017-05-08 05:25:41 -0700203 main_(ss_.get()),
204 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
205 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
deadbeeff137e972017-03-23 15:45:49 -0700206 socks_server1_(ss_.get(),
207 kSocksProxyAddrs[0],
208 ss_.get(),
209 kSocksProxyAddrs[0]),
210 socks_server2_(ss_.get(),
211 kSocksProxyAddrs[1],
212 ss_.get(),
213 kSocksProxyAddrs[1]),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000214 force_relay_(false) {
deadbeef14f97f52016-06-22 17:14:15 -0700215 ep1_.role_ = ICEROLE_CONTROLLING;
216 ep2_.role_ = ICEROLE_CONTROLLED;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217
218 ServerAddresses stun_servers;
219 stun_servers.insert(kStunAddr);
Honghai Zhangb73d2692016-09-29 22:46:09 -0700220 ep1_.allocator_.reset(
221 CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
222 kTurnUdpIntAddr, rtc::SocketAddress()));
223 ep2_.allocator_.reset(
224 CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
225 kTurnUdpIntAddr, rtc::SocketAddress()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700226 webrtc::metrics::Reset();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227 }
228
229 protected:
230 enum Config {
Yves Gerey665174f2018-06-19 15:03:05 +0200231 OPEN, // Open to the Internet
232 NAT_FULL_CONE, // NAT, no filtering
233 NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
234 NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
235 NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
236 NAT_DOUBLE_CONE, // Double NAT, both cone
237 NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
238 BLOCK_UDP, // Firewall, UDP in/out blocked
239 BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
240 BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
241 PROXY_HTTPS, // All traffic through HTTPS proxy
242 PROXY_SOCKS, // All traffic through SOCKS proxy
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000243 NUM_CONFIGS
244 };
245
246 struct Result {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700247 Result(const std::string& controlling_type,
248 const std::string& controlling_protocol,
249 const std::string& controlled_type,
250 const std::string& controlled_protocol,
251 int wait)
252 : controlling_type(controlling_type),
253 controlling_protocol(controlling_protocol),
254 controlled_type(controlled_type),
255 controlled_protocol(controlled_protocol),
256 connect_wait(wait) {}
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700257
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700258 // The expected candidate type and protocol of the controlling ICE agent.
259 std::string controlling_type;
260 std::string controlling_protocol;
261 // The expected candidate type and protocol of the controlled ICE agent.
262 std::string controlled_type;
263 std::string controlled_protocol;
264 // How long to wait before the correct candidate pair is selected.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000265 int connect_wait;
266 };
267
268 struct ChannelData {
269 bool CheckData(const char* data, int len) {
270 bool ret = false;
271 if (!ch_packets_.empty()) {
Yves Gerey665174f2018-06-19 15:03:05 +0200272 std::string packet = ch_packets_.front();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273 ret = (packet == std::string(data, len));
274 ch_packets_.pop_front();
275 }
276 return ret;
277 }
278
Steve Antone9324572017-11-29 10:18:21 -0800279 std::string name_; // TODO(?) - Currently not used.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000280 std::list<std::string> ch_packets_;
deadbeef14f97f52016-06-22 17:14:15 -0700281 std::unique_ptr<P2PTransportChannel> ch_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000282 };
283
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700284 struct CandidatesData : public rtc::MessageData {
zhihuangd06adf62017-01-12 15:58:31 -0800285 CandidatesData(IceTransportInternal* ch, const Candidate& c)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700286 : channel(ch), candidates(1, c) {}
zhihuangd06adf62017-01-12 15:58:31 -0800287 CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700288 : channel(ch), candidates(cc) {}
zhihuangd06adf62017-01-12 15:58:31 -0800289 IceTransportInternal* channel;
deadbeef14f97f52016-06-22 17:14:15 -0700290 Candidates candidates;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000291 };
292
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700293 struct Endpoint : public sigslot::has_slots<> {
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000294 Endpoint()
deadbeef14f97f52016-06-22 17:14:15 -0700295 : role_(ICEROLE_UNKNOWN),
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000296 tiebreaker_(0),
297 role_conflict_(false),
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700298 save_candidates_(false) {}
deadbeef5bd5ca32017-02-10 11:31:50 -0800299 bool HasTransport(const rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700300 return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800302 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700303 if (!HasTransport(transport))
304 return NULL;
305 if (cd1_.ch_.get() == transport)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000306 return &cd1_;
307 else
308 return &cd2_;
309 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000310
deadbeef14f97f52016-06-22 17:14:15 -0700311 void SetIceRole(IceRole role) { role_ = role; }
312 IceRole ice_role() { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200313 void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
314 uint64_t GetIceTiebreaker() { return tiebreaker_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000315 void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
316 bool role_conflict() { return role_conflict_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200317 void SetAllocationStepDelay(uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000318 allocator_->set_step_delay(delay);
319 }
320 void SetAllowTcpListen(bool allow_tcp_listen) {
321 allocator_->set_allow_tcp_listen(allow_tcp_listen);
322 }
323
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700324 void OnIceRegathering(PortAllocatorSession*, IceRegatheringReason reason) {
325 ++ice_regathering_counter_[reason];
326 }
327
328 int GetIceRegatheringCountForReason(IceRegatheringReason reason) {
329 return ice_regathering_counter_[reason];
330 }
331
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000332 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -0700333 std::unique_ptr<BasicPortAllocator> allocator_;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700334 webrtc::AsyncResolverFactory* async_resolver_factory_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000335 ChannelData cd1_;
336 ChannelData cd2_;
deadbeef14f97f52016-06-22 17:14:15 -0700337 IceRole role_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200338 uint64_t tiebreaker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000339 bool role_conflict_;
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000340 bool save_candidates_;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700341 std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
deadbeef14f97f52016-06-22 17:14:15 -0700342 bool ready_to_send_ = false;
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700343 std::map<IceRegatheringReason, int> ice_regathering_counter_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000344 };
345
deadbeef5bd5ca32017-02-10 11:31:50 -0800346 ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700347 if (ep1_.HasTransport(transport))
348 return ep1_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000349 else
johand89ab142016-10-25 10:50:32 -0700350 return ep2_.GetChannelData(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000351 }
352
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700353 IceParameters IceParamsWithRenomination(const IceParameters& ice,
354 bool renomination) {
355 IceParameters new_ice = ice;
356 new_ice.renomination = renomination;
357 return new_ice;
358 }
359
johan02bd5122016-09-20 00:23:27 -0700360 void CreateChannels(const IceConfig& ep1_config,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700361 const IceConfig& ep2_config,
362 bool renomination = false) {
363 IceParameters ice_ep1_cd1_ch =
364 IceParamsWithRenomination(kIceParams[0], renomination);
365 IceParameters ice_ep2_cd1_ch =
366 IceParamsWithRenomination(kIceParams[1], renomination);
367 ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
368 ice_ep1_cd1_ch, ice_ep2_cd1_ch));
369 ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
370 ice_ep2_cd1_ch, ice_ep1_cd1_ch));
deadbeefb60a8192016-08-24 15:15:00 -0700371 ep1_.cd1_.ch_->SetIceConfig(ep1_config);
372 ep2_.cd1_.ch_->SetIceConfig(ep2_config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700373 ep1_.cd1_.ch_->MaybeStartGathering();
374 ep2_.cd1_.ch_->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700375 ep1_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
376 &ep1_, &Endpoint::OnIceRegathering);
377 ep2_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
378 &ep2_, &Endpoint::OnIceRegathering);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000379 }
deadbeefb60a8192016-08-24 15:15:00 -0700380
johan02bd5122016-09-20 00:23:27 -0700381 void CreateChannels() {
deadbeefb60a8192016-08-24 15:15:00 -0700382 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -0700383 CreateChannels(default_config, default_config, false);
deadbeefb60a8192016-08-24 15:15:00 -0700384 }
385
deadbeef14f97f52016-06-22 17:14:15 -0700386 P2PTransportChannel* CreateChannel(int endpoint,
387 int component,
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700388 const IceParameters& local_ice,
389 const IceParameters& remote_ice) {
deadbeef14f97f52016-06-22 17:14:15 -0700390 P2PTransportChannel* channel = new P2PTransportChannel(
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700391 "test content name", component, GetAllocator(endpoint),
392 GetEndpoint(endpoint)->async_resolver_factory_);
deadbeef14f97f52016-06-22 17:14:15 -0700393 channel->SignalReadyToSend.connect(
394 this, &P2PTransportChannelTestBase::OnReadyToSend);
deadbeefcbecd352015-09-23 11:50:27 -0700395 channel->SignalCandidateGathered.connect(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700396 this, &P2PTransportChannelTestBase::OnCandidateGathered);
397 channel->SignalCandidatesRemoved.connect(
398 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000399 channel->SignalReadPacket.connect(
400 this, &P2PTransportChannelTestBase::OnReadPacket);
401 channel->SignalRoleConflict.connect(
402 this, &P2PTransportChannelTestBase::OnRoleConflict);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800403 channel->SignalNetworkRouteChanged.connect(
404 this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
Qingsi Wang6e641e62018-04-11 20:14:17 -0700405 channel->SignalSentPacket.connect(
406 this, &P2PTransportChannelTestBase::OnSentPacket);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700407 channel->SetIceParameters(local_ice);
408 if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
409 channel->SetRemoteIceParameters(remote_ice);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000410 }
411 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
412 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000413 return channel;
414 }
415 void DestroyChannels() {
Qingsi Wang5b8dd4d2018-06-20 13:30:43 -0700416 main_.Clear(this);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000417 ep1_.cd1_.ch_.reset();
418 ep2_.cd1_.ch_.reset();
419 ep1_.cd2_.ch_.reset();
420 ep2_.cd2_.ch_.reset();
421 }
deadbeef14f97f52016-06-22 17:14:15 -0700422 P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
423 P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
424 P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
425 P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000426
Taylor Brandstetteref184702016-06-23 17:35:47 -0700427 TestTurnServer* test_turn_server() { return &turn_server_; }
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700428 rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }
Taylor Brandstetteref184702016-06-23 17:35:47 -0700429
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000430 // Common results.
431 static const Result kLocalUdpToLocalUdp;
432 static const Result kLocalUdpToStunUdp;
433 static const Result kLocalUdpToPrflxUdp;
434 static const Result kPrflxUdpToLocalUdp;
435 static const Result kStunUdpToLocalUdp;
436 static const Result kStunUdpToStunUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700437 static const Result kStunUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000438 static const Result kPrflxUdpToStunUdp;
439 static const Result kLocalUdpToRelayUdp;
440 static const Result kPrflxUdpToRelayUdp;
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700441 static const Result kRelayUdpToPrflxUdp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000442 static const Result kLocalTcpToLocalTcp;
443 static const Result kLocalTcpToPrflxTcp;
444 static const Result kPrflxTcpToLocalTcp;
445
446 rtc::NATSocketServer* nat() { return nss_.get(); }
447 rtc::FirewallSocketServer* fw() { return ss_.get(); }
448
449 Endpoint* GetEndpoint(int endpoint) {
450 if (endpoint == 0) {
451 return &ep1_;
452 } else if (endpoint == 1) {
453 return &ep2_;
454 } else {
455 return NULL;
456 }
457 }
honghaiz7252a002016-11-08 20:04:09 -0800458 BasicPortAllocator* GetAllocator(int endpoint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000459 return GetEndpoint(endpoint)->allocator_.get();
460 }
461 void AddAddress(int endpoint, const SocketAddress& addr) {
462 GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
463 }
honghaize1a0c942016-02-16 14:54:56 -0800464 void AddAddress(int endpoint,
465 const SocketAddress& addr,
466 const std::string& ifname,
467 rtc::AdapterType adapter_type) {
468 GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
469 adapter_type);
470 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000471 void RemoveAddress(int endpoint, const SocketAddress& addr) {
472 GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700473 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000474 }
deadbeeff137e972017-03-23 15:45:49 -0700475 void SetProxy(int endpoint, rtc::ProxyType type) {
476 rtc::ProxyInfo info;
477 info.type = type;
Yves Gerey665174f2018-06-19 15:03:05 +0200478 info.address = (type == rtc::PROXY_HTTPS) ? kHttpsProxyAddrs[endpoint]
479 : kSocksProxyAddrs[endpoint];
deadbeeff137e972017-03-23 15:45:49 -0700480 GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
481 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000482 void SetAllocatorFlags(int endpoint, int flags) {
483 GetAllocator(endpoint)->set_flags(flags);
484 }
deadbeef14f97f52016-06-22 17:14:15 -0700485 void SetIceRole(int endpoint, IceRole role) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000486 GetEndpoint(endpoint)->SetIceRole(role);
487 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200488 void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000489 GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
490 }
491 bool GetRoleConflict(int endpoint) {
492 return GetEndpoint(endpoint)->role_conflict();
493 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200494 void SetAllocationStepDelay(int endpoint, uint32_t delay) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000495 return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
496 }
497 void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
498 return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
499 }
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700500
501 // Return true if the approprite parts of the expected Result, based
502 // on the local and remote candidate of ep1_ch1, match. This can be
503 // used in an EXPECT_TRUE_WAIT.
504 bool CheckCandidate1(const Result& expected) {
505 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700506 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700507 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700508 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
509 return (local_protocol == expected.controlling_protocol &&
510 remote_protocol == expected.controlled_protocol &&
511 local_type == expected.controlling_type &&
512 remote_type == expected.controlled_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700513 }
514
515 // EXPECT_EQ on the approprite parts of the expected Result, based
516 // on the local and remote candidate of ep1_ch1. This is like
517 // CheckCandidate1, except that it will provide more detail about
518 // what didn't match.
519 void ExpectCandidate1(const Result& expected) {
520 if (CheckCandidate1(expected)) {
521 return;
522 }
523
524 const std::string& local_type = LocalCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700525 const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700526 const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700527 const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
528 EXPECT_EQ(expected.controlling_type, local_type);
529 EXPECT_EQ(expected.controlled_type, remote_type);
530 EXPECT_EQ(expected.controlling_protocol, local_protocol);
531 EXPECT_EQ(expected.controlled_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700532 }
533
534 // Return true if the approprite parts of the expected Result, based
535 // on the local and remote candidate of ep2_ch1, match. This can be
536 // used in an EXPECT_TRUE_WAIT.
537 bool CheckCandidate2(const Result& expected) {
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700538 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
539 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
540 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
541 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
542 return (local_protocol == expected.controlled_protocol &&
543 remote_protocol == expected.controlling_protocol &&
544 local_type == expected.controlled_type &&
545 remote_type == expected.controlling_type);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700546 }
547
548 // EXPECT_EQ on the approprite parts of the expected Result, based
549 // on the local and remote candidate of ep2_ch1. This is like
550 // CheckCandidate2, except that it will provide more detail about
551 // what didn't match.
552 void ExpectCandidate2(const Result& expected) {
553 if (CheckCandidate2(expected)) {
554 return;
555 }
556
557 const std::string& local_type = LocalCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700558 const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700559 const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700560 const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
561 EXPECT_EQ(expected.controlled_type, local_type);
562 EXPECT_EQ(expected.controlling_type, remote_type);
563 EXPECT_EQ(expected.controlled_protocol, local_protocol);
564 EXPECT_EQ(expected.controlling_protocol, remote_protocol);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700565 }
566
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000567 void Test(const Result& expected) {
honghaize58d73d2016-10-24 16:38:26 -0700568 rtc::ScopedFakeClock clock;
nisse1bffc1d2016-05-02 08:18:55 -0700569 int64_t connect_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700570 int64_t connect_time;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000571
572 // Create the channels and wait for them to connect.
johan02bd5122016-09-20 00:23:27 -0700573 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -0700574 EXPECT_TRUE_SIMULATED_WAIT(
575 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
576 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
577 ep2_ch1()->writable(),
578 expected.connect_wait + kShortTimeout, clock);
nisse1bffc1d2016-05-02 08:18:55 -0700579 connect_time = rtc::TimeMillis() - connect_start;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000580 if (connect_time < expected.connect_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100581 RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000582 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200583 RTC_LOG(LS_INFO) << "Connect time: TIMEOUT (" << expected.connect_wait
584 << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000585 }
586
Honghai Zhang572b0942016-06-23 12:26:57 -0700587 // Allow a few turns of the crank for the selected connections to emerge.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000588 // This may take up to 2 seconds.
Honghai Zhang572b0942016-06-23 12:26:57 -0700589 if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
nisse1bffc1d2016-05-02 08:18:55 -0700590 int64_t converge_start = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700591 int64_t converge_time;
Honghai Zhang572b0942016-06-23 12:26:57 -0700592 // Verifying local and remote channel selected connection information.
593 // This is done only for the RFC 5245 as controlled agent will use
594 // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
595 // EP1 result matrix.
honghaize58d73d2016-10-24 16:38:26 -0700596 EXPECT_TRUE_SIMULATED_WAIT(
597 CheckCandidate1(expected) && CheckCandidate2(expected),
598 kMediumTimeout, clock);
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -0700599 // Also do EXPECT_EQ on each part so that failures are more verbose.
600 ExpectCandidate1(expected);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700601 ExpectCandidate2(expected);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000602
nisse1bffc1d2016-05-02 08:18:55 -0700603 converge_time = rtc::TimeMillis() - converge_start;
honghaize58d73d2016-10-24 16:38:26 -0700604 int64_t converge_wait = 2000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000605 if (converge_time < converge_wait) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100606 RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000607 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200608 RTC_LOG(LS_INFO) << "Converge time: TIMEOUT (" << converge_wait
609 << " ms)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000610 }
611 }
612 // Try sending some data to other end.
Steve Antone9324572017-11-29 10:18:21 -0800613 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000614
615 // Destroy the channels, and wait for them to be fully cleaned up.
616 DestroyChannels();
617 }
618
Sebastian Janssond624c392019-04-17 10:36:03 +0200619 void TestSendRecv(rtc::ThreadProcessingFakeClock* clock) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000620 for (int i = 0; i < 10; ++i) {
Honghai Zhang52dce732016-03-31 12:37:31 -0700621 const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000622 int len = static_cast<int>(strlen(data));
623 // local_channel1 <==> remote_channel1
honghaize58d73d2016-10-24 16:38:26 -0700624 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800625 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700626 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800627 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700628 EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800629 kMediumTimeout, *clock);
honghaize58d73d2016-10-24 16:38:26 -0700630 EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
Steve Antone9324572017-11-29 10:18:21 -0800631 kMediumTimeout, *clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000632 }
633 }
634
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700635 // This test waits for the transport to become receiving and writable on both
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700636 // end points. Once they are, the end points set new local ice parameters and
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000637 // restart the ice gathering. Finally it waits for the transport to select a
638 // new connection using the newly generated ice candidates.
639 // Before calling this function the end points must be configured.
640 void TestHandleIceUfragPasswordChanged() {
honghaize58d73d2016-10-24 16:38:26 -0700641 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700642 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
643 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
honghaize58d73d2016-10-24 16:38:26 -0700644 EXPECT_TRUE_SIMULATED_WAIT(
645 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
646 ep2_ch1()->receiving() && ep2_ch1()->writable(),
647 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000648
deadbeef14f97f52016-06-22 17:14:15 -0700649 const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
650 const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
651 const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
652 const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000653
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700654 ep1_ch1()->SetIceParameters(kIceParams[2]);
655 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeefcbecd352015-09-23 11:50:27 -0700656 ep1_ch1()->MaybeStartGathering();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700657 ep2_ch1()->SetIceParameters(kIceParams[3]);
658
659 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeefcbecd352015-09-23 11:50:27 -0700660 ep2_ch1()->MaybeStartGathering();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000661
honghaize58d73d2016-10-24 16:38:26 -0700662 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
663 old_local_candidate1->generation(),
664 kMediumTimeout, clock);
665 EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
666 old_local_candidate2->generation(),
667 kMediumTimeout, clock);
668 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
669 old_remote_candidate1->generation(),
670 kMediumTimeout, clock);
671 EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
672 old_remote_candidate2->generation(),
673 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000674 EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
675 EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
676 }
677
678 void TestSignalRoleConflict() {
honghaize58d73d2016-10-24 16:38:26 -0700679 rtc::ScopedFakeClock clock;
680 // Default EP1 is in controlling state.
681 SetIceTiebreaker(0, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000682
deadbeef14f97f52016-06-22 17:14:15 -0700683 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -0700684 SetIceTiebreaker(1, kHighTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000685
686 // Creating channels with both channels role set to CONTROLLING.
johan02bd5122016-09-20 00:23:27 -0700687 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000688 // Since both the channels initiated with controlling state and channel2
689 // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
honghaize58d73d2016-10-24 16:38:26 -0700690 EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000691 EXPECT_FALSE(GetRoleConflict(1));
692
honghaize58d73d2016-10-24 16:38:26 -0700693 EXPECT_TRUE_SIMULATED_WAIT(
694 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
695 ep2_ch1()->receiving() && ep2_ch1()->writable(),
696 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000697
Honghai Zhang572b0942016-06-23 12:26:57 -0700698 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
699 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000700
Steve Antone9324572017-11-29 10:18:21 -0800701 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000702 }
703
Qingsi Wang6e641e62018-04-11 20:14:17 -0700704 void TestPacketInfoIsSet(rtc::PacketInfo info) {
705 EXPECT_NE(info.packet_type, rtc::PacketType::kUnknown);
706 EXPECT_NE(info.protocol, rtc::PacketInfoProtocolType::kUnknown);
707 EXPECT_TRUE(info.network_id.has_value());
Qingsi Wang6e641e62018-04-11 20:14:17 -0700708 }
709
deadbeef5bd5ca32017-02-10 11:31:50 -0800710 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700711 GetEndpoint(transport)->ready_to_send_ = true;
deadbeef14f97f52016-06-22 17:14:15 -0700712 }
713
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000714 // We pass the candidates directly to the other side.
zhihuangd06adf62017-01-12 15:58:31 -0800715 void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
deadbeef14f97f52016-06-22 17:14:15 -0700716 if (force_relay_ && c.type() != RELAY_PORT_TYPE)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000717 return;
718
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000719 if (GetEndpoint(ch)->save_candidates_) {
Taylor Brandstetteref184702016-06-23 17:35:47 -0700720 GetEndpoint(ch)->saved_candidates_.push_back(
721 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000722 } else {
nisse7eaa4ea2017-05-08 05:25:41 -0700723 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
724 new CandidatesData(ch, c));
jiayl@webrtc.orgc5fd66d2014-12-29 19:23:37 +0000725 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000726 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800727
Danil Chapovalov00c71832018-06-15 15:58:38 +0200728 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800729 // If the |network_route| is unset, don't count. This is used in the case
730 // when the network on remote side is down, the signal will be fired with an
731 // unset network route and it shouldn't trigger a connection switch.
732 if (network_route) {
Honghai Zhangfd16da22016-08-17 16:12:46 -0700733 ++selected_candidate_pair_switches_;
734 }
honghaiz9ad0db52016-07-14 19:30:28 -0700735 }
736
737 int reset_selected_candidate_pair_switches() {
738 int switches = selected_candidate_pair_switches_;
739 selected_candidate_pair_switches_ = 0;
740 return switches;
741 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000742
743 void PauseCandidates(int endpoint) {
744 GetEndpoint(endpoint)->save_candidates_ = true;
745 }
746
zhihuangd06adf62017-01-12 15:58:31 -0800747 void OnCandidatesRemoved(IceTransportInternal* ch,
deadbeef14f97f52016-06-22 17:14:15 -0700748 const std::vector<Candidate>& candidates) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700749 // Candidate removals are not paused.
750 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
nisse7eaa4ea2017-05-08 05:25:41 -0700751 main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700752 }
753
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800754 // Tcp candidate verification has to be done when they are generated.
755 void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
756 for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700757 for (auto& candidate : data->candidates) {
deadbeef14f97f52016-06-22 17:14:15 -0700758 EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700759 EXPECT_EQ(candidate.tcptype(), tcptype);
deadbeef14f97f52016-06-22 17:14:15 -0700760 if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
761 EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
762 } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
763 EXPECT_NE(candidate.address().port(), DISCARD_PORT);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700764 } else {
765 FAIL() << "Unknown tcptype: " << candidate.tcptype();
766 }
Guo-wei Shieh310b0932015-11-17 19:15:50 -0800767 }
768 }
769 }
770
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000771 void ResumeCandidates(int endpoint) {
772 Endpoint* ed = GetEndpoint(endpoint);
Taylor Brandstetteref184702016-06-23 17:35:47 -0700773 for (auto& candidate : ed->saved_candidates_) {
nisse7eaa4ea2017-05-08 05:25:41 -0700774 main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000775 }
776 ed->saved_candidates_.clear();
777 ed->save_candidates_ = false;
778 }
779
780 void OnMessage(rtc::Message* msg) {
781 switch (msg->message_id) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700782 case MSG_ADD_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700783 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700784 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700785 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
786 if (!rch) {
787 return;
788 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700789 for (auto& c : data->candidates) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700790 if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700791 c.set_username("");
792 c.set_password("");
793 }
Mirko Bonadei675513b2017-11-09 11:09:25 +0100794 RTC_LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
795 << rch->component() << "): " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700796 rch->AddRemoteCandidate(c);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000797 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700798 break;
799 }
800 case MSG_REMOVE_CANDIDATES: {
kwiberg3ec46792016-04-27 07:22:53 -0700801 std::unique_ptr<CandidatesData> data(
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700802 static_cast<CandidatesData*>(msg->pdata));
deadbeef14f97f52016-06-22 17:14:15 -0700803 P2PTransportChannel* rch = GetRemoteChannel(data->channel);
804 if (!rch) {
805 return;
806 }
807 for (Candidate& c : data->candidates) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100808 RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700809 rch->RemoveRemoteCandidate(c);
810 }
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000811 break;
812 }
813 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000814 }
johand89ab142016-10-25 10:50:32 -0700815
deadbeef5bd5ca32017-02-10 11:31:50 -0800816 void OnReadPacket(rtc::PacketTransportInternal* transport,
deadbeef14f97f52016-06-22 17:14:15 -0700817 const char* data,
818 size_t len,
Niels Möllere6933812018-11-05 13:01:41 +0100819 const int64_t& /* packet_time_us */,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000820 int flags) {
johand89ab142016-10-25 10:50:32 -0700821 std::list<std::string>& packets = GetPacketList(transport);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000822 packets.push_front(std::string(data, len));
823 }
johand89ab142016-10-25 10:50:32 -0700824
zhihuangd06adf62017-01-12 15:58:31 -0800825 void OnRoleConflict(IceTransportInternal* channel) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000826 GetEndpoint(channel)->OnRoleConflict(true);
deadbeef14f97f52016-06-22 17:14:15 -0700827 IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
828 ? ICEROLE_CONTROLLED
829 : ICEROLE_CONTROLLING;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000830 channel->SetIceRole(new_role);
831 }
Honghai Zhangcc411c02016-03-29 17:27:21 -0700832
Qingsi Wang6e641e62018-04-11 20:14:17 -0700833 void OnSentPacket(rtc::PacketTransportInternal* transport,
834 const rtc::SentPacket& packet) {
835 TestPacketInfoIsSet(packet.info);
836 }
837
zhihuangd06adf62017-01-12 15:58:31 -0800838 int SendData(IceTransportInternal* channel, const char* data, size_t len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000839 rtc::PacketOptions options;
840 return channel->SendPacket(data, len, options, 0);
841 }
zhihuangd06adf62017-01-12 15:58:31 -0800842 bool CheckDataOnChannel(IceTransportInternal* channel,
deadbeef14f97f52016-06-22 17:14:15 -0700843 const char* data,
844 int len) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000845 return GetChannelData(channel)->CheckData(data, len);
846 }
deadbeef14f97f52016-06-22 17:14:15 -0700847 static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700848 return (ch && ch->selected_connection())
849 ? &ch->selected_connection()->local_candidate()
850 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000851 }
deadbeef14f97f52016-06-22 17:14:15 -0700852 static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
Honghai Zhang572b0942016-06-23 12:26:57 -0700853 return (ch && ch->selected_connection())
854 ? &ch->selected_connection()->remote_candidate()
855 : NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000856 }
deadbeef5bd5ca32017-02-10 11:31:50 -0800857 Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700858 if (ep1_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000859 return &ep1_;
johand89ab142016-10-25 10:50:32 -0700860 } else if (ep2_.HasTransport(transport)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000861 return &ep2_;
862 } else {
863 return NULL;
864 }
865 }
zhihuangd06adf62017-01-12 15:58:31 -0800866 P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000867 if (ch == ep1_ch1())
868 return ep2_ch1();
869 else if (ch == ep1_ch2())
870 return ep2_ch2();
871 else if (ch == ep2_ch1())
872 return ep1_ch1();
873 else if (ch == ep2_ch2())
874 return ep1_ch2();
875 else
876 return NULL;
877 }
johand89ab142016-10-25 10:50:32 -0700878 std::list<std::string>& GetPacketList(
deadbeef5bd5ca32017-02-10 11:31:50 -0800879 rtc::PacketTransportInternal* transport) {
johand89ab142016-10-25 10:50:32 -0700880 return GetChannelData(transport)->ch_packets_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000881 }
882
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700883 enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };
deadbeef0af180b2016-06-21 13:15:32 -0700884
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700885 // How does the test pass ICE parameters to the P2PTransportChannel?
886 // On the candidate itself, or through SetRemoteIceParameters?
deadbeef0af180b2016-06-21 13:15:32 -0700887 // Goes through the candidate itself by default.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700888 void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
889 remote_ice_parameter_source_ = source;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000890 }
891
Yves Gerey665174f2018-06-19 15:03:05 +0200892 void set_force_relay(bool relay) { force_relay_ = relay; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000893
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700894 void ConnectSignalNominated(Connection* conn) {
895 conn->SignalNominated.connect(this,
896 &P2PTransportChannelTestBase::OnNominated);
897 }
898
899 void OnNominated(Connection* conn) { nominated_ = true; }
900 bool nominated() { return nominated_; }
901
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000902 private:
kwiberg3ec46792016-04-27 07:22:53 -0700903 std::unique_ptr<rtc::VirtualSocketServer> vss_;
904 std::unique_ptr<rtc::NATSocketServer> nss_;
905 std::unique_ptr<rtc::FirewallSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700906 rtc::AutoSocketServerThread main_;
deadbeef14f97f52016-06-22 17:14:15 -0700907 std::unique_ptr<TestStunServer> stun_server_;
908 TestTurnServer turn_server_;
deadbeeff137e972017-03-23 15:45:49 -0700909 rtc::SocksProxyServer socks_server1_;
910 rtc::SocksProxyServer socks_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000911 Endpoint ep1_;
912 Endpoint ep2_;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700913 RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000914 bool force_relay_;
honghaiz9ad0db52016-07-14 19:30:28 -0700915 int selected_candidate_pair_switches_ = 0;
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700916
917 bool nominated_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000918};
919
920// The tests have only a few outcomes, which we predefine.
Taylor Brandstetter62351c92016-08-11 16:05:07 -0700921const P2PTransportChannelTestBase::Result
922 P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
923 "udp",
924 "local",
925 "udp",
926 1000);
927const P2PTransportChannelTestBase::Result
928 P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
929 "udp",
930 "stun",
931 "udp",
932 1000);
933const P2PTransportChannelTestBase::Result
934 P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
935 "udp",
936 "prflx",
937 "udp",
938 1000);
939const P2PTransportChannelTestBase::Result
940 P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
941 "udp",
942 "local",
943 "udp",
944 1000);
945const P2PTransportChannelTestBase::Result
946 P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
947 "udp",
948 "local",
949 "udp",
950 1000);
951const P2PTransportChannelTestBase::Result
952 P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
953 "udp",
954 "stun",
955 "udp",
956 1000);
957const P2PTransportChannelTestBase::Result
958 P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
959 "udp",
960 "prflx",
961 "udp",
962 1000);
963const P2PTransportChannelTestBase::Result
964 P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
965 "udp",
966 "stun",
967 "udp",
968 1000);
969const P2PTransportChannelTestBase::Result
970 P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
971 "udp",
972 "relay",
973 "udp",
974 2000);
975const P2PTransportChannelTestBase::Result
976 P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
977 "udp",
978 "relay",
979 "udp",
980 2000);
981const P2PTransportChannelTestBase::Result
982 P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
983 "udp",
984 "prflx",
985 "udp",
986 2000);
987const P2PTransportChannelTestBase::Result
988 P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
989 "tcp",
990 "local",
991 "tcp",
992 3000);
993const P2PTransportChannelTestBase::Result
994 P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
995 "tcp",
996 "prflx",
997 "tcp",
998 3000);
999const P2PTransportChannelTestBase::Result
1000 P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
1001 "tcp",
1002 "local",
1003 "tcp",
1004 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001005
1006// Test the matrix of all the connectivity types we expect to see in the wild.
1007// Just test every combination of the configs in the Config enum.
1008class P2PTransportChannelTest : public P2PTransportChannelTestBase {
1009 protected:
1010 static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
deadbeefcbecd352015-09-23 11:50:27 -07001011 void ConfigureEndpoints(Config config1,
1012 Config config2,
1013 int allocator_flags1,
1014 int allocator_flags2) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001015 ConfigureEndpoint(0, config1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001016 SetAllocatorFlags(0, allocator_flags1);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001017 SetAllocationStepDelay(0, kMinimumStepDelay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001018 ConfigureEndpoint(1, config2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001019 SetAllocatorFlags(1, allocator_flags2);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001020 SetAllocationStepDelay(1, kMinimumStepDelay);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001021
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001022 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001023 }
1024 void ConfigureEndpoint(int endpoint, Config config) {
1025 switch (config) {
1026 case OPEN:
1027 AddAddress(endpoint, kPublicAddrs[endpoint]);
1028 break;
1029 case NAT_FULL_CONE:
1030 case NAT_ADDR_RESTRICTED:
1031 case NAT_PORT_RESTRICTED:
1032 case NAT_SYMMETRIC:
1033 AddAddress(endpoint, kPrivateAddrs[endpoint]);
1034 // Add a single NAT of the desired type
Yves Gerey665174f2018-06-19 15:03:05 +02001035 nat()
1036 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1037 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
1038 ->AddClient(kPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001039 break;
1040 case NAT_DOUBLE_CONE:
1041 case NAT_SYMMETRIC_THEN_CONE:
1042 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
1043 // Add a two cascaded NATs of the desired types
Yves Gerey665174f2018-06-19 15:03:05 +02001044 nat()
1045 ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
1046 (config == NAT_DOUBLE_CONE) ? rtc::NAT_OPEN_CONE
1047 : rtc::NAT_SYMMETRIC)
1048 ->AddTranslator(kPrivateAddrs[endpoint],
1049 kCascadedNatAddrs[endpoint], rtc::NAT_OPEN_CONE)
1050 ->AddClient(kCascadedPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001051 break;
1052 case BLOCK_UDP:
1053 case BLOCK_UDP_AND_INCOMING_TCP:
deadbeeff137e972017-03-23 15:45:49 -07001054 case BLOCK_ALL_BUT_OUTGOING_HTTP:
1055 case PROXY_HTTPS:
1056 case PROXY_SOCKS:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001057 AddAddress(endpoint, kPublicAddrs[endpoint]);
1058 // Block all UDP
Yves Gerey665174f2018-06-19 15:03:05 +02001059 fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001060 if (config == BLOCK_UDP_AND_INCOMING_TCP) {
1061 // Block TCP inbound to the endpoint
1062 fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
1063 kPublicAddrs[endpoint]);
deadbeeff137e972017-03-23 15:45:49 -07001064 } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
1065 // Block all TCP to/from the endpoint except 80/443 out
1066 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1067 SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
1068 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1069 SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
1070 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1071 kPublicAddrs[endpoint]);
1072 } else if (config == PROXY_HTTPS) {
1073 // Block all TCP to/from the endpoint except to the proxy server
1074 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1075 kHttpsProxyAddrs[endpoint]);
1076 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1077 kPublicAddrs[endpoint]);
1078 SetProxy(endpoint, rtc::PROXY_HTTPS);
1079 } else if (config == PROXY_SOCKS) {
1080 // Block all TCP to/from the endpoint except to the proxy server
1081 fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
1082 kSocksProxyAddrs[endpoint]);
1083 fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
1084 kPublicAddrs[endpoint]);
1085 SetProxy(endpoint, rtc::PROXY_SOCKS5);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001086 }
1087 break;
1088 default:
deadbeef1ee21252017-06-13 15:49:45 -07001089 RTC_NOTREACHED();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001090 break;
1091 }
1092 }
1093};
1094
1095// Shorthands for use in the test matrix.
1096#define LULU &kLocalUdpToLocalUdp
1097#define LUSU &kLocalUdpToStunUdp
1098#define LUPU &kLocalUdpToPrflxUdp
1099#define PULU &kPrflxUdpToLocalUdp
1100#define SULU &kStunUdpToLocalUdp
1101#define SUSU &kStunUdpToStunUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001102#define SUPU &kStunUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001103#define PUSU &kPrflxUdpToStunUdp
1104#define LURU &kLocalUdpToRelayUdp
1105#define PURU &kPrflxUdpToRelayUdp
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001106#define RUPU &kRelayUdpToPrflxUdp
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001107#define LTLT &kLocalTcpToLocalTcp
1108#define LTPT &kLocalTcpToPrflxTcp
1109#define PTLT &kPrflxTcpToLocalTcp
Steve Antone9324572017-11-29 10:18:21 -08001110// TODO(?): Enable these once TestRelayServer can accept external TCP.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001111#define LTRT NULL
1112#define LSRS NULL
1113
1114// Test matrix. Originator behavior defined by rows, receiever by columns.
1115
Steve Antone9324572017-11-29 10:18:21 -08001116// TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
1117// TODO(?): Fix NULLs caused by no HTTP proxy support.
1118// TODO(?): Rearrange rows/columns from best to worst.
Taylor Brandstetter62351c92016-08-11 16:05:07 -07001119const P2PTransportChannelTest::Result*
1120 P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
Yves Gerey665174f2018-06-19 15:03:05 +02001121 // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH
1122 // PRXS
1123 /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS,
1124 NULL, LTPT},
1125 /*CO*/
1126 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1127 LTRT},
1128 /*AD*/
1129 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1130 LTRT},
1131 /*PO*/
1132 {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL,
1133 LTRT},
1134 /*SY*/
1135 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1136 LTRT},
1137 /*2C*/
1138 {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
1139 LTRT},
1140 /*SC*/
1141 {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
1142 LTRT},
1143 /*!U*/
1144 {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL,
1145 LTRT},
1146 /*!T*/
1147 {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL,
1148 LTRT},
1149 /*HT*/
1150 {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL,
1151 LSRS},
1152 /*PR*/
1153 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1154 NULL},
1155 /*PR*/
1156 {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL,
1157 LTRT},
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001158};
1159
1160// The actual tests that exercise all the various configurations.
1161// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
deadbeefcbecd352015-09-23 11:50:27 -07001162#define P2P_TEST_DECLARATION(x, y, z) \
1163 TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
1164 ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
1165 PORTALLOCATOR_ENABLE_SHARED_SOCKET); \
Taylor Brandstetter7e1b8fb2016-05-26 15:21:45 -07001166 if (kMatrix[x][y] != NULL) \
1167 Test(*kMatrix[x][y]); \
deadbeefcbecd352015-09-23 11:50:27 -07001168 else \
Mirko Bonadei675513b2017-11-09 11:09:25 +01001169 RTC_LOG(LS_WARNING) << "Not yet implemented"; \
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001170 }
1171
Steve Antone9324572017-11-29 10:18:21 -08001172#define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001173
deadbeeff137e972017-03-23 15:45:49 -07001174#define P2P_TEST_SET(x) \
1175 P2P_TEST(x, OPEN) \
1176 P2P_TEST(x, NAT_FULL_CONE) \
1177 P2P_TEST(x, NAT_ADDR_RESTRICTED) \
1178 P2P_TEST(x, NAT_PORT_RESTRICTED) \
1179 P2P_TEST(x, NAT_SYMMETRIC) \
1180 P2P_TEST(x, NAT_DOUBLE_CONE) \
1181 P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
1182 P2P_TEST(x, BLOCK_UDP) \
1183 P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
1184 P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
1185 P2P_TEST(x, PROXY_HTTPS) \
1186 P2P_TEST(x, PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001187
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001188P2P_TEST_SET(OPEN)
1189P2P_TEST_SET(NAT_FULL_CONE)
1190P2P_TEST_SET(NAT_ADDR_RESTRICTED)
1191P2P_TEST_SET(NAT_PORT_RESTRICTED)
1192P2P_TEST_SET(NAT_SYMMETRIC)
1193P2P_TEST_SET(NAT_DOUBLE_CONE)
1194P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
1195P2P_TEST_SET(BLOCK_UDP)
1196P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
deadbeeff137e972017-03-23 15:45:49 -07001197P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
1198P2P_TEST_SET(PROXY_HTTPS)
1199P2P_TEST_SET(PROXY_SOCKS)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001200
1201// Test that we restart candidate allocation when local ufrag&pwd changed.
1202// Standard Ice protocol is used.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001203TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
deadbeefcbecd352015-09-23 11:50:27 -07001204 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001205 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001206 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001207 TestHandleIceUfragPasswordChanged();
1208 DestroyChannels();
1209}
1210
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001211// Same as above test, but with a symmetric NAT.
1212// We should end up with relay<->prflx candidate pairs, with generation "1".
1213TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
1214 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
1215 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001216 CreateChannels();
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001217 TestHandleIceUfragPasswordChanged();
1218 DestroyChannels();
1219}
1220
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001221// Test the operation of GetStats.
1222TEST_F(P2PTransportChannelTest, GetStats) {
honghaize58d73d2016-10-24 16:38:26 -07001223 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001224 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001225 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001226 CreateChannels();
honghaize58d73d2016-10-24 16:38:26 -07001227 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1228 ep2_ch1()->receiving() &&
1229 ep2_ch1()->writable(),
1230 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08001231 TestSendRecv(&clock);
Jonas Oreland149dc722019-08-28 08:10:27 +02001232 IceTransportStats ice_transport_stats;
1233 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
1234 ASSERT_GE(ice_transport_stats.connection_infos.size(), 1u);
1235 ASSERT_GE(ice_transport_stats.candidate_stats_list.size(), 1u);
1236 EXPECT_EQ(ice_transport_stats.selected_candidate_pair_changes, 1u);
deadbeef14f97f52016-06-22 17:14:15 -07001237 ConnectionInfo* best_conn_info = nullptr;
Jonas Oreland149dc722019-08-28 08:10:27 +02001238 for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
Honghai Zhang2b342bf2015-09-30 09:51:58 -07001239 if (info.best_connection) {
1240 best_conn_info = &info;
1241 break;
1242 }
1243 }
1244 ASSERT_TRUE(best_conn_info != nullptr);
1245 EXPECT_TRUE(best_conn_info->new_connection);
1246 EXPECT_TRUE(best_conn_info->receiving);
1247 EXPECT_TRUE(best_conn_info->writable);
1248 EXPECT_FALSE(best_conn_info->timeout);
1249 EXPECT_EQ(10U, best_conn_info->sent_total_packets);
1250 EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
1251 EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
1252 EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001253 DestroyChannels();
1254}
1255
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001256// Tests that UMAs are recorded when ICE restarts while the channel
1257// is disconnected.
1258TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
1259 rtc::ScopedFakeClock clock;
1260 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1261
1262 CreateChannels();
1263 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1264 ep2_ch1()->receiving() &&
1265 ep2_ch1()->writable(),
1266 kDefaultTimeout, clock);
1267
1268 // Drop all packets so that both channels become not writable.
1269 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
skvlad51072462017-02-02 11:50:14 -08001270 const int kWriteTimeoutDelay = 8000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001271 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
1272 kWriteTimeoutDelay, clock);
1273
1274 ep1_ch1()->SetIceParameters(kIceParams[2]);
1275 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1276 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001277 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1278 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001279 static_cast<int>(IceRestartState::DISCONNECTED)));
1280
1281 ep2_ch1()->SetIceParameters(kIceParams[3]);
1282 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1283 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001284 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1285 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001286 static_cast<int>(IceRestartState::DISCONNECTED)));
1287
1288 DestroyChannels();
1289}
1290
1291// Tests that UMAs are recorded when ICE restarts while the channel
1292// is connected.
1293TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
1294 rtc::ScopedFakeClock clock;
1295 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1296
1297 CreateChannels();
1298 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1299 ep2_ch1()->receiving() &&
1300 ep2_ch1()->writable(),
1301 kDefaultTimeout, clock);
1302
1303 ep1_ch1()->SetIceParameters(kIceParams[2]);
1304 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1305 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001306 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1307 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001308 static_cast<int>(IceRestartState::CONNECTED)));
1309
1310 ep2_ch1()->SetIceParameters(kIceParams[3]);
1311 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1312 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001313 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1314 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001315 static_cast<int>(IceRestartState::CONNECTED)));
1316
1317 DestroyChannels();
1318}
1319
1320// Tests that UMAs are recorded when ICE restarts while the channel
1321// is connecting.
1322TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
1323 rtc::ScopedFakeClock clock;
1324 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1325
1326 // Create the channels without waiting for them to become connected.
1327 CreateChannels();
1328
1329 ep1_ch1()->SetIceParameters(kIceParams[2]);
1330 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1331 ep1_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001332 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1333 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001334 static_cast<int>(IceRestartState::CONNECTING)));
1335
1336 ep2_ch1()->SetIceParameters(kIceParams[3]);
1337 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1338 ep2_ch1()->MaybeStartGathering();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001339 EXPECT_EQ(2, webrtc::metrics::NumEvents(
1340 "WebRTC.PeerConnection.IceRestartState",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001341 static_cast<int>(IceRestartState::CONNECTING)));
1342
1343 DestroyChannels();
1344}
1345
1346// Tests that a UMA on ICE regathering is recorded when there is a network
1347// change if and only if continual gathering is enabled.
1348TEST_F(P2PTransportChannelTest,
1349 TestIceRegatheringReasonContinualGatheringByNetworkChange) {
1350 rtc::ScopedFakeClock clock;
1351 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1352
1353 // ep1 gathers continually but ep2 does not.
1354 IceConfig continual_gathering_config =
1355 CreateIceConfig(1000, GATHER_CONTINUALLY);
1356 IceConfig default_config;
1357 CreateChannels(continual_gathering_config, default_config);
1358
1359 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1360 ep2_ch1()->receiving() &&
1361 ep2_ch1()->writable(),
1362 kDefaultTimeout, clock);
1363
1364 // Adding address in ep1 will trigger continual gathering.
1365 AddAddress(0, kAlternateAddrs[0]);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001366 EXPECT_EQ_SIMULATED_WAIT(1,
1367 GetEndpoint(0)->GetIceRegatheringCountForReason(
1368 IceRegatheringReason::NETWORK_CHANGE),
1369 kDefaultTimeout, clock);
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001370
1371 ep2_ch1()->SetIceParameters(kIceParams[3]);
1372 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
1373 ep2_ch1()->MaybeStartGathering();
1374
1375 AddAddress(1, kAlternateAddrs[1]);
1376 SIMULATED_WAIT(false, kDefaultTimeout, clock);
1377 // ep2 has not enabled continual gathering.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001378 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1379 IceRegatheringReason::NETWORK_CHANGE));
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001380
1381 DestroyChannels();
1382}
1383
1384// Tests that a UMA on ICE regathering is recorded when there is a network
1385// failure if and only if continual gathering is enabled.
1386TEST_F(P2PTransportChannelTest,
1387 TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
1388 rtc::ScopedFakeClock clock;
1389 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1390
1391 // ep1 gathers continually but ep2 does not.
1392 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001393 config1.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001394 IceConfig config2;
Oskar Sundbom903dcd72017-11-16 10:55:57 +01001395 config2.regather_on_failed_networks_interval = 2000;
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001396 CreateChannels(config1, config2);
1397
1398 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1399 ep2_ch1()->receiving() &&
1400 ep2_ch1()->writable(),
1401 kDefaultTimeout, clock);
1402
1403 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1404 // Timeout value such that all connections are deleted.
1405 const int kNetworkFailureTimeout = 35000;
1406 SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001407 EXPECT_LE(1, GetEndpoint(0)->GetIceRegatheringCountForReason(
1408 IceRegatheringReason::NETWORK_FAILURE));
1409 EXPECT_LE(1, webrtc::metrics::NumEvents(
1410 "WebRTC.PeerConnection.IceRegatheringReason",
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001411 static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001412 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1413 IceRegatheringReason::NETWORK_FAILURE));
Honghai Zhangd93f50c2016-10-05 11:47:22 -07001414
1415 DestroyChannels();
1416}
1417
Steve Anton300bf8e2017-07-14 10:13:10 -07001418// Tests that ICE regathering occurs regularly when
1419// regather_all_networks_interval_range configuration value is set.
1420TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
1421 rtc::ScopedFakeClock clock;
1422 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1423
1424 // ep1 gathers continually but ep2 does not.
1425 const int kRegatherInterval = 2000;
1426 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Yves Gerey665174f2018-06-19 15:03:05 +02001427 config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
1428 kRegatherInterval);
Steve Anton300bf8e2017-07-14 10:13:10 -07001429 IceConfig config2;
Steve Anton300bf8e2017-07-14 10:13:10 -07001430 CreateChannels(config1, config2);
1431
1432 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1433 ep2_ch1()->receiving() &&
1434 ep2_ch1()->writable(),
1435 kDefaultTimeout, clock);
1436
1437 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1438 // Timeout value such that all connections are deleted.
1439 const int kNetworkGatherDuration = 11000;
1440 SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
1441 // Expect regathering to happen 5 times in 11s with 2s interval.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001442 EXPECT_LE(5, GetEndpoint(0)->GetIceRegatheringCountForReason(
1443 IceRegatheringReason::OCCASIONAL_REFRESH));
1444 EXPECT_LE(5, webrtc::metrics::NumEvents(
1445 "WebRTC.PeerConnection.IceRegatheringReason",
Steve Anton300bf8e2017-07-14 10:13:10 -07001446 static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
1447 // Expect no regathering if continual gathering not configured.
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001448 EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
1449 IceRegatheringReason::OCCASIONAL_REFRESH));
Steve Anton300bf8e2017-07-14 10:13:10 -07001450
1451 DestroyChannels();
1452}
1453
1454// Test that ICE periodic regathering can change the selected connection on the
1455// specified interval and that the peers can communicate over the new
1456// connection. The test is parameterized to test that it works when regathering
1457// is done by the ICE controlling peer and when done by the controlled peer.
1458class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
1459 protected:
1460 void TestWithRoles(IceRole p1_role, IceRole p2_role) {
1461 rtc::ScopedFakeClock clock;
1462 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Yves Gerey665174f2018-06-19 15:03:05 +02001463 kDefaultPortAllocatorFlags);
Steve Anton300bf8e2017-07-14 10:13:10 -07001464 set_force_relay(true);
1465
1466 const int kRegatherInterval = 2000;
1467 const int kNumRegathers = 2;
1468
1469 // Set up peer 1 to auto regather every 2s.
1470 IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
Yves Gerey665174f2018-06-19 15:03:05 +02001471 config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
1472 kRegatherInterval);
Steve Anton300bf8e2017-07-14 10:13:10 -07001473 IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
1474
1475 // Set peer roles.
1476 SetIceRole(0, p1_role);
1477 SetIceRole(1, p2_role);
1478
1479 CreateChannels(config1, config2);
1480
1481 // Wait for initial connection to be made.
Yves Gerey665174f2018-06-19 15:03:05 +02001482 EXPECT_TRUE_SIMULATED_WAIT(
1483 ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1484 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1485 kMediumTimeout, clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001486
1487 const Connection* initial_selected = ep1_ch1()->selected_connection();
1488
1489 // Wait long enough for 2 regathering cycles to happen plus some extra so
1490 // the new connection has time to settle.
1491 const int kWaitRegather =
1492 kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
1493 SIMULATED_WAIT(false, kWaitRegather, clock);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001494 EXPECT_EQ(kNumRegathers, GetEndpoint(0)->GetIceRegatheringCountForReason(
1495 IceRegatheringReason::OCCASIONAL_REFRESH));
Steve Anton300bf8e2017-07-14 10:13:10 -07001496
1497 const Connection* new_selected = ep1_ch1()->selected_connection();
1498
1499 // Want the new selected connection to be different.
1500 ASSERT_NE(initial_selected, new_selected);
1501
1502 // Make sure we can communicate over the new connection too.
Steve Antone9324572017-11-29 10:18:21 -08001503 TestSendRecv(&clock);
Steve Anton300bf8e2017-07-14 10:13:10 -07001504 }
1505};
1506
1507TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
1508 TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
1509}
1510
1511TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
1512 TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
1513}
1514
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001515// Test that we properly create a connection on a STUN ping from unknown address
1516// when the signaling is slow.
1517TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
deadbeefcbecd352015-09-23 11:50:27 -07001518 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001519 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001520 // Emulate no remote parameters coming in.
1521 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001522 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001523 // Only have remote parameters come in for ep2, not ep1.
1524 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001525
1526 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1527 // candidate.
1528 PauseCandidates(1);
1529
Honghai Zhange05bcc22016-08-16 18:19:14 -07001530 // Wait until the callee becomes writable to make sure that a ping request is
1531 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001532 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001533 // Add two sets of remote ICE credentials, so that the ones used by the
1534 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001535 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1536 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001537 // The caller should have the selected connection connected to the peer
1538 // reflexive candidate.
1539 const Connection* selected_connection = nullptr;
1540 ASSERT_TRUE_WAIT(
1541 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001542 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001543 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001544 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1545 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1546 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001547
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001548 ResumeCandidates(1);
Honghai Zhang572b0942016-06-23 12:26:57 -07001549 // Verify ep1's selected connection is updated to use the 'local' candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001550 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001551 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001552 kMediumTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001553 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001554 DestroyChannels();
1555}
1556
Qingsi Wang7627fdd2019-08-19 16:07:40 -07001557// Test that if we learn a prflx remote candidate, its address is concealed in
1558// 1. the selected candidate pair accessed via the public API, and
1559// 2. the candidate pair stats
1560// until we learn the same address from signaling.
1561TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) {
1562 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
1563 // Emulate no remote parameters coming in.
1564 set_remote_ice_parameter_source(FROM_CANDIDATE);
1565 CreateChannels();
1566 // Only have remote parameters come in for ep2, not ep1.
1567 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
1568
1569 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1570 // candidate.
1571 PauseCandidates(1);
1572
1573 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
1574 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1575 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
1576
1577 // Check the selected candidate pair.
1578 auto pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
1579 ASSERT_TRUE(pair_ep1.has_value());
1580 EXPECT_EQ(PRFLX_PORT_TYPE, pair_ep1->remote_candidate().type());
1581 EXPECT_TRUE(pair_ep1->remote_candidate().address().ipaddr().IsNil());
1582
Jonas Oreland149dc722019-08-28 08:10:27 +02001583 IceTransportStats ice_transport_stats;
1584 ep1_ch1()->GetStats(&ice_transport_stats);
Qingsi Wang7627fdd2019-08-19 16:07:40 -07001585 // Check the candidate pair stats.
Jonas Oreland149dc722019-08-28 08:10:27 +02001586 ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
1587 EXPECT_EQ(PRFLX_PORT_TYPE,
1588 ice_transport_stats.connection_infos[0].remote_candidate.type());
1589 EXPECT_TRUE(ice_transport_stats.connection_infos[0]
1590 .remote_candidate.address()
1591 .ipaddr()
1592 .IsNil());
Qingsi Wang7627fdd2019-08-19 16:07:40 -07001593
1594 // Let ep1 receive the remote candidate to update its type from prflx to host.
1595 ResumeCandidates(1);
1596 ASSERT_TRUE_WAIT(
1597 ep1_ch1()->selected_connection() != nullptr &&
1598 ep1_ch1()->selected_connection()->remote_candidate().type() ==
1599 LOCAL_PORT_TYPE,
1600 kMediumTimeout);
1601
1602 // We should be able to reveal the address after it is learnt via
1603 // AddIceCandidate.
1604 //
1605 // Check the selected candidate pair.
1606 auto updated_pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
1607 ASSERT_TRUE(updated_pair_ep1.has_value());
1608 EXPECT_EQ(LOCAL_PORT_TYPE, updated_pair_ep1->remote_candidate().type());
1609 EXPECT_TRUE(
1610 updated_pair_ep1->remote_candidate().address().EqualIPs(kPublicAddrs[1]));
1611
Jonas Oreland149dc722019-08-28 08:10:27 +02001612 ep1_ch1()->GetStats(&ice_transport_stats);
Qingsi Wang7627fdd2019-08-19 16:07:40 -07001613 // Check the candidate pair stats.
Jonas Oreland149dc722019-08-28 08:10:27 +02001614 ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
1615 EXPECT_EQ(LOCAL_PORT_TYPE,
1616 ice_transport_stats.connection_infos[0].remote_candidate.type());
1617 EXPECT_TRUE(ice_transport_stats.connection_infos[0]
1618 .remote_candidate.address()
1619 .EqualIPs(kPublicAddrs[1]));
Qingsi Wang7627fdd2019-08-19 16:07:40 -07001620
1621 DestroyChannels();
1622}
1623
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001624// Test that we properly create a connection on a STUN ping from unknown address
1625// when the signaling is slow and the end points are behind NAT.
1626TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
deadbeefcbecd352015-09-23 11:50:27 -07001627 ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001628 kDefaultPortAllocatorFlags);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001629 // Emulate no remote parameters coming in.
1630 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001631 CreateChannels();
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001632 // Only have remote parameters come in for ep2, not ep1.
1633 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001634 // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
1635 // candidate.
1636 PauseCandidates(1);
1637
Honghai Zhange05bcc22016-08-16 18:19:14 -07001638 // Wait until the callee becomes writable to make sure that a ping request is
1639 // received by the caller before his remote ICE credentials are set.
Honghai Zhang161a5862016-10-20 11:47:02 -07001640 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001641 // Add two sets of remote ICE credentials, so that the ones used by the
1642 // candidate will be generation 1 instead of 0.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001643 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
1644 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001645
1646 // The caller's selected connection should be connected to the peer reflexive
1647 // candidate.
1648 const Connection* selected_connection = nullptr;
1649 ASSERT_TRUE_WAIT(
1650 (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07001651 kMediumTimeout);
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001652 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Honghai Zhange05bcc22016-08-16 18:19:14 -07001653 EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
1654 EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
1655 EXPECT_EQ(1u, selected_connection->remote_candidate().generation());
Taylor Brandstetter0a1bc532016-04-19 18:03:26 -07001656
1657 ResumeCandidates(1);
Peter Thatcher7351f462015-04-02 16:39:16 -07001658
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001659 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhange05bcc22016-08-16 18:19:14 -07001660 ep1_ch1()->selected_connection()->remote_candidate().type(),
Honghai Zhang161a5862016-10-20 11:47:02 -07001661 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07001662 EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001663 DestroyChannels();
1664}
1665
deadbeef0af180b2016-06-21 13:15:32 -07001666// Test that we properly create a connection on a STUN ping from unknown address
1667// when the signaling is slow, even if the new candidate is created due to the
1668// remote peer doing an ICE restart, pairing this candidate across generations.
1669//
1670// Previously this wasn't working due to a bug where the peer reflexive
1671// candidate was only updated for the newest generation candidate pairs, and
1672// not older-generation candidate pairs created by pairing candidates across
1673// generations. This resulted in the old-generation prflx candidate being
1674// prioritized above new-generation candidate pairs.
1675TEST_F(P2PTransportChannelTest,
1676 PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
1677 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
1678 kDefaultPortAllocatorFlags);
1679 // Only gather relay candidates, so that when the prflx candidate arrives
1680 // it's prioritized above the current candidate pair.
Qingsi Wangc129c352019-04-18 10:41:58 -07001681 GetEndpoint(0)->allocator_->SetCandidateFilter(CF_RELAY);
1682 GetEndpoint(1)->allocator_->SetCandidateFilter(CF_RELAY);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001683 // Setting this allows us to control when SetRemoteIceParameters is called.
1684 set_remote_ice_parameter_source(FROM_CANDIDATE);
johan02bd5122016-09-20 00:23:27 -07001685 CreateChannels();
deadbeef0af180b2016-06-21 13:15:32 -07001686 // Wait for the initial connection to be made.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001687 ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
1688 ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
deadbeef0af180b2016-06-21 13:15:32 -07001689 EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1690 ep2_ch1()->receiving() && ep2_ch1()->writable(),
1691 kDefaultTimeout);
1692
1693 // Simulate an ICE restart on ep2, but don't signal the candidate or new
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001694 // ICE parameters until after a prflx connection has been made.
deadbeef0af180b2016-06-21 13:15:32 -07001695 PauseCandidates(1);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001696 ep2_ch1()->SetIceParameters(kIceParams[3]);
1697
1698 ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
deadbeef0af180b2016-06-21 13:15:32 -07001699 ep2_ch1()->MaybeStartGathering();
1700
Honghai Zhang572b0942016-06-23 12:26:57 -07001701 // The caller should have the selected connection connected to the peer
1702 // reflexive candidate.
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001703 EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001704 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001705 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001706 const Connection* prflx_selected_connection =
1707 ep1_ch1()->selected_connection();
deadbeef0af180b2016-06-21 13:15:32 -07001708
1709 // Now simulate the ICE restart on ep1.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001710 ep1_ch1()->SetIceParameters(kIceParams[2]);
1711
1712 ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
deadbeef0af180b2016-06-21 13:15:32 -07001713 ep1_ch1()->MaybeStartGathering();
1714
1715 // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
1716 // their information to update the peer reflexive candidate.
1717 ResumeCandidates(1);
1718
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001719 EXPECT_EQ_WAIT(RELAY_PORT_TYPE,
Honghai Zhang572b0942016-06-23 12:26:57 -07001720 ep1_ch1()->selected_connection()->remote_candidate().type(),
deadbeef0af180b2016-06-21 13:15:32 -07001721 kDefaultTimeout);
Honghai Zhang572b0942016-06-23 12:26:57 -07001722 EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
deadbeef0af180b2016-06-21 13:15:32 -07001723 DestroyChannels();
1724}
1725
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001726// Test that if remote candidates don't have ufrag and pwd, we still work.
1727TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001728 rtc::ScopedFakeClock clock;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001729 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefcbecd352015-09-23 11:50:27 -07001730 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001731 kDefaultPortAllocatorFlags);
johan02bd5122016-09-20 00:23:27 -07001732 CreateChannels();
Honghai Zhang572b0942016-06-23 12:26:57 -07001733 const Connection* selected_connection = NULL;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001734 // Wait until the callee's connections are created.
Honghai Zhang161a5862016-10-20 11:47:02 -07001735 EXPECT_TRUE_SIMULATED_WAIT(
1736 (selected_connection = ep2_ch1()->selected_connection()) != NULL,
1737 kMediumTimeout, clock);
1738 // Wait to make sure the selected connection is not changed.
1739 SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
1740 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001741 EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001742 DestroyChannels();
1743}
1744
1745// Test that a host behind NAT cannot be reached when incoming_only
1746// is set to true.
1747TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
honghaize58d73d2016-10-24 16:38:26 -07001748 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001749 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001750 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001751
1752 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001753 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001754 ep1_ch1()->set_incoming_only(true);
1755
1756 // Pump for 1 second and verify that the channels are not connected.
honghaize58d73d2016-10-24 16:38:26 -07001757 SIMULATED_WAIT(false, kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001758
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001759 EXPECT_FALSE(ep1_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001760 EXPECT_FALSE(ep1_ch1()->writable());
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001761 EXPECT_FALSE(ep2_ch1()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001762 EXPECT_FALSE(ep2_ch1()->writable());
1763
1764 DestroyChannels();
1765}
1766
1767// Test that a peer behind NAT can connect to a peer that has
1768// incoming_only flag set.
1769TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
honghaize58d73d2016-10-24 16:38:26 -07001770 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001771 ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001772 kDefaultPortAllocatorFlags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001773
1774 SetAllocatorFlags(0, kOnlyLocalPorts);
johan02bd5122016-09-20 00:23:27 -07001775 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001776 ep1_ch1()->set_incoming_only(true);
1777
honghaize58d73d2016-10-24 16:38:26 -07001778 EXPECT_TRUE_SIMULATED_WAIT(
1779 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
1780 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
1781 ep2_ch1()->writable(),
1782 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001783
1784 DestroyChannels();
1785}
1786
deadbeef1ee21252017-06-13 15:49:45 -07001787// Test that two peers can connect when one can only make outgoing TCP
1788// connections. This has been observed in some scenarios involving
1789// VPNs/firewalls.
1790TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
Mirko Bonadei5f4d47b2018-08-22 17:41:22 +00001791 // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
1792 // application needs this use case to work, since the application must accept
1793 // the tradeoff that more candidates need to be allocated.
1794 //
1795 // TODO(deadbeef): Later, make this flag the default, and do more elegant
1796 // things to ensure extra candidates don't waste resources?
1797 ConfigureEndpoints(
1798 OPEN, OPEN,
1799 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
1800 kDefaultPortAllocatorFlags);
deadbeef1ee21252017-06-13 15:49:45 -07001801 // In order to simulate nothing working but outgoing TCP connections, prevent
1802 // the endpoint from binding to its interface's address as well as the
1803 // "any" addresses. It can then only make a connection by using "Connect()".
1804 fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
1805 kPublicAddrs[0].ipaddr()});
1806 CreateChannels();
1807 // Expect a "prflx" candidate on the side that can only make outgoing
1808 // connections, endpoint 0.
1809 Test(kPrflxTcpToLocalTcp);
1810 DestroyChannels();
1811}
1812
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001813TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
honghaize58d73d2016-10-24 16:38:26 -07001814 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001815 AddAddress(0, kPublicAddrs[0]);
1816 AddAddress(1, kPublicAddrs[1]);
1817
1818 SetAllocationStepDelay(0, kMinimumStepDelay);
1819 SetAllocationStepDelay(1, kMinimumStepDelay);
1820
deadbeef14f97f52016-06-22 17:14:15 -07001821 int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
1822 PORTALLOCATOR_DISABLE_STUN |
1823 PORTALLOCATOR_DISABLE_RELAY;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001824 // Disable all protocols except TCP.
1825 SetAllocatorFlags(0, kOnlyLocalTcpPorts);
1826 SetAllocatorFlags(1, kOnlyLocalTcpPorts);
1827
1828 SetAllowTcpListen(0, true); // actpass.
1829 SetAllowTcpListen(1, false); // active.
1830
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001831 // We want SetRemoteIceParameters to be called as it normally would.
1832 // Otherwise we won't know what parameters to use for the expected
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001833 // prflx TCP candidates.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001834 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Taylor Brandstetterf7c15a92016-06-22 13:13:55 -07001835
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001836 // Pause candidate so we could verify the candidate properties.
1837 PauseCandidates(0);
1838 PauseCandidates(1);
johan02bd5122016-09-20 00:23:27 -07001839 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001840
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001841 // Verify tcp candidates.
deadbeef14f97f52016-06-22 17:14:15 -07001842 VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
1843 VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);
Guo-wei Shieh310b0932015-11-17 19:15:50 -08001844
1845 // Resume candidates.
1846 ResumeCandidates(0);
1847 ResumeCandidates(1);
1848
honghaize58d73d2016-10-24 16:38:26 -07001849 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1850 ep2_ch1()->receiving() &&
1851 ep2_ch1()->writable(),
1852 kShortTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07001853 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1854 ep2_ch1()->selected_connection() &&
1855 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1856 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001857
Steve Antone9324572017-11-29 10:18:21 -08001858 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001859 DestroyChannels();
1860}
1861
Peter Thatcher73ba7a62015-04-14 09:26:03 -07001862TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001863 AddAddress(0, kPublicAddrs[0]);
1864 AddAddress(1, kPublicAddrs[1]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001865 TestSignalRoleConflict();
1866}
1867
1868// Tests that the ice configs (protocol, tiebreaker and role) can be passed
1869// down to ports.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001870TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
honghaize58d73d2016-10-24 16:38:26 -07001871 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001872 AddAddress(0, kPublicAddrs[0]);
1873 AddAddress(1, kPublicAddrs[1]);
1874
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001875 // Give the first connection the higher tiebreaker so its role won't
1876 // change unless we tell it to.
deadbeef14f97f52016-06-22 17:14:15 -07001877 SetIceRole(0, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001878 SetIceTiebreaker(0, kHighTiebreaker);
deadbeef14f97f52016-06-22 17:14:15 -07001879 SetIceRole(1, ICEROLE_CONTROLLING);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001880 SetIceTiebreaker(1, kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001881
johan02bd5122016-09-20 00:23:27 -07001882 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001883
honghaize58d73d2016-10-24 16:38:26 -07001884 EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001885
deadbeef14f97f52016-06-22 17:14:15 -07001886 const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001887 for (size_t i = 0; i < ports_before.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001888 EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001889 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001890 }
1891
deadbeef14f97f52016-06-22 17:14:15 -07001892 ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001893 ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001894
deadbeef14f97f52016-06-22 17:14:15 -07001895 const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001896 for (size_t i = 0; i < ports_after.size(); ++i) {
deadbeef14f97f52016-06-22 17:14:15 -07001897 EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07001898 // SetIceTiebreaker after ports have been created will fail. So expect the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001899 // original value.
Taylor Brandstetterf3d8d322016-06-29 11:07:36 -07001900 EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001901 }
1902
honghaize58d73d2016-10-24 16:38:26 -07001903 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1904 ep2_ch1()->receiving() &&
1905 ep2_ch1()->writable(),
1906 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001907
Honghai Zhang572b0942016-06-23 12:26:57 -07001908 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1909 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001910
Steve Antone9324572017-11-29 10:18:21 -08001911 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001912 DestroyChannels();
1913}
1914
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001915// Verify that we can set DSCP value and retrieve properly from P2PTC.
1916TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
1917 AddAddress(0, kPublicAddrs[0]);
1918 AddAddress(1, kPublicAddrs[1]);
1919
johan02bd5122016-09-20 00:23:27 -07001920 CreateChannels();
Yves Gerey665174f2018-06-19 15:03:05 +02001921 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1922 EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1923 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1924 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
1925 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1926 EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
1927 GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1928 GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
1929 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
1930 EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001931}
1932
1933// Verify IPv6 connection is preferred over IPv4.
guoweis@webrtc.org1f05c452014-12-15 21:25:54 +00001934TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
honghaize58d73d2016-10-24 16:38:26 -07001935 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001936 AddAddress(0, kIPv6PublicAddrs[0]);
1937 AddAddress(0, kPublicAddrs[0]);
1938 AddAddress(1, kIPv6PublicAddrs[1]);
1939 AddAddress(1, kPublicAddrs[1]);
1940
1941 SetAllocationStepDelay(0, kMinimumStepDelay);
1942 SetAllocationStepDelay(1, kMinimumStepDelay);
1943
1944 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08001945 SetAllocatorFlags(
1946 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1947 SetAllocatorFlags(
1948 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001949
johan02bd5122016-09-20 00:23:27 -07001950 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001951
honghaize58d73d2016-10-24 16:38:26 -07001952 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1953 ep2_ch1()->receiving() &&
1954 ep2_ch1()->writable(),
1955 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001956 EXPECT_TRUE(
Honghai Zhang572b0942016-06-23 12:26:57 -07001957 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001958 LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
1959 RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
1960
Steve Antone9324572017-11-29 10:18:21 -08001961 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001962 DestroyChannels();
1963}
1964
1965// Testing forceful TURN connections.
1966TEST_F(P2PTransportChannelTest, TestForceTurn) {
honghaize58d73d2016-10-24 16:38:26 -07001967 rtc::ScopedFakeClock clock;
deadbeefcbecd352015-09-23 11:50:27 -07001968 ConfigureEndpoints(
1969 NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
deadbeef14f97f52016-06-22 17:14:15 -07001970 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
1971 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001972 set_force_relay(true);
1973
1974 SetAllocationStepDelay(0, kMinimumStepDelay);
1975 SetAllocationStepDelay(1, kMinimumStepDelay);
1976
johan02bd5122016-09-20 00:23:27 -07001977 CreateChannels();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001978
honghaize58d73d2016-10-24 16:38:26 -07001979 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1980 ep2_ch1()->receiving() &&
1981 ep2_ch1()->writable(),
1982 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001983
Honghai Zhang572b0942016-06-23 12:26:57 -07001984 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1985 ep2_ch1()->selected_connection());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001986
Qingsi Wang2bd41f92018-03-23 14:28:37 -07001987 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
1988 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
1989 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type());
1990 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001991
Steve Antone9324572017-11-29 10:18:21 -08001992 TestSendRecv(&clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001993 DestroyChannels();
1994}
1995
honghaiz98db68f2015-09-29 07:58:17 -07001996// Test that if continual gathering is set to true, ICE gathering state will
1997// not change to "Complete", and vice versa.
1998TEST_F(P2PTransportChannelTest, TestContinualGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07001999 rtc::ScopedFakeClock clock;
honghaiz98db68f2015-09-29 07:58:17 -07002000 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2001 kDefaultPortAllocatorFlags);
2002 SetAllocationStepDelay(0, kDefaultStepDelay);
2003 SetAllocationStepDelay(1, kDefaultStepDelay);
deadbeefb60a8192016-08-24 15:15:00 -07002004 IceConfig continual_gathering_config =
2005 CreateIceConfig(1000, GATHER_CONTINUALLY);
honghaiz98db68f2015-09-29 07:58:17 -07002006 // By default, ep2 does not gather continually.
deadbeefb60a8192016-08-24 15:15:00 -07002007 IceConfig default_config;
johan02bd5122016-09-20 00:23:27 -07002008 CreateChannels(continual_gathering_config, default_config);
honghaiz98db68f2015-09-29 07:58:17 -07002009
Honghai Zhang161a5862016-10-20 11:47:02 -07002010 EXPECT_TRUE_SIMULATED_WAIT(
2011 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
2012 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2013 ep2_ch1()->writable(),
2014 kMediumTimeout, clock);
2015 SIMULATED_WAIT(
2016 IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
2017 kShortTimeout, clock);
deadbeef14f97f52016-06-22 17:14:15 -07002018 EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
honghaiz98db68f2015-09-29 07:58:17 -07002019 ep1_ch1()->gathering_state());
2020 // By now, ep2 should have completed gathering.
deadbeef14f97f52016-06-22 17:14:15 -07002021 EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
honghaiz98db68f2015-09-29 07:58:17 -07002022 ep2_ch1()->gathering_state());
2023
2024 DestroyChannels();
2025}
2026
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002027// Test that a connection succeeds when the P2PTransportChannel uses a pooled
2028// PortAllocatorSession that has not yet finished gathering candidates.
2029TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002030 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002031 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2032 kDefaultPortAllocatorFlags);
2033 // First create a pooled session for each endpoint.
2034 auto& allocator_1 = GetEndpoint(0)->allocator_;
2035 auto& allocator_2 = GetEndpoint(1)->allocator_;
2036 int pool_size = 1;
2037 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002038 allocator_1->turn_servers(), pool_size,
2039 webrtc::NO_PRUNE);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002040 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002041 allocator_2->turn_servers(), pool_size,
2042 webrtc::NO_PRUNE);
deadbeef14f97f52016-06-22 17:14:15 -07002043 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002044 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07002045 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002046 allocator_2->GetPooledSession();
2047 ASSERT_NE(nullptr, pooled_session_1);
2048 ASSERT_NE(nullptr, pooled_session_2);
2049 // Sanity check that pooled sessions haven't gathered anything yet.
2050 EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
2051 EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
2052 EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
2053 EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
2054 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07002055 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07002056 EXPECT_TRUE_SIMULATED_WAIT(
2057 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
2058 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2059 ep2_ch1()->writable(),
2060 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08002061 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002062 // Make sure the P2PTransportChannels are actually using ports from the
2063 // pooled sessions.
2064 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2065 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
Steve Antonae226f62019-01-29 12:47:38 -08002066 EXPECT_THAT(pooled_ports_1,
2067 Contains(ep1_ch1()->selected_connection()->port()));
2068 EXPECT_THAT(pooled_ports_2,
2069 Contains(ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002070}
2071
2072// Test that a connection succeeds when the P2PTransportChannel uses a pooled
2073// PortAllocatorSession that already finished gathering candidates.
2074TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002075 rtc::ScopedFakeClock clock;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002076 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2077 kDefaultPortAllocatorFlags);
2078 // First create a pooled session for each endpoint.
2079 auto& allocator_1 = GetEndpoint(0)->allocator_;
2080 auto& allocator_2 = GetEndpoint(1)->allocator_;
2081 int pool_size = 1;
2082 allocator_1->SetConfiguration(allocator_1->stun_servers(),
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002083 allocator_1->turn_servers(), pool_size,
2084 webrtc::NO_PRUNE);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002085 allocator_2->SetConfiguration(allocator_2->stun_servers(),
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002086 allocator_2->turn_servers(), pool_size,
2087 webrtc::NO_PRUNE);
deadbeef14f97f52016-06-22 17:14:15 -07002088 const PortAllocatorSession* pooled_session_1 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002089 allocator_1->GetPooledSession();
deadbeef14f97f52016-06-22 17:14:15 -07002090 const PortAllocatorSession* pooled_session_2 =
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002091 allocator_2->GetPooledSession();
2092 ASSERT_NE(nullptr, pooled_session_1);
2093 ASSERT_NE(nullptr, pooled_session_2);
2094 // Wait for the pooled sessions to finish gathering before the
2095 // P2PTransportChannels try to use them.
Honghai Zhang161a5862016-10-20 11:47:02 -07002096 EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
2097 pooled_session_2->CandidatesAllocationDone(),
2098 kDefaultTimeout, clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002099 // Now let the endpoints connect and try exchanging some data.
johan02bd5122016-09-20 00:23:27 -07002100 CreateChannels();
Honghai Zhang161a5862016-10-20 11:47:02 -07002101 EXPECT_TRUE_SIMULATED_WAIT(
2102 ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
2103 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2104 ep2_ch1()->writable(),
2105 kMediumTimeout, clock);
Steve Antone9324572017-11-29 10:18:21 -08002106 TestSendRecv(&clock);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002107 // Make sure the P2PTransportChannels are actually using ports from the
2108 // pooled sessions.
2109 auto pooled_ports_1 = pooled_session_1->ReadyPorts();
2110 auto pooled_ports_2 = pooled_session_2->ReadyPorts();
Steve Antonae226f62019-01-29 12:47:38 -08002111 EXPECT_THAT(pooled_ports_1,
2112 Contains(ep1_ch1()->selected_connection()->port()));
2113 EXPECT_THAT(pooled_ports_2,
2114 Contains(ep2_ch1()->selected_connection()->port()));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002115}
2116
deadbeef14f97f52016-06-22 17:14:15 -07002117// Test that when the "presume_writable_when_fully_relayed" flag is set to
Taylor Brandstetteref184702016-06-23 17:35:47 -07002118// true and there's a TURN-TURN candidate pair, it's presumed to be writable
deadbeef14f97f52016-06-22 17:14:15 -07002119// as soon as it's created.
deadbeefdd7fb432016-09-30 15:16:48 -07002120// TODO(deadbeef): Move this and other "presumed writable" tests into a test
2121// class that operates on a single P2PTransportChannel, once an appropriate one
2122// (which supports TURN servers and TURN candidate gathering) is available.
deadbeef14f97f52016-06-22 17:14:15 -07002123TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
2124 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2125 kDefaultPortAllocatorFlags);
2126 // Only configure one channel so we can control when the remote candidate
2127 // is added.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002128 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2129 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
deadbeef14f97f52016-06-22 17:14:15 -07002130 IceConfig config;
2131 config.presume_writable_when_fully_relayed = true;
2132 ep1_ch1()->SetIceConfig(config);
2133 ep1_ch1()->MaybeStartGathering();
2134 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2135 ep1_ch1()->gathering_state(), kDefaultTimeout);
2136 // Add two remote candidates; a host candidate (with higher priority)
2137 // and TURN candidate.
2138 ep1_ch1()->AddRemoteCandidate(
2139 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
2140 ep1_ch1()->AddRemoteCandidate(
2141 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2142 // Expect that the TURN-TURN candidate pair will be prioritized since it's
2143 // "probably writable".
Jonas Oreland1230fb72019-10-25 15:58:14 +02002144 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07002145 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2146 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2147 // Also expect that the channel instantly indicates that it's writable since
2148 // it has a TURN-TURN pair.
2149 EXPECT_TRUE(ep1_ch1()->writable());
2150 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002151 // Also make sure we can immediately send packets.
2152 const char* data = "test";
2153 int len = static_cast<int>(strlen(data));
2154 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
deadbeef14f97f52016-06-22 17:14:15 -07002155}
2156
Taylor Brandstetteref184702016-06-23 17:35:47 -07002157// Test that a TURN/peer reflexive candidate pair is also presumed writable.
2158TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
2159 rtc::ScopedFakeClock fake_clock;
2160
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07002161 // We need to add artificial network delay to verify that the connection
2162 // is presumed writable before it's actually writable. Without this delay
2163 // it would become writable instantly.
2164 virtual_socket_server()->set_delay_mean(50);
2165 virtual_socket_server()->UpdateDelayDistribution();
2166
Taylor Brandstetteref184702016-06-23 17:35:47 -07002167 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2168 kDefaultPortAllocatorFlags);
2169 // We want the remote TURN candidate to show up as prflx. To do this we need
2170 // to configure the server to accept packets from an address we haven't
2171 // explicitly installed permission for.
2172 test_turn_server()->set_enable_permission_checks(false);
2173 IceConfig config;
2174 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002175 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2176 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2177 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2178 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
Taylor Brandstetteref184702016-06-23 17:35:47 -07002179 ep1_ch1()->SetIceConfig(config);
2180 ep2_ch1()->SetIceConfig(config);
2181 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2182 // candidate as peer reflexive.
2183 PauseCandidates(1);
2184 ep1_ch1()->MaybeStartGathering();
2185 ep2_ch1()->MaybeStartGathering();
2186
2187 // Wait for the TURN<->prflx connection.
2188 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002189 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002190 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2191 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2192 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2193 // Make sure that at this point the connection is only presumed writable,
2194 // not fully writable.
2195 EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());
2196
2197 // Now wait for it to actually become writable.
Honghai Zhang161a5862016-10-20 11:47:02 -07002198 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
2199 kShortTimeout, fake_clock);
Taylor Brandstetteref184702016-06-23 17:35:47 -07002200
2201 // Explitly destroy channels, before fake clock is destroyed.
2202 DestroyChannels();
2203}
2204
deadbeef14f97f52016-06-22 17:14:15 -07002205// Test that a presumed-writable TURN<->TURN connection is preferred above an
2206// unreliable connection (one that has failed to be pinged for some time).
2207TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
2208 rtc::ScopedFakeClock fake_clock;
2209
2210 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
2211 kDefaultPortAllocatorFlags);
2212 IceConfig config;
2213 config.presume_writable_when_fully_relayed = true;
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002214 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2215 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2216 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2217 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
deadbeef14f97f52016-06-22 17:14:15 -07002218 ep1_ch1()->SetIceConfig(config);
2219 ep2_ch1()->SetIceConfig(config);
2220 ep1_ch1()->MaybeStartGathering();
2221 ep2_ch1()->MaybeStartGathering();
2222 // Wait for initial connection as usual.
Honghai Zhang572b0942016-06-23 12:26:57 -07002223 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2224 ep1_ch1()->selected_connection()->writable() &&
2225 ep2_ch1()->receiving() &&
2226 ep2_ch1()->writable() &&
2227 ep2_ch1()->selected_connection()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002228 kShortTimeout, fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002229 const Connection* old_selected_connection = ep1_ch1()->selected_connection();
deadbeef14f97f52016-06-22 17:14:15 -07002230 // Destroy the second channel and wait for the current connection on the
2231 // first channel to become "unreliable", making it no longer writable.
2232 GetEndpoint(1)->cd1_.ch_.reset();
Honghai Zhang161a5862016-10-20 11:47:02 -07002233 EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
2234 fake_clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002235 EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002236 // Add a remote TURN candidate. The first channel should still have a TURN
2237 // port available to make a TURN<->TURN pair that's presumed writable.
2238 ep1_ch1()->AddRemoteCandidate(
2239 CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
2240 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2241 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2242 EXPECT_TRUE(ep1_ch1()->writable());
2243 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
Honghai Zhang572b0942016-06-23 12:26:57 -07002244 EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
deadbeef14f97f52016-06-22 17:14:15 -07002245 // Explitly destroy channels, before fake clock is destroyed.
2246 DestroyChannels();
2247}
2248
deadbeefdd7fb432016-09-30 15:16:48 -07002249// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
2250// writable" connection. Previously this did not work.
2251TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
2252 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
2253 kDefaultPortAllocatorFlags);
2254 // Only test one endpoint, so we can ensure the connection doesn't receive a
2255 // binding response and advance beyond being "presumed" writable.
2256 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2257 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2258 IceConfig config;
2259 config.presume_writable_when_fully_relayed = true;
2260 ep1_ch1()->SetIceConfig(config);
2261 ep1_ch1()->MaybeStartGathering();
2262 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
2263 ep1_ch1()->gathering_state(), kDefaultTimeout);
2264 ep1_ch1()->AddRemoteCandidate(
2265 CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
2266 // Sanity checking the type of the connection.
Jonas Oreland1230fb72019-10-25 15:58:14 +02002267 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout);
deadbeefdd7fb432016-09-30 15:16:48 -07002268 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2269 EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2270
2271 // Tell the socket server to block packets (returning EWOULDBLOCK).
2272 virtual_socket_server()->SetSendingBlocked(true);
2273 const char* data = "test";
2274 int len = static_cast<int>(strlen(data));
2275 EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
2276
2277 // Reset |ready_to_send_| flag, which is set to true if the event fires as it
2278 // should.
2279 GetEndpoint(0)->ready_to_send_ = false;
2280 virtual_socket_server()->SetSendingBlocked(false);
2281 EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
2282 EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
2283}
2284
Qingsi Wang2bd41f92018-03-23 14:28:37 -07002285// Test that role conflict error responses are sent as expected when receiving a
2286// ping from an unknown address over a TURN connection. Regression test for
2287// crbug.com/webrtc/9034.
2288TEST_F(P2PTransportChannelTest,
2289 TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict) {
2290 rtc::ScopedFakeClock clock;
2291 // Gather only relay candidates.
2292 ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC,
2293 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2294 PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP,
2295 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
2296 PORTALLOCATOR_DISABLE_STUN |
2297 PORTALLOCATOR_DISABLE_TCP);
2298 // With conflicting ICE roles, endpoint 1 has the higher tie breaker and will
2299 // send a binding error response.
2300 SetIceRole(0, ICEROLE_CONTROLLING);
2301 SetIceTiebreaker(0, kHighTiebreaker);
2302 SetIceRole(1, ICEROLE_CONTROLLING);
2303 SetIceTiebreaker(1, kLowTiebreaker);
2304 // We want the remote TURN candidate to show up as prflx. To do this we need
2305 // to configure the server to accept packets from an address we haven't
2306 // explicitly installed permission for.
2307 test_turn_server()->set_enable_permission_checks(false);
2308 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
2309 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
2310 GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
2311 1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
2312 // Don't signal candidates from channel 2, so that channel 1 sees the TURN
2313 // candidate as peer reflexive.
2314 PauseCandidates(1);
2315 ep1_ch1()->MaybeStartGathering();
2316 ep2_ch1()->MaybeStartGathering();
2317
2318 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
2319 kMediumTimeout, clock);
2320
2321 ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
2322
2323 EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
2324 EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
2325
2326 DestroyChannels();
2327}
2328
Qingsi Wang0894f0f2019-06-18 14:11:36 -07002329// Test that the writability can be established with the piggyback
2330// acknowledgement in the connectivity check from the remote peer.
2331TEST_F(P2PTransportChannelTest,
2332 CanConnectWithPiggybackCheckAcknowledgementWhenCheckResponseBlocked) {
2333 webrtc::test::ScopedFieldTrials field_trials(
Qingsi Wange3cc4892019-06-19 14:50:44 -07002334 "WebRTC-PiggybackIceCheckAcknowledgement/Enabled/");
Qingsi Wang0894f0f2019-06-18 14:11:36 -07002335 rtc::ScopedFakeClock clock;
2336 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
2337 IceConfig ep1_config;
2338 IceConfig ep2_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2339 // Let ep2 be tolerable of the loss of connectivity checks, so that it keeps
2340 // sending pings even after ep1 becomes unwritable as we configure the
2341 // firewall below.
2342 ep2_config.receiving_timeout = 30 * 1000;
2343 ep2_config.ice_unwritable_timeout = 30 * 1000;
2344 ep2_config.ice_unwritable_min_checks = 30;
2345 ep2_config.ice_inactive_timeout = 60 * 1000;
2346
2347 CreateChannels(ep1_config, ep2_config);
2348
2349 // Wait until both sides become writable for the first time.
2350 EXPECT_TRUE_SIMULATED_WAIT(
2351 ep1_ch1() != nullptr && ep2_ch1() != nullptr && ep1_ch1()->receiving() &&
2352 ep1_ch1()->writable() && ep2_ch1()->receiving() &&
2353 ep2_ch1()->writable(),
2354 kDefaultTimeout, clock);
2355 // Block the ingress traffic to ep1 so that there is no check response from
2356 // ep2.
2357 ASSERT_NE(nullptr, LocalCandidate(ep1_ch1()));
2358 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_IN,
2359 LocalCandidate(ep1_ch1())->address());
2360 // Wait until ep1 becomes unwritable. At the same time ep2 should be still
2361 // fine so that it will keep sending pings.
2362 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && !ep1_ch1()->writable(),
2363 kDefaultTimeout, clock);
2364 EXPECT_TRUE(ep2_ch1() != nullptr && ep2_ch1()->writable());
2365 // Now let the pings from ep2 to flow but block any pings from ep1, so that
2366 // ep1 can only become writable again after receiving an incoming ping from
2367 // ep2 with piggyback acknowledgement of its previously sent pings. Note
2368 // though that ep1 should have stopped sending pings after becoming unwritable
2369 // in the current design.
2370 fw()->ClearRules();
2371 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_OUT,
2372 LocalCandidate(ep1_ch1())->address());
2373 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1() != nullptr && ep1_ch1()->writable(),
2374 kDefaultTimeout, clock);
2375 DestroyChannels();
2376}
2377
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002378// Test what happens when we have 2 users behind the same NAT. This can lead
2379// to interesting behavior because the STUN server will only give out the
2380// address of the outermost NAT.
2381class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
2382 protected:
2383 void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
kwibergee89e782017-08-09 17:22:01 -07002384 RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
2385 RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
Yves Gerey665174f2018-06-19 15:03:05 +02002386 rtc::NATSocketServer::Translator* outer_nat = nat()->AddTranslator(
2387 kPublicAddrs[0], kNatAddrs[0],
2388 static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002389 ConfigureEndpoint(outer_nat, 0, config1);
2390 ConfigureEndpoint(outer_nat, 1, config2);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002391 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002392 }
2393 void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
Yves Gerey665174f2018-06-19 15:03:05 +02002394 int endpoint,
2395 Config config) {
nissec8ee8822017-01-18 07:20:55 -08002396 RTC_CHECK(config <= NAT_SYMMETRIC);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002397 if (config == OPEN) {
2398 AddAddress(endpoint, kPrivateAddrs[endpoint]);
2399 nat->AddClient(kPrivateAddrs[endpoint]);
2400 } else {
2401 AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
2402 nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
Yves Gerey665174f2018-06-19 15:03:05 +02002403 static_cast<rtc::NATType>(config - NAT_FULL_CONE))
2404 ->AddClient(kCascadedPrivateAddrs[endpoint]);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002405 }
2406 }
2407};
2408
2409TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
2410 ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
Taylor Brandstetter62351c92016-08-11 16:05:07 -07002411 Test(
2412 P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002413}
2414
2415// Test what happens when we have multiple available pathways.
2416// In the future we will try different RTTs and configs for the different
2417// interfaces, so that we can simulate a user with Ethernet and VPN networks.
2418class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002419 public:
honghaiz7252a002016-11-08 20:04:09 -08002420 const Connection* GetConnectionWithRemoteAddress(
2421 P2PTransportChannel* channel,
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002422 const SocketAddress& address) {
honghaiz7252a002016-11-08 20:04:09 -08002423 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002424 if (conn->remote_candidate().address().EqualIPs(address)) {
2425 return conn;
2426 }
2427 }
2428 return nullptr;
2429 }
2430
honghaiz7252a002016-11-08 20:04:09 -08002431 Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
2432 const SocketAddress& address) {
2433 for (Connection* conn : channel->connections()) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002434 if (conn->local_candidate().address().EqualIPs(address)) {
2435 return conn;
2436 }
2437 }
2438 return nullptr;
2439 }
2440
honghaiz7252a002016-11-08 20:04:09 -08002441 Connection* GetConnection(P2PTransportChannel* channel,
2442 const SocketAddress& local,
2443 const SocketAddress& remote) {
2444 for (Connection* conn : channel->connections()) {
2445 if (conn->local_candidate().address().EqualIPs(local) &&
2446 conn->remote_candidate().address().EqualIPs(remote)) {
2447 return conn;
2448 }
2449 }
2450 return nullptr;
2451 }
2452
2453 void DestroyAllButBestConnection(P2PTransportChannel* channel) {
2454 const Connection* selected_connection = channel->selected_connection();
2455 for (Connection* conn : channel->connections()) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002456 if (conn != selected_connection) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002457 conn->Destroy();
2458 }
2459 }
2460 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002461};
2462
2463// Test that we can establish connectivity when both peers are multihomed.
zhihuanga3095d02016-11-10 13:59:46 -08002464TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002465 AddAddress(0, kPublicAddrs[0]);
2466 AddAddress(0, kAlternateAddrs[0]);
2467 AddAddress(1, kPublicAddrs[1]);
2468 AddAddress(1, kAlternateAddrs[1]);
2469 Test(kLocalUdpToLocalUdp);
2470}
2471
Honghai Zhang52dce732016-03-31 12:37:31 -07002472// Test that we can quickly switch links if an interface goes down.
2473// The controlled side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002474TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002475 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002476 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002477 // Simulate failing over from Wi-Fi to cell interface.
2478 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2479 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002480
2481 // Use only local ports for simplicity.
2482 SetAllocatorFlags(0, kOnlyLocalPorts);
2483 SetAllocatorFlags(1, kOnlyLocalPorts);
2484
deadbeefb60a8192016-08-24 15:15:00 -07002485 // Make the receiving timeout shorter for testing.
2486 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002487 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002488 CreateChannels(config, config);
honghaiza58ea782015-09-24 08:13:36 -07002489
honghaiz9ad0db52016-07-14 19:30:28 -07002490 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2491 ep2_ch1()->receiving() &&
2492 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002493 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002494 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2495 ep2_ch1()->selected_connection() &&
2496 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2497 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002498
2499 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002500 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002501 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
honghaiz9ad0db52016-07-14 19:30:28 -07002502 // The selected connections may switch, so keep references to them.
Honghai Zhang572b0942016-06-23 12:26:57 -07002503 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2504 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002505 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002506 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002507 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002508 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002509
honghaiz9ad0db52016-07-14 19:30:28 -07002510 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002511 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002512 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2513 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002514 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002515 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2516 EXPECT_TRUE(
2517 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2518 EXPECT_TRUE(
2519 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
2520
2521 DestroyChannels();
2522}
2523
Honghai Zhang52dce732016-03-31 12:37:31 -07002524// Test that we can quickly switch links if an interface goes down.
2525// The controlling side has two interfaces and one will die.
honghaiza58ea782015-09-24 08:13:36 -07002526TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
honghaiz9ad0db52016-07-14 19:30:28 -07002527 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002528 // Simulate failing over from Wi-Fi to cell interface.
2529 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2530 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiza58ea782015-09-24 08:13:36 -07002531 AddAddress(1, kPublicAddrs[1]);
2532
2533 // Use only local ports for simplicity.
2534 SetAllocatorFlags(0, kOnlyLocalPorts);
2535 SetAllocatorFlags(1, kOnlyLocalPorts);
2536
deadbeefb60a8192016-08-24 15:15:00 -07002537 // Make the receiving timeout shorter for testing.
2538 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
honghaiza58ea782015-09-24 08:13:36 -07002539 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002540 CreateChannels(config, config);
honghaiz9ad0db52016-07-14 19:30:28 -07002541 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2542 ep2_ch1()->receiving() &&
2543 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002544 kMediumTimeout, clock);
Honghai Zhang572b0942016-06-23 12:26:57 -07002545 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2546 ep2_ch1()->selected_connection() &&
2547 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2548 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
honghaiza58ea782015-09-24 08:13:36 -07002549
2550 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002551 RTC_LOG(LS_INFO) << "Failing over...";
honghaiza58ea782015-09-24 08:13:36 -07002552 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
Honghai Zhang572b0942016-06-23 12:26:57 -07002553 // The selected connections will switch, so keep references to them.
2554 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2555 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
honghaiza58ea782015-09-24 08:13:36 -07002556 // We should detect loss of receiving within 1 second or so.
honghaiz9ad0db52016-07-14 19:30:28 -07002557 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07002558 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002559 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002560
honghaiz9ad0db52016-07-14 19:30:28 -07002561 // We should switch over to use the alternate addr on both sides
honghaiza58ea782015-09-24 08:13:36 -07002562 // when we are not receiving.
honghaiz9ad0db52016-07-14 19:30:28 -07002563 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2564 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002565 kMediumTimeout, clock);
honghaiza58ea782015-09-24 08:13:36 -07002566 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02002567 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
honghaiza58ea782015-09-24 08:13:36 -07002568 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2569 EXPECT_TRUE(
2570 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002571
2572 DestroyChannels();
2573}
2574
honghaiz7252a002016-11-08 20:04:09 -08002575// Tests that we can quickly switch links if an interface goes down when
2576// there are many connections.
2577TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
2578 rtc::ScopedFakeClock clock;
2579 test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
Niels Möller191e38f2019-11-04 08:49:12 +01002580 RelayServerConfig turn_server;
honghaiz7252a002016-11-08 20:04:09 -08002581 turn_server.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08002582 turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
honghaiz7252a002016-11-08 20:04:09 -08002583 GetAllocator(0)->AddTurnServer(turn_server);
2584 GetAllocator(1)->AddTurnServer(turn_server);
2585 // Enable IPv6
zhihuangb09b3f92017-03-07 14:40:51 -08002586 SetAllocatorFlags(
2587 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2588 SetAllocatorFlags(
2589 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08002590 SetAllocationStepDelay(0, kMinimumStepDelay);
2591 SetAllocationStepDelay(1, kMinimumStepDelay);
2592
2593 auto& wifi = kPublicAddrs;
2594 auto& cellular = kAlternateAddrs;
2595 auto& wifiIpv6 = kIPv6PublicAddrs;
2596 auto& cellularIpv6 = kIPv6AlternateAddrs;
2597 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2598 AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2599 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2600 AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2601 AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2602 AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
2603 AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2604 AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
2605
2606 // Set smaller delay on the TCP TURN server so that TCP TURN candidates
2607 // will be created in time.
2608 virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
2609 virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
2610 virtual_socket_server()->set_delay_mean(500);
2611 virtual_socket_server()->UpdateDelayDistribution();
2612
2613 // Make the receiving timeout shorter for testing.
2614 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
2615 // Create channels and let them go writable, as usual.
2616 CreateChannels(config, config, true /* ice_renomination */);
2617 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2618 ep2_ch1()->receiving() &&
2619 ep2_ch1()->writable(),
2620 kMediumTimeout, clock);
2621 EXPECT_TRUE_SIMULATED_WAIT(
2622 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
2623 LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
2624 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
2625 kMediumTimeout, clock);
2626
2627 // Blackhole any traffic to or from the wifi on endpoint 1.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002628 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz7252a002016-11-08 20:04:09 -08002629 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
2630 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);
2631
2632 // The selected connections may switch, so keep references to them.
2633 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2634 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2635 EXPECT_TRUE_SIMULATED_WAIT(
2636 !selected_connection1->receiving() && !selected_connection2->receiving(),
2637 kMediumTimeout, clock);
2638
2639 // Per-network best connections will be pinged at relatively higher rate when
2640 // the selected connection becomes not receiving.
2641 Connection* per_network_best_connection1 =
2642 GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
2643 ASSERT_NE(nullptr, per_network_best_connection1);
2644 int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
2645 int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
2646 EXPECT_TRUE_SIMULATED_WAIT(
2647 num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
2648 kMediumTimeout, clock);
2649 int64_t ping_interval1 =
2650 (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
2651 (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
2652 constexpr int SCHEDULING_DELAY = 200;
2653 EXPECT_LT(
2654 ping_interval1,
2655 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);
2656
2657 // It should switch over to use the cellular IPv6 addr on endpoint 1 before
2658 // it timed out on writing.
2659 EXPECT_TRUE_SIMULATED_WAIT(
2660 ep1_ch1()->selected_connection()->receiving() &&
2661 ep2_ch1()->selected_connection()->receiving() &&
2662 RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
2663 LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
2664 kMediumTimeout, clock);
2665
2666 DestroyChannels();
2667}
2668
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002669// Test that when the controlling side switches the selected connection,
2670// the nomination of the selected connection on the controlled side will
2671// increase.
2672TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
2673 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002674 // Simulate failing over from Wi-Fi to cell interface.
2675 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2676 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002677 AddAddress(1, kPublicAddrs[1]);
2678
2679 // Use only local ports for simplicity.
2680 SetAllocatorFlags(0, kOnlyLocalPorts);
2681 SetAllocatorFlags(1, kOnlyLocalPorts);
2682
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002683 // We want it to set the remote ICE parameters when creating channels.
2684 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
deadbeefb60a8192016-08-24 15:15:00 -07002685 // Make the receiving timeout shorter for testing.
2686 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07002687 // Create channels with ICE renomination and let them go writable as usual.
johan02bd5122016-09-20 00:23:27 -07002688 CreateChannels(config, config, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002689 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2690 ep2_ch1()->receiving() &&
2691 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002692 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002693 EXPECT_TRUE_SIMULATED_WAIT(
2694 ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
2695 ep1_ch1()->selected_connection()->acked_nomination() > 0,
2696 kDefaultTimeout, clock);
2697 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2698 Connection* selected_connection2 =
2699 const_cast<Connection*>(ep2_ch1()->selected_connection());
2700 uint32_t remote_nomination2 = selected_connection2->remote_nomination();
2701 // |selected_connection2| should not be nominated any more since the previous
2702 // nomination has been acknowledged.
2703 ConnectSignalNominated(selected_connection2);
Honghai Zhang161a5862016-10-20 11:47:02 -07002704 SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002705 EXPECT_FALSE(nominated());
2706
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002707 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002708 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002709 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2710
2711 // The selected connection on the controlling side should switch.
2712 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002713 ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
2714 clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07002715 // The connection on the controlled side should be nominated again
2716 // and have an increased nomination.
2717 EXPECT_TRUE_SIMULATED_WAIT(
2718 ep2_ch1()->selected_connection()->remote_nomination() >
2719 remote_nomination2,
2720 kDefaultTimeout, clock);
2721
2722 DestroyChannels();
2723}
2724
honghaiz9ad0db52016-07-14 19:30:28 -07002725// Test that if an interface fails temporarily and then recovers quickly,
2726// the selected connection will not switch.
2727// The case that it will switch over to the backup connection if the selected
2728// connection does not recover after enough time is covered in
2729// TestFailoverControlledSide and TestFailoverControllingSide.
2730TEST_F(P2PTransportChannelMultihomedTest,
2731 TestConnectionSwitchDampeningControlledSide) {
2732 rtc::ScopedFakeClock clock;
2733 AddAddress(0, kPublicAddrs[0]);
deadbeef3427f532017-07-26 16:09:33 -07002734 // Simulate failing over from Wi-Fi to cell interface.
2735 AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
2736 AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002737
2738 // Use only local ports for simplicity.
2739 SetAllocatorFlags(0, kOnlyLocalPorts);
2740 SetAllocatorFlags(1, kOnlyLocalPorts);
2741
2742 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002743 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002744
2745 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2746 ep2_ch1()->receiving() &&
2747 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002748 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002749 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2750 ep2_ch1()->selected_connection() &&
2751 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2752 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2753
2754 // Make the receiving timeout shorter for testing.
2755 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2756 ep1_ch1()->SetIceConfig(config);
2757 ep2_ch1()->SetIceConfig(config);
2758 reset_selected_candidate_pair_switches();
2759
2760 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002761 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002762 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2763
2764 // The selected connections may switch, so keep references to them.
2765 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2766 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2767 // We should detect loss of receiving within 1 second or so.
2768 EXPECT_TRUE_SIMULATED_WAIT(
2769 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002770 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002771 // After a short while, the link recovers itself.
2772 SIMULATED_WAIT(false, 10, clock);
2773 fw()->ClearRules();
2774
2775 // We should remain on the public address on both sides and no connection
2776 // switches should have happened.
2777 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2778 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002779 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002780 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2781 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2782 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2783
2784 DestroyChannels();
2785}
2786
2787// Test that if an interface fails temporarily and then recovers quickly,
2788// the selected connection will not switch.
2789TEST_F(P2PTransportChannelMultihomedTest,
2790 TestConnectionSwitchDampeningControllingSide) {
2791 rtc::ScopedFakeClock clock;
deadbeef3427f532017-07-26 16:09:33 -07002792 // Simulate failing over from Wi-Fi to cell interface.
2793 AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
2794 AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
honghaiz9ad0db52016-07-14 19:30:28 -07002795 AddAddress(1, kPublicAddrs[1]);
2796
2797 // Use only local ports for simplicity.
2798 SetAllocatorFlags(0, kOnlyLocalPorts);
2799 SetAllocatorFlags(1, kOnlyLocalPorts);
2800
2801 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002802 CreateChannels();
honghaiz9ad0db52016-07-14 19:30:28 -07002803 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2804 ep2_ch1()->receiving() &&
2805 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002806 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002807 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2808 ep2_ch1()->selected_connection() &&
2809 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2810 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2811
2812 // Make the receiving timeout shorter for testing.
2813 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2814 ep1_ch1()->SetIceConfig(config);
2815 ep2_ch1()->SetIceConfig(config);
2816 reset_selected_candidate_pair_switches();
2817
2818 // Blackhole any traffic to or from the public addrs.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002819 RTC_LOG(LS_INFO) << "Failing over...";
honghaiz9ad0db52016-07-14 19:30:28 -07002820 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2821 // The selected connections may switch, so keep references to them.
2822 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2823 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2824 // We should detect loss of receiving within 1 second or so.
2825 EXPECT_TRUE_SIMULATED_WAIT(
2826 !selected_connection1->receiving() && !selected_connection2->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002827 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002828 // The link recovers after a short while.
2829 SIMULATED_WAIT(false, 10, clock);
2830 fw()->ClearRules();
2831
2832 // We should not switch to the alternate addr on both sides because of the
2833 // dampening.
2834 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2835 ep2_ch1()->selected_connection()->receiving(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002836 kMediumTimeout, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07002837 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2838 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2839 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2840 DestroyChannels();
2841}
2842
Honghai Zhangfd16da22016-08-17 16:12:46 -07002843// Tests that if the remote side's network failed, it won't cause the local
2844// side to switch connections and networks.
2845TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
2846 rtc::ScopedFakeClock clock;
2847 // The interface names are chosen so that |cellular| would have higher
2848 // candidate priority and higher cost.
2849 auto& wifi = kPublicAddrs;
2850 auto& cellular = kAlternateAddrs;
2851 AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2852 AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
2853 AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);
2854
2855 // Use only local ports for simplicity.
2856 SetAllocatorFlags(0, kOnlyLocalPorts);
2857 SetAllocatorFlags(1, kOnlyLocalPorts);
2858 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002859 CreateChannels();
Honghai Zhangfd16da22016-08-17 16:12:46 -07002860 // Make the receiving timeout shorter for testing.
2861 // Set the backup connection ping interval to 25s.
2862 IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
2863 // Ping the best connection more frequently since we don't have traffic.
2864 config.stable_writable_connection_ping_interval = 900;
2865 ep1_ch1()->SetIceConfig(config);
2866 ep2_ch1()->SetIceConfig(config);
2867 // Need to wait to make sure the connections on both networks are writable.
2868 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2869 ep2_ch1()->receiving() &&
2870 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002871 kMediumTimeout, clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002872 EXPECT_TRUE_SIMULATED_WAIT(
2873 ep1_ch1()->selected_connection() &&
2874 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2875 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2876 kDefaultTimeout, clock);
2877 Connection* backup_conn =
2878 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
2879 ASSERT_NE(nullptr, backup_conn);
2880 // After a short while, the backup connection will be writable but not
2881 // receiving because backup connection is pinged at a slower rate.
2882 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002883 backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
2884 clock);
Honghai Zhangfd16da22016-08-17 16:12:46 -07002885 reset_selected_candidate_pair_switches();
2886 // Blackhole any traffic to or from the remote WiFi networks.
Mirko Bonadei675513b2017-11-09 11:09:25 +01002887 RTC_LOG(LS_INFO) << "Failing over...";
Honghai Zhangfd16da22016-08-17 16:12:46 -07002888 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);
2889
2890 int num_switches = 0;
2891 SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
2892 20000, clock);
2893 EXPECT_EQ(0, num_switches);
2894 DestroyChannels();
2895}
2896
honghaize1a0c942016-02-16 14:54:56 -08002897// Tests that a Wifi-Wifi connection has the highest precedence.
2898TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
2899 // The interface names are chosen so that |cellular| would have higher
2900 // candidate priority if it is not for the network type.
2901 auto& wifi = kAlternateAddrs;
2902 auto& cellular = kPublicAddrs;
2903 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
2904 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2905 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2906 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2907
2908 // Use only local ports for simplicity.
2909 SetAllocatorFlags(0, kOnlyLocalPorts);
2910 SetAllocatorFlags(1, kOnlyLocalPorts);
2911
2912 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002913 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002914
2915 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2916 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2917 1000, 1000);
2918 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002919 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002920 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
2921 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2922 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002923 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002924 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
2925 RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
2926 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002927 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002928}
2929
2930// Tests that a Wifi-Cellular connection has higher precedence than
2931// a Cellular-Cellular connection.
2932TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
2933 // The interface names are chosen so that |cellular| would have higher
2934 // candidate priority if it is not for the network type.
2935 auto& wifi = kAlternateAddrs;
2936 auto& cellular = kPublicAddrs;
2937 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2938 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
2939 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
2940
2941 // Use only local ports for simplicity.
2942 SetAllocatorFlags(0, kOnlyLocalPorts);
2943 SetAllocatorFlags(1, kOnlyLocalPorts);
2944
2945 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002946 CreateChannels();
honghaize1a0c942016-02-16 14:54:56 -08002947
2948 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2949 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2950 1000, 1000);
2951 // Need to wait to make sure the connections on both networks are writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07002952 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002953 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
2954 1000);
Honghai Zhang572b0942016-06-23 12:26:57 -07002955 EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
honghaize1a0c942016-02-16 14:54:56 -08002956 LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
2957 1000);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002958 DestroyChannels();
honghaize1a0c942016-02-16 14:54:56 -08002959}
2960
Honghai Zhang381b4212015-12-04 12:24:03 -08002961// Test that the backup connection is pinged at a rate no faster than
2962// what was configured.
2963TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
2964 AddAddress(0, kPublicAddrs[0]);
2965 // Adding alternate address will make sure |kPublicAddrs| has the higher
2966 // priority than others. This is due to FakeNetwork::AddInterface method.
2967 AddAddress(1, kAlternateAddrs[1]);
2968 AddAddress(1, kPublicAddrs[1]);
2969
2970 // Use only local ports for simplicity.
2971 SetAllocatorFlags(0, kOnlyLocalPorts);
2972 SetAllocatorFlags(1, kOnlyLocalPorts);
2973
2974 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07002975 CreateChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08002976 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2977 ep2_ch1()->receiving() && ep2_ch1()->writable(),
2978 1000, 1000);
2979 int backup_ping_interval = 2000;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002980 ep2_ch1()->SetIceConfig(
2981 CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
Honghai Zhang381b4212015-12-04 12:24:03 -08002982 // After the state becomes COMPLETED, the backup connection will be pinged
2983 // once every |backup_ping_interval| milliseconds.
zhihuangd06adf62017-01-12 15:58:31 -08002984 ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
2985 1000);
deadbeef14f97f52016-06-22 17:14:15 -07002986 const std::vector<Connection*>& connections = ep2_ch1()->connections();
Honghai Zhang381b4212015-12-04 12:24:03 -08002987 ASSERT_EQ(2U, connections.size());
deadbeef14f97f52016-06-22 17:14:15 -07002988 Connection* backup_conn = connections[1];
Honghai Zhang161a5862016-10-20 11:47:02 -07002989 EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
honghaiz34b11eb2016-03-16 08:55:44 -07002990 int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
Honghai Zhang381b4212015-12-04 12:24:03 -08002991 EXPECT_TRUE_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07002992 last_ping_response_ms < backup_conn->last_ping_response_received(),
2993 kDefaultTimeout);
Honghai Zhang381b4212015-12-04 12:24:03 -08002994 int time_elapsed =
2995 backup_conn->last_ping_response_received() - last_ping_response_ms;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002996 RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
Honghai Zhang381b4212015-12-04 12:24:03 -08002997 EXPECT_GE(time_elapsed, backup_ping_interval);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002998
2999 DestroyChannels();
Honghai Zhang381b4212015-12-04 12:24:03 -08003000}
3001
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003002TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003003 rtc::ScopedFakeClock clock;
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003004 AddAddress(0, kAlternateAddrs[0]);
3005 AddAddress(0, kPublicAddrs[0]);
3006 AddAddress(1, kPublicAddrs[1]);
3007 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07003008 CreateChannels();
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003009
3010 // Both transport channels will reach STATE_COMPLETED quickly.
zhihuangd06adf62017-01-12 15:58:31 -08003011 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07003012 ep1_ch1()->GetState(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08003013 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
Honghai Zhang161a5862016-10-20 11:47:02 -07003014 ep2_ch1()->GetState(), kShortTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003015}
3016
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003017// Tests that when a network interface becomes inactive, if Continual Gathering
3018// policy is GATHER_CONTINUALLY, the ports associated with that network
Honghai Zhang7fb69db2016-03-14 11:59:18 -07003019// will be removed from the port list of the channel, and the respective
3020// remote candidates on the other participant will be removed eventually.
honghaize3c6c822016-02-17 13:00:28 -08003021TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003022 rtc::ScopedFakeClock clock;
honghaize3c6c822016-02-17 13:00:28 -08003023 AddAddress(0, kPublicAddrs[0]);
3024 AddAddress(1, kPublicAddrs[1]);
3025 // Create channels and let them go writable, as usual.
deadbeefb60a8192016-08-24 15:15:00 -07003026 IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
3027 IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
johan02bd5122016-09-20 00:23:27 -07003028 CreateChannels(ep1_config, ep2_config);
honghaize3c6c822016-02-17 13:00:28 -08003029
3030 SetAllocatorFlags(0, kOnlyLocalPorts);
3031 SetAllocatorFlags(1, kOnlyLocalPorts);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003032 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3033 ep2_ch1()->receiving() &&
3034 ep2_ch1()->writable(),
3035 kDefaultTimeout, clock);
honghaize3c6c822016-02-17 13:00:28 -08003036 // More than one port has been created.
3037 EXPECT_LE(1U, ep1_ch1()->ports().size());
3038 // Endpoint 1 enabled continual gathering; the port will be removed
3039 // when the interface is removed.
3040 RemoveAddress(0, kPublicAddrs[0]);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07003041 EXPECT_TRUE(ep1_ch1()->ports().empty());
3042 // The remote candidates will be removed eventually.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003043 EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
3044 clock);
honghaize3c6c822016-02-17 13:00:28 -08003045
3046 size_t num_ports = ep2_ch1()->ports().size();
3047 EXPECT_LE(1U, num_ports);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07003048 size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003049 // Endpoint 2 did not enable continual gathering; the local port will still be
3050 // removed when the interface is removed but the remote candidates on the
3051 // other participant will not be removed.
honghaize3c6c822016-02-17 13:00:28 -08003052 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003053
3054 EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
3055 clock);
3056 SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07003057 EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003058
3059 DestroyChannels();
honghaize3c6c822016-02-17 13:00:28 -08003060}
3061
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003062// Tests that continual gathering will create new connections when a new
3063// interface is added.
3064TEST_F(P2PTransportChannelMultihomedTest,
3065 TestContinualGatheringOnNewInterface) {
3066 auto& wifi = kAlternateAddrs;
3067 auto& cellular = kPublicAddrs;
3068 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3069 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003070 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07003071 IceConfig continual_gathering_config =
3072 CreateIceConfig(1000, GATHER_CONTINUALLY);
johan02bd5122016-09-20 00:23:27 -07003073 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003074 SetAllocatorFlags(0, kOnlyLocalPorts);
3075 SetAllocatorFlags(1, kOnlyLocalPorts);
3076 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3077 ep2_ch1()->receiving() && ep2_ch1()->writable(),
3078 kDefaultTimeout, kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003079
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003080 // Add a new wifi interface on end point 2. We should expect a new connection
3081 // to be created and the new one will be the best connection.
3082 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
honghaiz7252a002016-11-08 20:04:09 -08003083 const Connection* conn;
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003084 EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003085 conn->remote_candidate().address().EqualIPs(wifi[1]),
3086 kDefaultTimeout);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003087 EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003088 conn->local_candidate().address().EqualIPs(wifi[1]),
3089 kDefaultTimeout);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003090
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003091 // Add a new cellular interface on end point 1, we should expect a new
3092 // backup connection created using this new interface.
3093 AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003094 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08003095 ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003096 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3097 nullptr &&
3098 conn != ep1_ch1()->selected_connection() && conn->writable(),
3099 kDefaultTimeout);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003100 EXPECT_TRUE_WAIT(
zhihuangd06adf62017-01-12 15:58:31 -08003101 ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003102 (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
3103 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003104 conn != ep2_ch1()->selected_connection() && conn->receiving(),
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003105 kDefaultTimeout);
3106
3107 DestroyChannels();
3108}
3109
3110// Tests that we can switch links via continual gathering.
3111TEST_F(P2PTransportChannelMultihomedTest,
3112 TestSwitchLinksViaContinualGathering) {
3113 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003114 AddAddress(0, kPublicAddrs[0]);
3115 AddAddress(1, kPublicAddrs[1]);
3116 // Use only local ports for simplicity.
3117 SetAllocatorFlags(0, kOnlyLocalPorts);
3118 SetAllocatorFlags(1, kOnlyLocalPorts);
3119
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003120 // Set continual gathering policy.
deadbeefb60a8192016-08-24 15:15:00 -07003121 IceConfig continual_gathering_config =
3122 CreateIceConfig(1000, GATHER_CONTINUALLY);
3123 // Create channels and let them go writable, as usual.
johan02bd5122016-09-20 00:23:27 -07003124 CreateChannels(continual_gathering_config, continual_gathering_config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003125 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3126 ep2_ch1()->receiving() &&
3127 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003128 kMediumTimeout, clock);
Yves Gerey665174f2018-06-19 15:03:05 +02003129 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3130 ep2_ch1()->selected_connection() &&
3131 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3132 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003133
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003134 // Add the new address first and then remove the other one.
Mirko Bonadei675513b2017-11-09 11:09:25 +01003135 RTC_LOG(LS_INFO) << "Draining...";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003136 AddAddress(1, kAlternateAddrs[1]);
3137 RemoveAddress(1, kPublicAddrs[1]);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003138 // We should switch to use the alternate address after an exchange of pings.
3139 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang572b0942016-06-23 12:26:57 -07003140 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003141 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3142 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
Honghai Zhang161a5862016-10-20 11:47:02 -07003143 kMediumTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003144
3145 // Remove one address first and then add another address.
Mirko Bonadei675513b2017-11-09 11:09:25 +01003146 RTC_LOG(LS_INFO) << "Draining again...";
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003147 RemoveAddress(1, kAlternateAddrs[1]);
3148 AddAddress(1, kAlternateAddrs[0]);
3149 EXPECT_TRUE_SIMULATED_WAIT(
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003150 ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003151 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
3152 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
Honghai Zhang161a5862016-10-20 11:47:02 -07003153 kMediumTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00003154
3155 DestroyChannels();
3156}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003157
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003158// Tests that the backup connection will be restored after it is destroyed.
3159TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
3160 rtc::ScopedFakeClock clock;
3161 auto& wifi = kAlternateAddrs;
3162 auto& cellular = kPublicAddrs;
3163 AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
3164 AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
3165 AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
3166 AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
3167 // Use only local ports for simplicity.
3168 SetAllocatorFlags(0, kOnlyLocalPorts);
3169 SetAllocatorFlags(1, kOnlyLocalPorts);
3170
3171 // Create channels and let them go writable, as usual.
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003172 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01003173 config.regather_on_failed_networks_interval = 2000;
johan02bd5122016-09-20 00:23:27 -07003174 CreateChannels(config, config);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003175 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
3176 ep2_ch1()->receiving() &&
3177 ep2_ch1()->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003178 kMediumTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003179 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
3180 ep2_ch1()->selected_connection() &&
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003181 LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
3182 RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
3183
3184 // Destroy all backup connections.
3185 DestroyAllButBestConnection(ep1_ch1());
3186 // Ensure the backup connection is removed first.
3187 EXPECT_TRUE_SIMULATED_WAIT(
3188 GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
3189 kDefaultTimeout, clock);
honghaiz7252a002016-11-08 20:04:09 -08003190 const Connection* conn;
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003191 EXPECT_TRUE_SIMULATED_WAIT(
3192 (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
3193 nullptr &&
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003194 conn != ep1_ch1()->selected_connection() && conn->writable(),
Honghai Zhang161a5862016-10-20 11:47:02 -07003195 kDefaultTimeout, clock);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003196
3197 DestroyChannels();
3198}
3199
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003200// A collection of tests which tests a single P2PTransportChannel by sending
3201// pings.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02003202class P2PTransportChannelPingTest : public ::testing::Test,
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003203 public sigslot::has_slots<> {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003204 public:
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003205 P2PTransportChannelPingTest()
deadbeef98e186c2017-05-16 18:00:06 -07003206 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003207
3208 protected:
deadbeef14f97f52016-06-22 17:14:15 -07003209 void PrepareChannel(P2PTransportChannel* ch) {
3210 ch->SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003211 ch->SetIceParameters(kIceParams[0]);
3212 ch->SetRemoteIceParameters(kIceParams[1]);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003213 ch->SignalNetworkRouteChanged.connect(
3214 this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
Honghai Zhang82f132c2016-03-30 12:55:14 -07003215 ch->SignalReadyToSend.connect(this,
3216 &P2PTransportChannelPingTest::OnReadyToSend);
Honghai Zhang1590c392016-05-24 13:15:02 -07003217 ch->SignalStateChanged.connect(
3218 this, &P2PTransportChannelPingTest::OnChannelStateChanged);
Alex Drake00c7ecf2019-08-06 10:54:47 -07003219 ch->SignalCandidatePairChanged.connect(
3220 this, &P2PTransportChannelPingTest::OnCandidatePairChanged);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003221 }
3222
Sebastian Janssond624c392019-04-17 10:36:03 +02003223 Connection* WaitForConnectionTo(
3224 P2PTransportChannel* ch,
3225 const std::string& ip,
3226 int port_num,
3227 rtc::ThreadProcessingFakeClock* clock = nullptr) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07003228 if (clock == nullptr) {
Honghai Zhang161a5862016-10-20 11:47:02 -07003229 EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
3230 kMediumTimeout);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003231 } else {
3232 EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003233 kMediumTimeout, *clock);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003234 }
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003235 return GetConnectionTo(ch, ip, port_num);
3236 }
3237
sprang716978d2016-10-11 06:43:28 -07003238 Port* GetPort(P2PTransportChannel* ch) {
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003239 if (ch->ports().empty()) {
3240 return nullptr;
3241 }
deadbeef14f97f52016-06-22 17:14:15 -07003242 return static_cast<Port*>(ch->ports()[0]);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003243 }
3244
Honghai Zhanga74363c2016-07-28 18:06:15 -07003245 Port* GetPrunedPort(P2PTransportChannel* ch) {
3246 if (ch->pruned_ports().empty()) {
3247 return nullptr;
3248 }
3249 return static_cast<Port*>(ch->pruned_ports()[0]);
3250 }
3251
deadbeef14f97f52016-06-22 17:14:15 -07003252 Connection* GetConnectionTo(P2PTransportChannel* ch,
3253 const std::string& ip,
3254 int port_num) {
sprang716978d2016-10-11 06:43:28 -07003255 Port* port = GetPort(ch);
3256 if (!port) {
3257 return nullptr;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003258 }
sprang716978d2016-10-11 06:43:28 -07003259 return port->GetConnection(rtc::SocketAddress(ip, port_num));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003260 }
3261
deadbeef14f97f52016-06-22 17:14:15 -07003262 Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
3263 Connection* conn = ch->FindNextPingableConnection();
guoweis36f01372016-03-02 18:02:40 -08003264 if (conn) {
3265 ch->MarkConnectionPinged(conn);
3266 }
3267 return conn;
3268 }
3269
Steve Antone9324572017-11-29 10:18:21 -08003270 int SendData(IceTransportInternal* channel,
Honghai Zhang52dce732016-03-31 12:37:31 -07003271 const char* data,
3272 size_t len,
3273 int packet_id) {
3274 rtc::PacketOptions options;
3275 options.packet_id = packet_id;
Steve Antone9324572017-11-29 10:18:21 -08003276 return channel->SendPacket(data, len, options, 0);
Honghai Zhang52dce732016-03-31 12:37:31 -07003277 }
3278
Steve Antone9324572017-11-29 10:18:21 -08003279 Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
3280 rtc::ScopedFakeClock* clock,
Honghai Zhang572b0942016-06-23 12:26:57 -07003281 const std::string& ip_addr,
3282 int port,
3283 int priority,
3284 bool writable) {
Steve Antone9324572017-11-29 10:18:21 -08003285 channel->AddRemoteCandidate(
Honghai Zhang572b0942016-06-23 12:26:57 -07003286 CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
3287 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antone9324572017-11-29 10:18:21 -08003288 GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
3289 *clock);
3290 Connection* conn = GetConnectionTo(channel, ip_addr, port);
Honghai Zhang572b0942016-06-23 12:26:57 -07003291
3292 if (conn && writable) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003293 conn->ReceivedPingResponse(LOW_RTT, "id"); // make it writable
Honghai Zhang572b0942016-06-23 12:26:57 -07003294 }
3295 return conn;
3296 }
3297
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003298 void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
3299 conn->set_remote_nomination(remote_nomination);
Honghai Zhang572b0942016-06-23 12:26:57 -07003300 conn->SignalNominated(conn);
3301 }
3302
Danil Chapovalov00c71832018-06-15 15:58:38 +02003303 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -08003304 last_network_route_ = network_route;
3305 if (last_network_route_) {
3306 last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
3307 }
Honghai Zhang572b0942016-06-23 12:26:57 -07003308 ++selected_candidate_pair_switches_;
Honghai Zhang52dce732016-03-31 12:37:31 -07003309 }
3310
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003311 void ReceivePingOnConnection(
3312 Connection* conn,
3313 const std::string& remote_ufrag,
3314 int priority,
3315 uint32_t nomination,
3316 const absl::optional<std::string>& piggyback_ping_id) {
deadbeef14f97f52016-06-22 17:14:15 -07003317 IceMessage msg;
3318 msg.SetType(STUN_BINDING_REQUEST);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003319 msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
deadbeef14f97f52016-06-22 17:14:15 -07003320 STUN_ATTR_USERNAME,
honghaiz36f50e82016-06-01 15:57:03 -07003321 conn->local_candidate().username() + ":" + remote_ufrag));
zsteinf42cc9d2017-03-27 16:17:19 -07003322 msg.AddAttribute(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003323 std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003324 if (nomination != 0) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003325 msg.AddAttribute(std::make_unique<StunUInt32Attribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003326 STUN_ATTR_NOMINATION, nomination));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003327 }
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003328 if (piggyback_ping_id) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003329 msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003330 STUN_ATTR_LAST_ICE_CHECK_RECEIVED, piggyback_ping_id.value()));
3331 }
deadbeef14f97f52016-06-22 17:14:15 -07003332 msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
honghaiz36f50e82016-06-01 15:57:03 -07003333 msg.AddMessageIntegrity(conn->local_candidate().password());
3334 msg.AddFingerprint();
3335 rtc::ByteBufferWriter buf;
3336 msg.Write(&buf);
Niels Möller15ca5a92018-11-01 14:32:47 +01003337 conn->OnReadPacket(buf.Data(), buf.Length(), rtc::TimeMicros());
honghaiz36f50e82016-06-01 15:57:03 -07003338 }
3339
Qingsi Wang0894f0f2019-06-18 14:11:36 -07003340 void ReceivePingOnConnection(Connection* conn,
3341 const std::string& remote_ufrag,
3342 int priority,
3343 uint32_t nomination = 0) {
3344 ReceivePingOnConnection(conn, remote_ufrag, priority, nomination,
3345 absl::nullopt);
3346 }
3347
deadbeef5bd5ca32017-02-10 11:31:50 -08003348 void OnReadyToSend(rtc::PacketTransportInternal* transport) {
Honghai Zhang82f132c2016-03-30 12:55:14 -07003349 channel_ready_to_send_ = true;
3350 }
zhihuangd06adf62017-01-12 15:58:31 -08003351 void OnChannelStateChanged(IceTransportInternal* channel) {
Honghai Zhang1590c392016-05-24 13:15:02 -07003352 channel_state_ = channel->GetState();
3353 }
Alex Drake00c7ecf2019-08-06 10:54:47 -07003354 void OnCandidatePairChanged(const CandidatePairChangeEvent& event) {
3355 last_candidate_change_event_ = event;
3356 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003357
Honghai Zhang52dce732016-03-31 12:37:31 -07003358 int last_sent_packet_id() { return last_sent_packet_id_; }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003359 bool channel_ready_to_send() { return channel_ready_to_send_; }
3360 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
zhihuangd06adf62017-01-12 15:58:31 -08003361 IceTransportState channel_state() { return channel_state_; }
honghaiz9ad0db52016-07-14 19:30:28 -07003362 int reset_selected_candidate_pair_switches() {
Honghai Zhang572b0942016-06-23 12:26:57 -07003363 int switches = selected_candidate_pair_switches_;
3364 selected_candidate_pair_switches_ = 0;
3365 return switches;
3366 }
Honghai Zhang82f132c2016-03-30 12:55:14 -07003367
Zhi Huang942bc2e2017-11-13 13:26:07 -08003368 // Return true if the |pair| matches the last network route.
3369 bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
3370 if (!pair) {
3371 return !last_network_route_.has_value();
3372 } else {
3373 return pair->local_candidate().network_id() ==
3374 last_network_route_->local_network_id &&
3375 pair->remote_candidate().network_id() ==
3376 last_network_route_->remote_network_id;
3377 }
3378 }
3379
Alex Drake00c7ecf2019-08-06 10:54:47 -07003380 bool ConnectionMatchesChangeEvent(Connection* conn, std::string reason) {
3381 if (!conn) {
3382 return !last_candidate_change_event_.has_value();
3383 } else {
Qingsi Wang7cdcda92019-08-28 09:18:37 -07003384 const auto& last_selected_pair =
3385 last_candidate_change_event_->selected_candidate_pair;
3386 return last_selected_pair.local_candidate().IsEquivalent(
Alex Drake00c7ecf2019-08-06 10:54:47 -07003387 conn->local_candidate()) &&
Qingsi Wang7cdcda92019-08-28 09:18:37 -07003388 last_selected_pair.remote_candidate().IsEquivalent(
Alex Drake00c7ecf2019-08-06 10:54:47 -07003389 conn->remote_candidate()) &&
3390 last_candidate_change_event_->last_data_received_ms ==
3391 conn->last_data_received() &&
3392 last_candidate_change_event_->reason == reason;
3393 }
3394 }
3395
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003396 private:
kwiberg3ec46792016-04-27 07:22:53 -07003397 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -07003398 rtc::AutoSocketServerThread thread_;
Honghai Zhang572b0942016-06-23 12:26:57 -07003399 int selected_candidate_pair_switches_ = 0;
Honghai Zhang52dce732016-03-31 12:37:31 -07003400 int last_sent_packet_id_ = -1;
Honghai Zhang82f132c2016-03-30 12:55:14 -07003401 bool channel_ready_to_send_ = false;
Alex Drake00c7ecf2019-08-06 10:54:47 -07003402 absl::optional<CandidatePairChangeEvent> last_candidate_change_event_;
zhihuangd06adf62017-01-12 15:58:31 -08003403 IceTransportState channel_state_ = IceTransportState::STATE_INIT;
Danil Chapovalov00c71832018-06-15 15:58:38 +02003404 absl::optional<rtc::NetworkRoute> last_network_route_;
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003405};
3406
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003407TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
deadbeef14f97f52016-06-22 17:14:15 -07003408 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3409 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003410 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003411 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003412 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3413 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003414
deadbeef14f97f52016-06-22 17:14:15 -07003415 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3416 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003417 ASSERT_TRUE(conn1 != nullptr);
3418 ASSERT_TRUE(conn2 != nullptr);
3419
3420 // Before a triggered check, the first connection to ping is the
3421 // highest priority one.
guoweis36f01372016-03-02 18:02:40 -08003422 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003423
3424 // Receiving a ping causes a triggered check which should make conn1
3425 // be pinged first instead of conn2, even though conn2 has a higher
3426 // priority.
3427 conn1->ReceivedPing();
guoweis36f01372016-03-02 18:02:40 -08003428 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003429}
3430
honghaiz524ecc22016-05-25 12:48:31 -07003431TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
deadbeef14f97f52016-06-22 17:14:15 -07003432 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3433 P2PTransportChannel ch("ping sufficiently", 1, &pa);
honghaiz524ecc22016-05-25 12:48:31 -07003434 PrepareChannel(&ch);
honghaiz524ecc22016-05-25 12:48:31 -07003435 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003436 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3437 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
honghaiz524ecc22016-05-25 12:48:31 -07003438
deadbeef14f97f52016-06-22 17:14:15 -07003439 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3440 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz524ecc22016-05-25 12:48:31 -07003441 ASSERT_TRUE(conn1 != nullptr);
3442 ASSERT_TRUE(conn2 != nullptr);
3443
3444 // Low-priority connection becomes writable so that the other connection
3445 // is not pruned.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003446 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz524ecc22016-05-25 12:48:31 -07003447 EXPECT_TRUE_WAIT(
3448 conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
3449 conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3450 kDefaultTimeout);
3451}
3452
zhihuang435264a2016-06-21 11:28:38 -07003453// Verify that the connections are pinged at the right time.
3454TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
3455 rtc::ScopedFakeClock clock;
3456 int RTT_RATIO = 4;
3457 int SCHEDULING_RANGE = 200;
3458 int RTT_RANGE = 10;
3459
deadbeef14f97f52016-06-22 17:14:15 -07003460 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3461 P2PTransportChannel ch("TestChannel", 1, &pa);
zhihuang435264a2016-06-21 11:28:38 -07003462 PrepareChannel(&ch);
zhihuang435264a2016-06-21 11:28:38 -07003463 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003464 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3465 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
zhihuang435264a2016-06-21 11:28:38 -07003466
3467 ASSERT_TRUE(conn != nullptr);
3468 SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);
3469
3470 // Initializing.
3471
3472 int64_t start = clock.TimeNanos();
3473 SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
3474 kDefaultTimeout, clock);
3475 int64_t ping_interval_ms = (clock.TimeNanos() - start) /
3476 rtc::kNumNanosecsPerMillisec /
3477 (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
deadbeef14f97f52016-06-22 17:14:15 -07003478 EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);
zhihuang435264a2016-06-21 11:28:38 -07003479
3480 // Stabilizing.
3481
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003482 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003483 int ping_sent_before = conn->num_pings_sent();
3484 start = clock.TimeNanos();
3485 // The connection becomes strong but not stable because we haven't been able
3486 // to converge the RTT.
Honghai Zhang161a5862016-10-20 11:47:02 -07003487 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3488 clock);
zhihuang435264a2016-06-21 11:28:38 -07003489 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003490 EXPECT_GE(ping_interval_ms,
3491 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3492 EXPECT_LE(
3493 ping_interval_ms,
3494 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003495
3496 // Stabilized.
3497
3498 // The connection becomes stable after receiving more than RTT_RATIO rtt
3499 // samples.
3500 for (int i = 0; i < RTT_RATIO; i++) {
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003501 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003502 }
3503 ping_sent_before = conn->num_pings_sent();
3504 start = clock.TimeNanos();
Honghai Zhang161a5862016-10-20 11:47:02 -07003505 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3506 clock);
zhihuang435264a2016-06-21 11:28:38 -07003507 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003508 EXPECT_GE(ping_interval_ms,
3509 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
3510 EXPECT_LE(
3511 ping_interval_ms,
3512 STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003513
3514 // Destabilized.
3515
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003516 conn->ReceivedPingResponse(LOW_RTT, "id");
zhihuang435264a2016-06-21 11:28:38 -07003517 // Create a in-flight ping.
3518 conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
3519 start = clock.TimeNanos();
3520 // In-flight ping timeout and the connection will be unstable.
3521 SIMULATED_WAIT(
Honghai Zhang161a5862016-10-20 11:47:02 -07003522 !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
3523 kMediumTimeout, clock);
zhihuang435264a2016-06-21 11:28:38 -07003524 int64_t duration_ms =
3525 (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
3526 EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
3527 EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
3528 // The connection become unstable due to not receiving ping responses.
3529 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003530 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3531 clock);
zhihuang435264a2016-06-21 11:28:38 -07003532 // The interval is expected to be
honghaiz7252a002016-11-08 20:04:09 -08003533 // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
zhihuang435264a2016-06-21 11:28:38 -07003534 start = clock.TimeNanos();
3535 ping_sent_before = conn->num_pings_sent();
Honghai Zhang161a5862016-10-20 11:47:02 -07003536 SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
3537 clock);
zhihuang435264a2016-06-21 11:28:38 -07003538 ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
honghaiz7252a002016-11-08 20:04:09 -08003539 EXPECT_GE(ping_interval_ms,
3540 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
3541 EXPECT_LE(
3542 ping_interval_ms,
3543 WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
zhihuang435264a2016-06-21 11:28:38 -07003544}
3545
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003546// Test that we start pinging as soon as we have a connection and remote ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003547// parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003548TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
3549 rtc::ScopedFakeClock clock;
3550
3551 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3552 P2PTransportChannel ch("TestChannel", 1, &pa);
3553 ch.SetIceRole(ICEROLE_CONTROLLING);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003554 ch.SetIceParameters(kIceParams[0]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003555 ch.MaybeStartGathering();
3556 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
3557 kDefaultTimeout);
3558
3559 // Simulate a binding request being received, creating a peer reflexive
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003560 // candidate pair while we still don't have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003561 IceMessage request;
3562 request.SetType(STUN_BINDING_REQUEST);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003563 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003564 STUN_ATTR_USERNAME, kIceUfrag[1]));
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003565 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003566 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
3567 prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003568 Port* port = GetPort(&ch);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003569 ASSERT_NE(nullptr, port);
3570 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3571 &request, kIceUfrag[1], false);
3572 Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
3573 ASSERT_NE(nullptr, conn);
3574
3575 // Simulate waiting for a second (and change) and verify that no pings were
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003576 // sent, since we don't yet have remote ICE parameters.
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003577 SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
3578 EXPECT_EQ(0, conn->num_pings_sent());
3579
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003580 // Set remote ICE parameters. Now we should be able to ping. Ensure that
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003581 // the first ping is sent as soon as possible, within one simulated clock
3582 // tick.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003583 ch.SetRemoteIceParameters(kIceParams[1]);
Taylor Brandstetterb825aee2016-06-29 13:07:16 -07003584 EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
3585}
3586
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003587TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
deadbeef14f97f52016-06-22 17:14:15 -07003588 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3589 P2PTransportChannel ch("trigger checks", 1, &pa);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003590 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003591 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003592 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3593 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003594
deadbeef14f97f52016-06-22 17:14:15 -07003595 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3596 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003597 ASSERT_TRUE(conn1 != nullptr);
3598 ASSERT_TRUE(conn2 != nullptr);
3599
guoweis36f01372016-03-02 18:02:40 -08003600 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
3601 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003602 conn1->ReceivedPingResponse(LOW_RTT, "id");
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003603 ASSERT_TRUE(conn1->writable());
3604 conn1->ReceivedPing();
3605
3606 // Ping received, but the connection is already writable, so no
3607 // "triggered check" and conn2 is pinged before conn1 because it has
3608 // a higher priority.
guoweis36f01372016-03-02 18:02:40 -08003609 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
Peter Thatcher1fe120a2015-06-10 11:33:17 -07003610}
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003611
honghaiz079a7a12016-06-22 16:26:29 -07003612TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
deadbeef14f97f52016-06-22 17:14:15 -07003613 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3614 P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
honghaiz079a7a12016-06-22 16:26:29 -07003615 PrepareChannel(&ch);
honghaiz079a7a12016-06-22 16:26:29 -07003616 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003617 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaiz079a7a12016-06-22 16:26:29 -07003618
deadbeef14f97f52016-06-22 17:14:15 -07003619 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz079a7a12016-06-22 16:26:29 -07003620 ASSERT_TRUE(conn1 != nullptr);
3621
3622 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3623 conn1->Prune(); // A pruned connection may still be pingable.
3624 EXPECT_EQ(conn1, ch.FindNextPingableConnection());
3625 conn1->FailAndPrune();
3626 EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
3627}
3628
Honghai Zhang1590c392016-05-24 13:15:02 -07003629TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
deadbeef14f97f52016-06-22 17:14:15 -07003630 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3631 P2PTransportChannel ch("state change", 1, &pa);
Honghai Zhang1590c392016-05-24 13:15:02 -07003632 PrepareChannel(&ch);
Honghai Zhang1590c392016-05-24 13:15:02 -07003633 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003634 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3635 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Honghai Zhang1590c392016-05-24 13:15:02 -07003636 ASSERT_TRUE(conn1 != nullptr);
3637 // Pruning the connection reduces the set of active connections and changes
3638 // the channel state.
3639 conn1->Prune();
zhihuangd06adf62017-01-12 15:58:31 -08003640 EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
3641 kDefaultTimeout);
Honghai Zhang1590c392016-05-24 13:15:02 -07003642}
3643
honghaiza54a0802015-12-16 18:37:23 -08003644// Test adding remote candidates with different ufrags. If a remote candidate
3645// is added with an old ufrag, it will be discarded. If it is added with a
3646// ufrag that was not seen before, it will be used to create connections
3647// although the ICE pwd in the remote candidate will be set when the ICE
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003648// parameters arrive. If a remote candidate is added with the current ICE
honghaiza54a0802015-12-16 18:37:23 -08003649// ufrag, its pwd and generation will be set properly.
3650TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
deadbeef14f97f52016-06-22 17:14:15 -07003651 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3652 P2PTransportChannel ch("add candidate", 1, &pa);
honghaiza54a0802015-12-16 18:37:23 -08003653 PrepareChannel(&ch);
honghaiza54a0802015-12-16 18:37:23 -08003654 ch.MaybeStartGathering();
3655 // Add a candidate with a future ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07003656 ch.AddRemoteCandidate(
3657 CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
3658 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiza54a0802015-12-16 18:37:23 -08003659 ASSERT_TRUE(conn1 != nullptr);
deadbeef14f97f52016-06-22 17:14:15 -07003660 const Candidate& candidate = conn1->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003661 EXPECT_EQ(kIceUfrag[2], candidate.username());
3662 EXPECT_TRUE(candidate.password().empty());
guoweis36f01372016-03-02 18:02:40 -08003663 EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);
honghaiza54a0802015-12-16 18:37:23 -08003664
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003665 // Set the remote ICE parameters with the "future" ufrag.
honghaiza54a0802015-12-16 18:37:23 -08003666 // This should set the ICE pwd in the remote candidate of |conn1|, making
3667 // it pingable.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003668 ch.SetRemoteIceParameters(kIceParams[2]);
honghaiza54a0802015-12-16 18:37:23 -08003669 EXPECT_EQ(kIceUfrag[2], candidate.username());
3670 EXPECT_EQ(kIcePwd[2], candidate.password());
guoweis36f01372016-03-02 18:02:40 -08003671 EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
honghaiza54a0802015-12-16 18:37:23 -08003672
3673 // Add a candidate with an old ufrag. No connection will be created.
deadbeef14f97f52016-06-22 17:14:15 -07003674 ch.AddRemoteCandidate(
3675 CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
honghaiza54a0802015-12-16 18:37:23 -08003676 rtc::Thread::Current()->ProcessMessages(500);
3677 EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);
3678
3679 // Add a candidate with the current ufrag, its pwd and generation will be
3680 // assigned, even if the generation is not set.
deadbeef14f97f52016-06-22 17:14:15 -07003681 ch.AddRemoteCandidate(
3682 CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
3683 Connection* conn3 = nullptr;
honghaiza54a0802015-12-16 18:37:23 -08003684 ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
Honghai Zhang161a5862016-10-20 11:47:02 -07003685 kMediumTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07003686 const Candidate& new_candidate = conn3->remote_candidate();
honghaiza54a0802015-12-16 18:37:23 -08003687 EXPECT_EQ(kIcePwd[2], new_candidate.password());
3688 EXPECT_EQ(1U, new_candidate.generation());
honghaiz112fe432015-12-30 13:32:47 -08003689
3690 // Check that the pwd of all remote candidates are properly assigned.
deadbeef14f97f52016-06-22 17:14:15 -07003691 for (const RemoteCandidate& candidate : ch.remote_candidates()) {
honghaiz112fe432015-12-30 13:32:47 -08003692 EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
3693 candidate.username() == kIceUfrag[2]);
3694 if (candidate.username() == kIceUfrag[1]) {
3695 EXPECT_EQ(kIcePwd[1], candidate.password());
3696 } else if (candidate.username() == kIceUfrag[2]) {
3697 EXPECT_EQ(kIcePwd[2], candidate.password());
3698 }
3699 }
honghaiza54a0802015-12-16 18:37:23 -08003700}
3701
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003702TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
deadbeef14f97f52016-06-22 17:14:15 -07003703 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3704 P2PTransportChannel ch("connection resurrection", 1, &pa);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003705 PrepareChannel(&ch);
deadbeefcbecd352015-09-23 11:50:27 -07003706 ch.MaybeStartGathering();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003707
3708 // Create conn1 and keep track of original candidate priority.
deadbeef14f97f52016-06-22 17:14:15 -07003709 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3710 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003711 ASSERT_TRUE(conn1 != nullptr);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003712 uint32_t remote_priority = conn1->remote_candidate().priority();
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003713
3714 // Create a higher priority candidate and make the connection
Peter Thatcher04ac81f2015-09-21 11:48:28 -07003715 // receiving/writable. This will prune conn1.
deadbeef14f97f52016-06-22 17:14:15 -07003716 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
3717 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003718 ASSERT_TRUE(conn2 != nullptr);
3719 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003720 conn2->ReceivedPingResponse(LOW_RTT, "id");
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003721
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003722 // Wait for conn1 to be pruned.
Honghai Zhang161a5862016-10-20 11:47:02 -07003723 EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07003724 // Destroy the connection to test SignalUnknownAddress.
3725 conn1->Destroy();
honghaize58d73d2016-10-24 16:38:26 -07003726 EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
3727 kMediumTimeout);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003728
3729 // Create a minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003730 IceMessage request;
3731 request.SetType(STUN_BINDING_REQUEST);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003732 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003733 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003734 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003735 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
3736 prflx_priority));
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003737 EXPECT_NE(prflx_priority, remote_priority);
3738
sprang716978d2016-10-11 06:43:28 -07003739 Port* port = GetPort(&ch);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003740 // conn1 should be resurrected with original priority.
deadbeef14f97f52016-06-22 17:14:15 -07003741 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3742 &request, kIceUfrag[1], false);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003743 conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3744 ASSERT_TRUE(conn1 != nullptr);
3745 EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);
3746
3747 // conn3, a real prflx connection, should have prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003748 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
3749 &request, kIceUfrag[1], false);
3750 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
Guo-wei Shieh372f2fc2015-06-12 10:12:46 -07003751 ASSERT_TRUE(conn3 != nullptr);
3752 EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
3753}
Peter Thatcher54360512015-07-08 11:08:35 -07003754
3755TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
honghaize58d73d2016-10-24 16:38:26 -07003756 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07003757 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3758 P2PTransportChannel ch("receiving state change", 1, &pa);
Peter Thatcher54360512015-07-08 11:08:35 -07003759 PrepareChannel(&ch);
Honghai Zhang049fbb12016-03-07 11:13:07 -08003760 // Default receiving timeout and checking receiving interval should not be too
Peter Thatcher54360512015-07-08 11:08:35 -07003761 // small.
Qingsi Wang866e08d2018-03-22 17:54:23 -07003762 EXPECT_LE(1000, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003763 EXPECT_LE(200, ch.check_receiving_interval());
Honghai Zhang5622c5e2016-07-01 13:59:29 -07003764 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
Qingsi Wang866e08d2018-03-22 17:54:23 -07003765 EXPECT_EQ(500, ch.config().receiving_timeout_or_default());
Honghai Zhang049fbb12016-03-07 11:13:07 -08003766 EXPECT_EQ(50, ch.check_receiving_interval());
deadbeefcbecd352015-09-23 11:50:27 -07003767 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003768 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
honghaize58d73d2016-10-24 16:38:26 -07003769 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003770 ASSERT_TRUE(conn1 != nullptr);
3771
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003772 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Peter Thatcher54360512015-07-08 11:08:35 -07003773 conn1->ReceivedPing();
Niels Möller15ca5a92018-11-01 14:32:47 +01003774 conn1->OnReadPacket("ABC", 3, rtc::TimeMicros());
honghaize58d73d2016-10-24 16:38:26 -07003775 EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
3776 EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
Peter Thatcher54360512015-07-08 11:08:35 -07003777}
honghaiz5a3acd82015-08-20 15:53:17 -07003778
Honghai Zhang572b0942016-06-23 12:26:57 -07003779// The controlled side will select a connection as the "selected connection"
3780// based on priority until the controlling side nominates a connection, at which
honghaiz5a3acd82015-08-20 15:53:17 -07003781// point the controlled side will select that connection as the
Zhi Huang942bc2e2017-11-13 13:26:07 -08003782// "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
Honghai Zhang572b0942016-06-23 12:26:57 -07003783// selected connection changes and SignalReadyToSend will be fired if the new
3784// selected connection is writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003785TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
deadbeef14f97f52016-06-22 17:14:15 -07003786 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3787 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003788 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003789 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003790 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003791 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
3792 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003793 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang52dce732016-03-31 12:37:31 -07003794 // Channel is not ready to send because it is not writable.
Honghai Zhang82f132c2016-03-30 12:55:14 -07003795 EXPECT_FALSE(channel_ready_to_send());
Honghai Zhang52dce732016-03-31 12:37:31 -07003796 int last_packet_id = 0;
3797 const char* data = "ABCDEFGH";
3798 int len = static_cast<int>(strlen(data));
Steve Antone9324572017-11-29 10:18:21 -08003799 EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003800 EXPECT_EQ(-1, last_sent_packet_id());
3801
3802 // A connection needs to be writable before it is selected for transmission.
3803 conn1->ReceivedPingResponse(LOW_RTT, "id");
3804 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003805 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Alex Drake00c7ecf2019-08-06 10:54:47 -07003806 EXPECT_TRUE(ConnectionMatchesChangeEvent(
3807 conn1, "remote candidate generation maybe changed"));
Steve Antone9324572017-11-29 10:18:21 -08003808 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003809
honghaiz5a3acd82015-08-20 15:53:17 -07003810 // When a higher priority candidate comes in, the new connection is chosen
Honghai Zhang572b0942016-06-23 12:26:57 -07003811 // as the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003812 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
3813 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz89374372015-09-24 13:14:47 -07003814 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003815 conn2->ReceivedPingResponse(LOW_RTT, "id");
3816 EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003817 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Alex Drake00c7ecf2019-08-06 10:54:47 -07003818 EXPECT_TRUE(
3819 ConnectionMatchesChangeEvent(conn2, "candidate pair state changed"));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003820 EXPECT_TRUE(channel_ready_to_send());
3821 EXPECT_EQ(last_packet_id, last_sent_packet_id());
honghaiz5a3acd82015-08-20 15:53:17 -07003822
3823 // If a stun request with use-candidate attribute arrives, the receiving
Honghai Zhang572b0942016-06-23 12:26:57 -07003824 // connection will be set as the selected connection, even though
honghaiz5a3acd82015-08-20 15:53:17 -07003825 // its priority is lower.
Steve Antone9324572017-11-29 10:18:21 -08003826 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003827 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
3828 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003829 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003830 // Because it has a lower priority, the selected connection is still conn2.
3831 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003832 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003833 // But if it is nominated via use_candidate, it is chosen as the selected
honghaiz5a3acd82015-08-20 15:53:17 -07003834 // connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003835 NominateConnection(conn3);
Honghai Zhang572b0942016-06-23 12:26:57 -07003836 EXPECT_EQ(conn3, ch.selected_connection());
Zhi Huang942bc2e2017-11-13 13:26:07 -08003837 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
Alex Drake00c7ecf2019-08-06 10:54:47 -07003838 EXPECT_TRUE(
3839 ConnectionMatchesChangeEvent(conn3, "nomination on the controlled side"));
Honghai Zhange05bcc22016-08-16 18:19:14 -07003840 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003841 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003842
Honghai Zhang572b0942016-06-23 12:26:57 -07003843 // Even if another higher priority candidate arrives, it will not be set as
3844 // the selected connection because the selected connection is nominated by
3845 // the controlling side.
Steve Antone9324572017-11-29 10:18:21 -08003846 EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
deadbeef14f97f52016-06-22 17:14:15 -07003847 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
3848 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003849 ASSERT_TRUE(conn4 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003850 EXPECT_EQ(conn3, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003851 // But if it is nominated via use_candidate and writable, it will be set as
Honghai Zhang572b0942016-06-23 12:26:57 -07003852 // the selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003853 NominateConnection(conn4);
honghaiz5a3acd82015-08-20 15:53:17 -07003854 // Not switched yet because conn4 is not writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003855 EXPECT_EQ(conn3, ch.selected_connection());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003856 reset_channel_ready_to_send();
Honghai Zhang572b0942016-06-23 12:26:57 -07003857 // The selected connection switches after conn4 becomes writable.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003858 conn4->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang572b0942016-06-23 12:26:57 -07003859 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
Zhi Huang942bc2e2017-11-13 13:26:07 -08003860 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
Alex Drake00c7ecf2019-08-06 10:54:47 -07003861 EXPECT_TRUE(
3862 ConnectionMatchesChangeEvent(conn4, "candidate pair state changed"));
Honghai Zhang52dce732016-03-31 12:37:31 -07003863 EXPECT_EQ(last_packet_id, last_sent_packet_id());
Honghai Zhang82f132c2016-03-30 12:55:14 -07003864 // SignalReadyToSend is fired again because conn4 is writable.
3865 EXPECT_TRUE(channel_ready_to_send());
honghaiz5a3acd82015-08-20 15:53:17 -07003866}
3867
Honghai Zhang572b0942016-06-23 12:26:57 -07003868// The controlled side will select a connection as the "selected connection"
3869// based on requests from an unknown address before the controlling side
3870// nominates a connection, and will nominate a connection from an unknown
3871// address if the request contains the use_candidate attribute. Plus, it will
3872// also sends back a ping response and set the ICE pwd in the remote candidate
3873// appropriately.
honghaiz5a3acd82015-08-20 15:53:17 -07003874TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
deadbeef14f97f52016-06-22 17:14:15 -07003875 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3876 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003877 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003878 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003879 ch.MaybeStartGathering();
honghaiz5a3acd82015-08-20 15:53:17 -07003880 // A minimal STUN message with prflx priority.
deadbeef14f97f52016-06-22 17:14:15 -07003881 IceMessage request;
3882 request.SetType(STUN_BINDING_REQUEST);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003883 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003884 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003885 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003886 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
3887 prflx_priority));
sprang716978d2016-10-11 06:43:28 -07003888 TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
deadbeef14f97f52016-06-22 17:14:15 -07003889 port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
3890 &request, kIceUfrag[1], false);
3891 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003892 ASSERT_TRUE(conn1 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003893 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhange05bcc22016-08-16 18:19:14 -07003894 EXPECT_NE(conn1, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003895 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07003896 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003897 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003898
3899 // Another connection is nominated via use_candidate.
deadbeef14f97f52016-06-22 17:14:15 -07003900 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3901 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003902 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003903 // Because it has a lower priority, the selected connection is still conn1.
3904 EXPECT_EQ(conn1, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003905 // When it is nominated via use_candidate and writable, it is chosen as the
Honghai Zhang572b0942016-06-23 12:26:57 -07003906 // selected connection.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003907 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
3908 NominateConnection(conn2);
Honghai Zhang572b0942016-06-23 12:26:57 -07003909 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz5a3acd82015-08-20 15:53:17 -07003910
Honghai Zhang572b0942016-06-23 12:26:57 -07003911 // Another request with unknown address, it will not be set as the selected
3912 // connection because the selected connection was nominated by the controlling
honghaiz5a3acd82015-08-20 15:53:17 -07003913 // side.
deadbeef14f97f52016-06-22 17:14:15 -07003914 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3915 &request, kIceUfrag[1], false);
3916 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003917 ASSERT_TRUE(conn3 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003918 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003919 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003920 EXPECT_EQ(conn2, ch.selected_connection());
honghaiz9b5ee9c2015-11-11 13:19:17 -08003921 port->set_sent_binding_response(false);
honghaiz5a3acd82015-08-20 15:53:17 -07003922
3923 // However if the request contains use_candidate attribute, it will be
Honghai Zhang572b0942016-06-23 12:26:57 -07003924 // selected as the selected connection.
zsteinf42cc9d2017-03-27 16:17:19 -07003925 request.AddAttribute(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003926 std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
deadbeef14f97f52016-06-22 17:14:15 -07003927 port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
3928 &request, kIceUfrag[1], false);
3929 Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
honghaiz5a3acd82015-08-20 15:53:17 -07003930 ASSERT_TRUE(conn4 != nullptr);
honghaiz9b5ee9c2015-11-11 13:19:17 -08003931 EXPECT_TRUE(port->sent_binding_response());
Honghai Zhang572b0942016-06-23 12:26:57 -07003932 // conn4 is not the selected connection yet because it is not writable.
3933 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003934 conn4->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003935 EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
honghaiz112fe432015-12-30 13:32:47 -08003936
3937 // Test that the request from an unknown address contains a ufrag from an old
3938 // generation.
3939 port->set_sent_binding_response(false);
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07003940 ch.SetRemoteIceParameters(kIceParams[2]);
3941 ch.SetRemoteIceParameters(kIceParams[3]);
deadbeef14f97f52016-06-22 17:14:15 -07003942 port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
3943 &request, kIceUfrag[2], false);
3944 Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
honghaiz112fe432015-12-30 13:32:47 -08003945 ASSERT_TRUE(conn5 != nullptr);
3946 EXPECT_TRUE(port->sent_binding_response());
3947 EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
honghaiz5a3acd82015-08-20 15:53:17 -07003948}
3949
Honghai Zhang572b0942016-06-23 12:26:57 -07003950// The controlled side will select a connection as the "selected connection"
honghaiz5a3acd82015-08-20 15:53:17 -07003951// based on media received until the controlling side nominates a connection,
3952// at which point the controlled side will select that connection as
Honghai Zhang572b0942016-06-23 12:26:57 -07003953// the "selected connection".
honghaiz5a3acd82015-08-20 15:53:17 -07003954TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
deadbeef14f97f52016-06-22 17:14:15 -07003955 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3956 P2PTransportChannel ch("receiving state change", 1, &pa);
honghaiz5a3acd82015-08-20 15:53:17 -07003957 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003958 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefcbecd352015-09-23 11:50:27 -07003959 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07003960 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
3961 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz5a3acd82015-08-20 15:53:17 -07003962 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003963 conn1->ReceivedPingResponse(LOW_RTT, "id");
3964 EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003965
Honghai Zhang572b0942016-06-23 12:26:57 -07003966 // If a data packet is received on conn2, the selected connection should
honghaiz5a3acd82015-08-20 15:53:17 -07003967 // switch to conn2 because the controlled side must mirror the media path
3968 // chosen by the controlling side.
deadbeef14f97f52016-06-22 17:14:15 -07003969 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
3970 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz5a3acd82015-08-20 15:53:17 -07003971 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07003972 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable and receiving.
Niels Möller15ca5a92018-11-01 14:32:47 +01003973 conn2->OnReadPacket("ABC", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07003974 EXPECT_EQ(conn2, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003975 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
honghaiz5a3acd82015-08-20 15:53:17 -07003976
3977 // Now another STUN message with an unknown address and use_candidate will
Honghai Zhang572b0942016-06-23 12:26:57 -07003978 // nominate the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07003979 IceMessage request;
3980 request.SetType(STUN_BINDING_REQUEST);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003981 request.AddAttribute(std::make_unique<StunByteStringAttribute>(
zsteinf42cc9d2017-03-27 16:17:19 -07003982 STUN_ATTR_USERNAME, kIceUfrag[1]));
deadbeef14f97f52016-06-22 17:14:15 -07003983 uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003984 request.AddAttribute(std::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY,
3985 prflx_priority));
deadbeef14f97f52016-06-22 17:14:15 -07003986 request.AddAttribute(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003987 std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
sprang716978d2016-10-11 06:43:28 -07003988 Port* port = GetPort(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07003989 port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
3990 &request, kIceUfrag[1], false);
3991 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
honghaiz5a3acd82015-08-20 15:53:17 -07003992 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07003993 EXPECT_EQ(conn2, ch.selected_connection()); // Not writable yet.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07003994 conn3->ReceivedPingResponse(LOW_RTT, "id"); // Become writable.
Honghai Zhang572b0942016-06-23 12:26:57 -07003995 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
honghaiz5a3acd82015-08-20 15:53:17 -07003996
Honghai Zhang572b0942016-06-23 12:26:57 -07003997 // Now another data packet will not switch the selected connection because the
3998 // selected connection was nominated by the controlling side.
honghaiz5a3acd82015-08-20 15:53:17 -07003999 conn2->ReceivedPing();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004000 conn2->ReceivedPingResponse(LOW_RTT, "id");
Niels Möller15ca5a92018-11-01 14:32:47 +01004001 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07004002 EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
4003}
4004
4005TEST_F(P2PTransportChannelPingTest,
4006 TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
4007 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004008 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004009 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4010 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
4011 PrepareChannel(&ch);
4012 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004013 ch.MaybeStartGathering();
4014 // The connections have decreasing priority.
4015 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004016 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004017 ASSERT_TRUE(conn1 != nullptr);
4018 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004019 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004020 ASSERT_TRUE(conn2 != nullptr);
4021
4022 // Initially, connections are selected based on priority.
honghaiz9ad0db52016-07-14 19:30:28 -07004023 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004024 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004025
4026 // conn2 receives data; it becomes selected.
4027 // Advance the clock by 1ms so that the last data receiving timestamp of
4028 // conn2 is larger.
4029 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01004030 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07004031 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004032 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004033
4034 // conn1 also receives data; it becomes selected due to priority again.
Niels Möller15ca5a92018-11-01 14:32:47 +01004035 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07004036 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004037 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004038
Honghai Zhange05bcc22016-08-16 18:19:14 -07004039 // conn2 received data more recently; it is selected now because it
4040 // received data more recently.
4041 SIMULATED_WAIT(false, 1, clock);
4042 // Need to become writable again because it was pruned.
4043 conn2->ReceivedPingResponse(LOW_RTT, "id");
Niels Möller15ca5a92018-11-01 14:32:47 +01004044 conn2->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhange05bcc22016-08-16 18:19:14 -07004045 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004046 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004047
Honghai Zhang572b0942016-06-23 12:26:57 -07004048 // Make sure sorting won't reselect candidate pair.
4049 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07004050 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07004051}
4052
4053TEST_F(P2PTransportChannelPingTest,
4054 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
4055 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004056 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004057
4058 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4059 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
4060 PrepareChannel(&ch);
4061 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004062 ch.MaybeStartGathering();
4063 // The connections have decreasing priority.
4064 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004065 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004066 ASSERT_TRUE(conn1 != nullptr);
4067 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004068 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004069 ASSERT_TRUE(conn2 != nullptr);
4070
4071 // conn1 received data; it is the selected connection.
4072 // Advance the clock to have a non-zero last-data-receiving time.
4073 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01004074 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
honghaiz9ad0db52016-07-14 19:30:28 -07004075 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004076 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004077
4078 // conn2 is nominated; it becomes the selected connection.
4079 NominateConnection(conn2);
honghaiz9ad0db52016-07-14 19:30:28 -07004080 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004081 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004082
Honghai Zhange05bcc22016-08-16 18:19:14 -07004083 // conn1 is selected because it has higher priority and also nominated.
Honghai Zhang572b0942016-06-23 12:26:57 -07004084 NominateConnection(conn1);
honghaiz9ad0db52016-07-14 19:30:28 -07004085 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004086 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004087
Honghai Zhang572b0942016-06-23 12:26:57 -07004088 // Make sure sorting won't reselect candidate pair.
4089 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07004090 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07004091}
4092
4093TEST_F(P2PTransportChannelPingTest,
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004094 TestControlledAgentSelectsConnectionWithHigherNomination) {
4095 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004096 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004097
4098 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4099 P2PTransportChannel ch("test", 1, &pa);
4100 PrepareChannel(&ch);
4101 ch.SetIceRole(ICEROLE_CONTROLLED);
4102 ch.MaybeStartGathering();
4103 // The connections have decreasing priority.
4104 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004105 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004106 ASSERT_TRUE(conn1 != nullptr);
4107 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004108 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004109 ASSERT_TRUE(conn2 != nullptr);
4110
4111 // conn1 is the selected connection because it has a higher priority,
Zhi Huang942bc2e2017-11-13 13:26:07 -08004112 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4113 clock);
4114 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004115 reset_selected_candidate_pair_switches();
4116
4117 // conn2 is nominated; it becomes selected.
4118 NominateConnection(conn2);
4119 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004120 EXPECT_EQ(conn2, ch.selected_connection());
4121 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004122
4123 // conn1 is selected because of its priority.
4124 NominateConnection(conn1);
4125 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004126 EXPECT_EQ(conn1, ch.selected_connection());
4127 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004128
4129 // conn2 gets higher remote nomination; it is selected again.
4130 NominateConnection(conn2, 2U);
4131 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
Zhi Huang942bc2e2017-11-13 13:26:07 -08004132 EXPECT_EQ(conn2, ch.selected_connection());
4133 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004134
4135 // Make sure sorting won't reselect candidate pair.
4136 SIMULATED_WAIT(false, 100, clock);
4137 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
4138}
4139
4140TEST_F(P2PTransportChannelPingTest,
4141 TestControlledAgentIgnoresSmallerNomination) {
4142 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004143 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07004144
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004145 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4146 P2PTransportChannel ch("test", 1, &pa);
4147 PrepareChannel(&ch);
4148 ch.SetIceRole(ICEROLE_CONTROLLED);
4149 ch.MaybeStartGathering();
4150 Connection* conn =
Steve Antone9324572017-11-29 10:18:21 -08004151 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004152 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
4153 EXPECT_EQ(2U, conn->remote_nomination());
4154 // Smaller nomination is ignored.
4155 ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
4156 EXPECT_EQ(2U, conn->remote_nomination());
4157}
4158
4159TEST_F(P2PTransportChannelPingTest,
Honghai Zhang572b0942016-06-23 12:26:57 -07004160 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
4161 rtc::ScopedFakeClock clock;
4162
4163 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4164 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
4165 PrepareChannel(&ch);
4166 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004167 ch.MaybeStartGathering();
4168 // The connections have decreasing priority.
4169 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004170 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004171 ASSERT_TRUE(conn1 != nullptr);
4172 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004173 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004174 ASSERT_TRUE(conn2 != nullptr);
4175
4176 NominateConnection(conn1);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004177 // There is no selected connection because no connection is writable.
4178 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
Honghai Zhang572b0942016-06-23 12:26:57 -07004179
4180 // conn2 becomes writable; it is selected even though it is not nominated.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004181 conn2->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07004182 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07004183 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08004184 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4185 clock);
4186 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
Honghai Zhang572b0942016-06-23 12:26:57 -07004187
4188 // If conn1 is also writable, it will become selected.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004189 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaiz9ad0db52016-07-14 19:30:28 -07004190 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
Honghai Zhang572b0942016-06-23 12:26:57 -07004191 kDefaultTimeout, clock);
Zhi Huang942bc2e2017-11-13 13:26:07 -08004192 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4193 clock);
4194 EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
Honghai Zhang572b0942016-06-23 12:26:57 -07004195
4196 // Make sure sorting won't reselect candidate pair.
4197 SIMULATED_WAIT(false, 10, clock);
honghaiz9ad0db52016-07-14 19:30:28 -07004198 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
honghaiz5a3acd82015-08-20 15:53:17 -07004199}
honghaiz89374372015-09-24 13:14:47 -07004200
honghaiz36f50e82016-06-01 15:57:03 -07004201// Test that if a new remote candidate has the same address and port with
4202// an old one, it will be used to create a new connection.
4203TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
deadbeef14f97f52016-06-22 17:14:15 -07004204 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4205 P2PTransportChannel ch("candidate reuse", 1, &pa);
honghaiz36f50e82016-06-01 15:57:03 -07004206 PrepareChannel(&ch);
honghaiz36f50e82016-06-01 15:57:03 -07004207 ch.MaybeStartGathering();
4208 const std::string host_address = "1.1.1.1";
4209 const int port_num = 1;
4210
4211 // kIceUfrag[1] is the current generation ufrag.
deadbeef14f97f52016-06-22 17:14:15 -07004212 Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
4213 port_num, 1, kIceUfrag[1]);
honghaiz36f50e82016-06-01 15:57:03 -07004214 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004215 Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004216 ASSERT_TRUE(conn1 != nullptr);
4217 EXPECT_EQ(0u, conn1->remote_candidate().generation());
4218
4219 // Simply adding the same candidate again won't create a new connection.
4220 ch.AddRemoteCandidate(candidate);
deadbeef14f97f52016-06-22 17:14:15 -07004221 Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
honghaiz36f50e82016-06-01 15:57:03 -07004222 EXPECT_EQ(conn1, conn2);
4223
4224 // Update the ufrag of the candidate and add it again.
4225 candidate.set_username(kIceUfrag[2]);
4226 ch.AddRemoteCandidate(candidate);
4227 conn2 = GetConnectionTo(&ch, host_address, port_num);
4228 EXPECT_NE(conn1, conn2);
4229 EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
4230 EXPECT_EQ(1u, conn2->remote_candidate().generation());
4231
4232 // Verify that a ping with the new ufrag can be received on the new
4233 // connection.
4234 EXPECT_EQ(0, conn2->last_ping_received());
4235 ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
Steve Antone9324572017-11-29 10:18:21 -08004236 EXPECT_GT(conn2->last_ping_received(), 0);
honghaiz36f50e82016-06-01 15:57:03 -07004237}
4238
Honghai Zhang572b0942016-06-23 12:26:57 -07004239// When the current selected connection is strong, lower-priority connections
4240// will be pruned. Otherwise, lower-priority connections are kept.
honghaiz89374372015-09-24 13:14:47 -07004241TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
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));
deadbeef14f97f52016-06-22 17:14:15 -07004244 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4245 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz89374372015-09-24 13:14:47 -07004246 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004247 ch.SetIceRole(ICEROLE_CONTROLLED);
honghaiz89374372015-09-24 13:14:47 -07004248 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004249 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4250 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz89374372015-09-24 13:14:47 -07004251 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004252 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004253 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz89374372015-09-24 13:14:47 -07004254
4255 // When a higher-priority, nominated candidate comes in, the connections with
4256 // lower-priority are pruned.
deadbeef14f97f52016-06-22 17:14:15 -07004257 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004258 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz89374372015-09-24 13:14:47 -07004259 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004260 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
4261 NominateConnection(conn2);
Honghai Zhang161a5862016-10-20 11:47:02 -07004262 EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004263
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004264 ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
honghaiz89374372015-09-24 13:14:47 -07004265 // Wait until conn2 becomes not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004266 EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004267
deadbeef14f97f52016-06-22 17:14:15 -07004268 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004269 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz89374372015-09-24 13:14:47 -07004270 ASSERT_TRUE(conn3 != nullptr);
Honghai Zhang572b0942016-06-23 12:26:57 -07004271 // The selected connection should still be conn2. Even through conn3 has lower
4272 // priority and is not receiving/writable, it is not pruned because the
4273 // selected connection is not receiving.
honghaize58d73d2016-10-24 16:38:26 -07004274 SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
honghaiz89374372015-09-24 13:14:47 -07004275 EXPECT_FALSE(conn3->pruned());
4276}
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004277
Honghai Zhang572b0942016-06-23 12:26:57 -07004278TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
4279 rtc::ScopedFakeClock clock;
4280 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4281 P2PTransportChannel ch("test channel", 1, &pa);
4282 PrepareChannel(&ch);
4283 ch.SetIceRole(ICEROLE_CONTROLLED);
Honghai Zhang572b0942016-06-23 12:26:57 -07004284 ch.MaybeStartGathering();
4285 Connection* conn1 =
Steve Antone9324572017-11-29 10:18:21 -08004286 CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
Honghai Zhang572b0942016-06-23 12:26:57 -07004287 ASSERT_TRUE(conn1 != nullptr);
4288 Connection* conn2 =
Steve Antone9324572017-11-29 10:18:21 -08004289 CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
Honghai Zhang572b0942016-06-23 12:26:57 -07004290 ASSERT_TRUE(conn2 != nullptr);
4291 // Even if conn1 is writable, nominated, receiving data, it should not prune
4292 // conn2.
4293 NominateConnection(conn1);
4294 SIMULATED_WAIT(false, 1, clock);
Niels Möller15ca5a92018-11-01 14:32:47 +01004295 conn1->OnReadPacket("XYZ", 3, rtc::TimeMicros());
Honghai Zhang572b0942016-06-23 12:26:57 -07004296 SIMULATED_WAIT(conn2->pruned(), 100, clock);
4297 EXPECT_FALSE(conn2->pruned());
4298}
4299
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004300// Test that GetState returns the state correctly.
4301TEST_F(P2PTransportChannelPingTest, TestGetState) {
honghaize58d73d2016-10-24 16:38:26 -07004302 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004303 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef14f97f52016-06-22 17:14:15 -07004304 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4305 P2PTransportChannel ch("test channel", 1, &pa);
Jonas Olsson81125f02018-10-09 10:52:04 +02004306 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004307 PrepareChannel(&ch);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004308 ch.MaybeStartGathering();
Seth Hampson98335f82019-02-22 17:50:03 -08004309 // After gathering we are still in the kNew state because we aren't checking
4310 // any connections yet.
4311 EXPECT_EQ(webrtc::IceTransportState::kNew, ch.GetIceTransportState());
zhihuangd06adf62017-01-12 15:58:31 -08004312 EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
deadbeef14f97f52016-06-22 17:14:15 -07004313 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4314 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Seth Hampson98335f82019-02-22 17:50:03 -08004315 // Checking candidates that have been added with gathered candidates.
4316 ASSERT_GT(ch.connections().size(), 0u);
4317 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
honghaize58d73d2016-10-24 16:38:26 -07004318 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
4319 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004320 ASSERT_TRUE(conn1 != nullptr);
4321 ASSERT_TRUE(conn2 != nullptr);
4322 // Now there are two connections, so the transport channel is connecting.
zhihuangd06adf62017-01-12 15:58:31 -08004323 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Seth Hampson98335f82019-02-22 17:50:03 -08004324 // No connections are writable yet, so we should still be in the kChecking
4325 // state.
4326 EXPECT_EQ(webrtc::IceTransportState::kChecking, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004327 // |conn1| becomes writable and receiving; it then should prune |conn2|.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004328 conn1->ReceivedPingResponse(LOW_RTT, "id");
honghaize58d73d2016-10-24 16:38:26 -07004329 EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004330 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Seth Hampson98335f82019-02-22 17:50:03 -08004331 EXPECT_EQ(webrtc::IceTransportState::kConnected, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004332 conn1->Prune(); // All connections are pruned.
Honghai Zhang381b4212015-12-04 12:24:03 -08004333 // Need to wait until the channel state is updated.
zhihuangd06adf62017-01-12 15:58:31 -08004334 EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
honghaize58d73d2016-10-24 16:38:26 -07004335 kShortTimeout, clock);
Jonas Olsson81125f02018-10-09 10:52:04 +02004336 EXPECT_EQ(webrtc::IceTransportState::kFailed, ch.GetIceTransportState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004337}
4338
4339// Test that when a low-priority connection is pruned, it is not deleted
4340// right away, and it can become active and be pruned again.
4341TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
Honghai Zhange05bcc22016-08-16 18:19:14 -07004342 rtc::ScopedFakeClock clock;
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004343 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
honghaize58d73d2016-10-24 16:38:26 -07004344
deadbeef14f97f52016-06-22 17:14:15 -07004345 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4346 P2PTransportChannel ch("test channel", 1, &pa);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004347 PrepareChannel(&ch);
honghaiz9ad0db52016-07-14 19:30:28 -07004348 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
Oskar Sundbom903dcd72017-11-16 10:55:57 +01004349 config.receiving_switching_delay = 800;
honghaiz9ad0db52016-07-14 19:30:28 -07004350 ch.SetIceConfig(config);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004351 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004352 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004353 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004354 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004355 EXPECT_EQ(nullptr, ch.selected_connection());
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004356 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
Honghai Zhange05bcc22016-08-16 18:19:14 -07004357 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4358 clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004359
4360 // Add a low-priority connection |conn2|, which will be pruned, but it will
Honghai Zhang572b0942016-06-23 12:26:57 -07004361 // not be deleted right away. Once the current selected connection becomes not
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004362 // receiving, |conn2| will start to ping and upon receiving the ping response,
Honghai Zhang572b0942016-06-23 12:26:57 -07004363 // it will become the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004364 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
Honghai Zhange05bcc22016-08-16 18:19:14 -07004365 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004366 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhange05bcc22016-08-16 18:19:14 -07004367 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004368 // |conn2| should not send a ping yet.
hbos06495bc2017-01-02 08:08:18 -08004369 EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
zhihuangd06adf62017-01-12 15:58:31 -08004370 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004371 // Wait for |conn1| becoming not receiving.
Honghai Zhang161a5862016-10-20 11:47:02 -07004372 EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004373 // Make sure conn2 is not deleted.
Honghai Zhange05bcc22016-08-16 18:19:14 -07004374 conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004375 ASSERT_TRUE(conn2 != nullptr);
hbos06495bc2017-01-02 08:08:18 -08004376 EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
Honghai Zhange05bcc22016-08-16 18:19:14 -07004377 kDefaultTimeout, clock);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004378 conn2->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004379 EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
4380 clock);
zhihuangd06adf62017-01-12 15:58:31 -08004381 EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004382
4383 // When |conn1| comes back again, |conn2| will be pruned again.
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004384 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhange05bcc22016-08-16 18:19:14 -07004385 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
4386 clock);
4387 EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
zhihuangd06adf62017-01-12 15:58:31 -08004388 EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
Honghai Zhang2b342bf2015-09-30 09:51:58 -07004389}
honghaiz77d0d6e2015-10-27 11:34:45 -07004390
4391// Test that if all connections in a channel has timed out on writing, they
4392// will all be deleted. We use Prune to simulate write_time_out.
4393TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
honghaize58d73d2016-10-24 16:38:26 -07004394 rtc::ScopedFakeClock clock;
deadbeef14f97f52016-06-22 17:14:15 -07004395 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4396 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz77d0d6e2015-10-27 11:34:45 -07004397 PrepareChannel(&ch);
honghaiz77d0d6e2015-10-27 11:34:45 -07004398 ch.MaybeStartGathering();
4399 // Have one connection only but later becomes write-time-out.
deadbeef14f97f52016-06-22 17:14:15 -07004400 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
honghaize58d73d2016-10-24 16:38:26 -07004401 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004402 ASSERT_TRUE(conn1 != nullptr);
4403 conn1->ReceivedPing(); // Becomes receiving
4404 conn1->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004405 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004406
4407 // Have two connections but both become write-time-out later.
deadbeef14f97f52016-06-22 17:14:15 -07004408 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
honghaize58d73d2016-10-24 16:38:26 -07004409 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004410 ASSERT_TRUE(conn2 != nullptr);
4411 conn2->ReceivedPing(); // Becomes receiving
deadbeef14f97f52016-06-22 17:14:15 -07004412 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
honghaize58d73d2016-10-24 16:38:26 -07004413 Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004414 ASSERT_TRUE(conn3 != nullptr);
4415 conn3->ReceivedPing(); // Becomes receiving
4416 // Now prune both conn2 and conn3; they will be deleted soon.
4417 conn2->Prune();
4418 conn3->Prune();
honghaize58d73d2016-10-24 16:38:26 -07004419 EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
honghaiz77d0d6e2015-10-27 11:34:45 -07004420}
honghaiz9b669572015-11-04 12:07:44 -08004421
Honghai Zhang5a246372016-05-02 17:28:35 -07004422// Tests that after a port allocator session is started, it will be stopped
4423// when a new connection becomes writable and receiving. Also tests that if a
4424// connection belonging to an old session becomes writable, it won't stop
4425// the current port allocator session.
honghaiz9b669572015-11-04 12:07:44 -08004426TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
deadbeef14f97f52016-06-22 17:14:15 -07004427 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4428 P2PTransportChannel ch("test channel", 1, &pa);
honghaiz9b669572015-11-04 12:07:44 -08004429 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004430 ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
honghaiz9b669572015-11-04 12:07:44 -08004431 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004432 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
4433 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
honghaiz9b669572015-11-04 12:07:44 -08004434 ASSERT_TRUE(conn1 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004435 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004436 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4437
Honghai Zhang5a246372016-05-02 17:28:35 -07004438 // Start a new session. Even though conn1, which belongs to an older
4439 // session, becomes unwritable and writable again, it should not stop the
4440 // current session.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004441 ch.SetIceParameters(kIceParams[1]);
honghaiz9b669572015-11-04 12:07:44 -08004442 ch.MaybeStartGathering();
Honghai Zhang5a246372016-05-02 17:28:35 -07004443 conn1->Prune();
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004444 conn1->ReceivedPingResponse(LOW_RTT, "id");
Honghai Zhang5a246372016-05-02 17:28:35 -07004445 EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());
4446
4447 // But if a new connection created from the new session becomes writable,
4448 // it will stop the current session.
deadbeef14f97f52016-06-22 17:14:15 -07004449 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
4450 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
honghaiz9b669572015-11-04 12:07:44 -08004451 ASSERT_TRUE(conn2 != nullptr);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004452 conn2->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
honghaiz9b669572015-11-04 12:07:44 -08004453 EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
4454}
guoweis36f01372016-03-02 18:02:40 -08004455
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004456// Test that the ICE role is updated even on ports that has been removed.
4457// These ports may still have connections that need a correct role, in case that
4458// the connections on it may still receive stun pings.
4459TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
deadbeef14f97f52016-06-22 17:14:15 -07004460 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4461 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004462 // Starts with ICEROLE_CONTROLLING.
4463 PrepareChannel(&ch);
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004464 IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
deadbeefdfc42442016-06-21 14:19:48 -07004465 ch.SetIceConfig(config);
deadbeefdfc42442016-06-21 14:19:48 -07004466 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004467 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004468
deadbeef14f97f52016-06-22 17:14:15 -07004469 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004470 ASSERT_TRUE(conn != nullptr);
4471
Honghai Zhang5622c5e2016-07-01 13:59:29 -07004472 // Make a fake signal to remove the ports in the p2ptransportchannel. then
4473 // change the ICE role and expect it to be updated.
4474 std::vector<PortInterface*> ports(1, conn->port());
Honghai Zhang8eeecab2016-07-28 13:20:15 -07004475 ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
deadbeef14f97f52016-06-22 17:14:15 -07004476 ch.SetIceRole(ICEROLE_CONTROLLED);
4477 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004478}
4479
4480// Test that the ICE role is updated even on ports with inactive networks.
4481// These ports may still have connections that need a correct role, for the
4482// pings sent by those connections until they're replaced by newer-generation
4483// connections.
4484TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
deadbeef14f97f52016-06-22 17:14:15 -07004485 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4486 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004487 // Starts with ICEROLE_CONTROLLING.
4488 PrepareChannel(&ch);
deadbeefdfc42442016-06-21 14:19:48 -07004489 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004490 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004491
deadbeef14f97f52016-06-22 17:14:15 -07004492 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004493 ASSERT_TRUE(conn != nullptr);
4494
4495 // Do an ICE restart, change the role, and expect the old port to have its
4496 // role updated.
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07004497 ch.SetIceParameters(kIceParams[1]);
deadbeefdfc42442016-06-21 14:19:48 -07004498 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004499 ch.SetIceRole(ICEROLE_CONTROLLED);
4500 EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
deadbeefdfc42442016-06-21 14:19:48 -07004501}
4502
4503// Test that after some amount of time without receiving data, the connection
Honghai Zhanga74363c2016-07-28 18:06:15 -07004504// will be destroyed. The port will only be destroyed after it is marked as
4505// "pruned."
4506TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
deadbeefdfc42442016-06-21 14:19:48 -07004507 rtc::ScopedFakeClock fake_clock;
4508
deadbeef14f97f52016-06-22 17:14:15 -07004509 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4510 P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
deadbeefdfc42442016-06-21 14:19:48 -07004511 PrepareChannel(&ch);
deadbeef14f97f52016-06-22 17:14:15 -07004512 ch.SetIceRole(ICEROLE_CONTROLLED);
deadbeefdfc42442016-06-21 14:19:48 -07004513 ch.MaybeStartGathering();
deadbeef14f97f52016-06-22 17:14:15 -07004514 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
deadbeefdfc42442016-06-21 14:19:48 -07004515
deadbeef14f97f52016-06-22 17:14:15 -07004516 Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
deadbeefdfc42442016-06-21 14:19:48 -07004517 ASSERT_TRUE(conn != nullptr);
4518
4519 // Simulate 2 minutes going by. This should be enough time for the port to
4520 // time out.
4521 for (int second = 0; second < 120; ++second) {
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004522 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeefdfc42442016-06-21 14:19:48 -07004523 }
4524 EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
Honghai Zhanga74363c2016-07-28 18:06:15 -07004525 // Port will not be removed because it is not pruned yet.
sprang716978d2016-10-11 06:43:28 -07004526 PortInterface* port = GetPort(&ch);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004527 ASSERT_NE(nullptr, port);
4528
4529 // If the session prunes all ports, the port will be destroyed.
4530 ch.allocator_session()->PruneAllPorts();
sprang716978d2016-10-11 06:43:28 -07004531 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
Honghai Zhanga74363c2016-07-28 18:06:15 -07004532 EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
deadbeefdfc42442016-06-21 14:19:48 -07004533}
4534
Jonas Orelandc6404a12019-10-14 15:52:15 +02004535TEST_F(P2PTransportChannelPingTest, TestMaxOutstandingPingsFieldTrial) {
4536 webrtc::test::ScopedFieldTrials field_trials(
4537 "WebRTC-IceFieldTrials/max_outstanding_pings:3/");
4538 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
4539 P2PTransportChannel ch("max", 1, &pa);
4540 ch.SetIceConfig(ch.config());
4541 PrepareChannel(&ch);
4542 ch.MaybeStartGathering();
4543 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
4544 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
4545
4546 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4547 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4548 ASSERT_TRUE(conn1 != nullptr);
4549 ASSERT_TRUE(conn2 != nullptr);
4550
4551 EXPECT_TRUE_WAIT(conn1->num_pings_sent() == 3 && conn2->num_pings_sent() == 3,
4552 kDefaultTimeout);
4553
4554 // Check that these connections don't send any more pings.
4555 EXPECT_EQ(nullptr, ch.FindNextPingableConnection());
4556}
4557
guoweis36f01372016-03-02 18:02:40 -08004558class P2PTransportChannelMostLikelyToWorkFirstTest
4559 : public P2PTransportChannelPingTest {
4560 public:
4561 P2PTransportChannelMostLikelyToWorkFirstTest()
4562 : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
4563 network_manager_.AddInterface(kPublicAddrs[0]);
Honghai Zhangb73d2692016-09-29 22:46:09 -07004564 allocator_.reset(
4565 CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
4566 kTurnUdpIntAddr, rtc::SocketAddress()));
deadbeef14f97f52016-06-22 17:14:15 -07004567 allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
4568 PORTALLOCATOR_DISABLE_TCP);
guoweis36f01372016-03-02 18:02:40 -08004569 allocator_->set_step_delay(kMinimumStepDelay);
4570 }
4571
deadbeef14f97f52016-06-22 17:14:15 -07004572 P2PTransportChannel& StartTransportChannel(
guoweis36f01372016-03-02 18:02:40 -08004573 bool prioritize_most_likely_to_work,
zhihuang435264a2016-06-21 11:28:38 -07004574 int stable_writable_connection_ping_interval) {
deadbeef49f34fd2016-12-06 16:22:06 -08004575 channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
deadbeef14f97f52016-06-22 17:14:15 -07004576 IceConfig config = channel_->config();
guoweis36f01372016-03-02 18:02:40 -08004577 config.prioritize_most_likely_candidate_pairs =
4578 prioritize_most_likely_to_work;
zhihuang435264a2016-06-21 11:28:38 -07004579 config.stable_writable_connection_ping_interval =
4580 stable_writable_connection_ping_interval;
guoweis36f01372016-03-02 18:02:40 -08004581 channel_->SetIceConfig(config);
4582 PrepareChannel(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004583 channel_->MaybeStartGathering();
4584 return *channel_.get();
4585 }
4586
deadbeef14f97f52016-06-22 17:14:15 -07004587 BasicPortAllocator* allocator() { return allocator_.get(); }
4588 TestTurnServer* turn_server() { return &turn_server_; }
guoweis36f01372016-03-02 18:02:40 -08004589
4590 // This verifies the next pingable connection has the expected candidates'
4591 // types and, for relay local candidate, the expected relay protocol and ping
4592 // it.
4593 void VerifyNextPingableConnection(
4594 const std::string& local_candidate_type,
4595 const std::string& remote_candidate_type,
deadbeef14f97f52016-06-22 17:14:15 -07004596 const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
4597 Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
guoweis36f01372016-03-02 18:02:40 -08004598 EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
deadbeef14f97f52016-06-22 17:14:15 -07004599 if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
guoweis36f01372016-03-02 18:02:40 -08004600 EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
4601 }
4602 EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
4603 }
4604
guoweis36f01372016-03-02 18:02:40 -08004605 private:
deadbeef14f97f52016-06-22 17:14:15 -07004606 std::unique_ptr<BasicPortAllocator> allocator_;
guoweis36f01372016-03-02 18:02:40 -08004607 rtc::FakeNetworkManager network_manager_;
deadbeef14f97f52016-06-22 17:14:15 -07004608 TestTurnServer turn_server_;
4609 std::unique_ptr<P2PTransportChannel> channel_;
guoweis36f01372016-03-02 18:02:40 -08004610};
4611
4612// Test that Relay/Relay connections will be pinged first when no other
4613// connections have been pinged yet, unless we need to ping a trigger check or
Honghai Zhang572b0942016-06-23 12:26:57 -07004614// we have a selected connection.
guoweis36f01372016-03-02 18:02:40 -08004615TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4616 TestRelayRelayFirstWhenNothingPingedYet) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004617 const int max_strong_interval = 500;
deadbeef14f97f52016-06-22 17:14:15 -07004618 P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
Honghai Zhang161a5862016-10-20 11:47:02 -07004619 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004620 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4621 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004622
deadbeef14f97f52016-06-22 17:14:15 -07004623 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4624 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
guoweis36f01372016-03-02 18:02:40 -08004625
Honghai Zhang161a5862016-10-20 11:47:02 -07004626 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004627
4628 // Relay/Relay should be the first pingable connection.
deadbeef14f97f52016-06-22 17:14:15 -07004629 Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
4630 EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
4631 EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004632
4633 // Unless that we have a trigger check waiting to be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004634 Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
4635 EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
4636 EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004637 conn2->ReceivedPing();
4638 EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
4639
Honghai Zhang572b0942016-06-23 12:26:57 -07004640 // Make conn3 the selected connection.
deadbeef14f97f52016-06-22 17:14:15 -07004641 Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
4642 EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
4643 EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004644 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004645 ASSERT_TRUE(conn3->writable());
4646 conn3->ReceivedPing();
4647
honghaiz524ecc22016-05-25 12:48:31 -07004648 /*
4649
4650 TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
4651 the flakiness. The following test becomes flaky because we now ping the
4652 connections with fast rates until every connection is pinged at least three
Honghai Zhang572b0942016-06-23 12:26:57 -07004653 times. The selected connection may have been pinged before
4654 |max_strong_interval|, so it may not be the next connection to be pinged as
4655 expected in the test.
honghaiz524ecc22016-05-25 12:48:31 -07004656
Honghai Zhang572b0942016-06-23 12:26:57 -07004657 // Verify that conn3 will be the "selected connection" since it is readable
4658 // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
Honghai Zhang049fbb12016-03-07 11:13:07 -08004659 // pingable connection.
Honghai Zhang161a5862016-10-20 11:47:02 -07004660 EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
Honghai Zhang049fbb12016-03-07 11:13:07 -08004661 WAIT(false, max_strong_interval + 100);
Honghai Zhang8cd8f812016-08-03 19:50:41 -07004662 conn3->ReceivedPingResponse(LOW_RTT, "id");
guoweis36f01372016-03-02 18:02:40 -08004663 ASSERT_TRUE(conn3->writable());
4664 EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));
honghaiz524ecc22016-05-25 12:48:31 -07004665
4666 */
guoweis36f01372016-03-02 18:02:40 -08004667}
4668
4669// Test that Relay/Relay connections will be pinged first when everything has
4670// been pinged even if the Relay/Relay connection wasn't the first to be pinged
4671// in the first round.
4672TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4673 TestRelayRelayFirstWhenEverythingPinged) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004674 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004675 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004676 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4677 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004678
deadbeef14f97f52016-06-22 17:14:15 -07004679 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004680 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004681
4682 // Initially, only have Local/Local and Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004683 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
4684 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004685
4686 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004687 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004688 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004689
4690 // Relay/Relay should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004691 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004692
4693 // Local/Relay is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004694 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004695
4696 // Now, every connection has been pinged once. The next one should be
4697 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004698 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004699}
4700
4701// Test that when we receive a new remote candidate, they will be tried first
4702// before we re-ping Relay/Relay connections again.
4703TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4704 TestNoStarvationOnNonRelayConnection) {
Qingsi Wangdea68892018-03-27 10:55:21 -07004705 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004706 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004707 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4708 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004709
deadbeef14f97f52016-06-22 17:14:15 -07004710 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004711 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004712
4713 // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
deadbeef14f97f52016-06-22 17:14:15 -07004714 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004715
4716 // Next, ping Local/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004717 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004718
4719 // Remote Local candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004720 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
Honghai Zhang161a5862016-10-20 11:47:02 -07004721 EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004722
4723 // Local/Local should be the first since it hasn't been pinged before.
deadbeef14f97f52016-06-22 17:14:15 -07004724 VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004725
4726 // Relay/Local is the final one.
deadbeef14f97f52016-06-22 17:14:15 -07004727 VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004728
4729 // Now, every connection has been pinged once. The next one should be
4730 // Relay/Relay.
deadbeef14f97f52016-06-22 17:14:15 -07004731 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004732}
4733
Jonas Oreland4af78822019-10-11 08:17:06 +02004734// Test skip_relay_to_non_relay_connections field-trial.
4735// I.e that we never create connection between relay and non-relay.
4736TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
4737 TestSkipRelayToNonRelayConnectionsFieldTrial) {
4738 webrtc::test::ScopedFieldTrials field_trials(
4739 "WebRTC-IceFieldTrials/skip_relay_to_non_relay_connections:true/");
4740 P2PTransportChannel& ch = StartTransportChannel(true, 500);
4741 EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
4742 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4743 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4744
4745 // Remote Relay candidate arrives.
4746 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
4747 EXPECT_TRUE_WAIT(ch.connections().size() == 1, kDefaultTimeout);
4748
4749 // Remote Local candidate arrives.
4750 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
4751 EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
4752}
4753
guoweis36f01372016-03-02 18:02:40 -08004754// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
4755// followed by the rest.
4756TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
4757 // Add a Tcp Turn server.
deadbeef14f97f52016-06-22 17:14:15 -07004758 turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
Niels Möller191e38f2019-11-04 08:49:12 +01004759 RelayServerConfig config;
guoweis36f01372016-03-02 18:02:40 -08004760 config.credentials = kRelayCredentials;
hnsl277b2502016-12-13 05:17:23 -08004761 config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
guoweis36f01372016-03-02 18:02:40 -08004762 allocator()->AddTurnServer(config);
4763
Qingsi Wangdea68892018-03-27 10:55:21 -07004764 P2PTransportChannel& ch = StartTransportChannel(true, 500);
Honghai Zhang161a5862016-10-20 11:47:02 -07004765 EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
deadbeef14f97f52016-06-22 17:14:15 -07004766 EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
4767 EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
4768 EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004769
4770 // Remote Relay candidate arrives.
deadbeef14f97f52016-06-22 17:14:15 -07004771 ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
Honghai Zhang161a5862016-10-20 11:47:02 -07004772 EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
guoweis36f01372016-03-02 18:02:40 -08004773
4774 // UDP Relay/Relay should be pinged first.
deadbeef14f97f52016-06-22 17:14:15 -07004775 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004776
4777 // TCP Relay/Relay is the next.
deadbeef14f97f52016-06-22 17:14:15 -07004778 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
4779 TCP_PROTOCOL_NAME);
guoweis36f01372016-03-02 18:02:40 -08004780
4781 // Finally, Local/Relay will be pinged.
deadbeef14f97f52016-06-22 17:14:15 -07004782 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
guoweis36f01372016-03-02 18:02:40 -08004783}
deadbeef14f97f52016-06-22 17:14:15 -07004784
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004785// Test that a resolver is created, asked for a result, and destroyed
Zach Stein5ec2c942018-11-27 16:58:08 -08004786// when the address is a hostname. The destruction should happen even
4787// if the channel is not destroyed.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004788TEST(P2PTransportChannelResolverTest, HostnameCandidateIsResolved) {
4789 rtc::MockAsyncResolver mock_async_resolver;
4790 EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
4791 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4792 .WillOnce(Return(true));
Zach Stein5ec2c942018-11-27 16:58:08 -08004793 // Destroy is called asynchronously after the address is resolved,
4794 // so we need a variable to wait on.
4795 bool destroy_called = false;
4796 EXPECT_CALL(mock_async_resolver, Destroy(_))
4797 .WillOnce(Assign(&destroy_called, true));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004798 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4799 EXPECT_CALL(mock_async_resolver_factory, Create())
4800 .WillOnce(Return(&mock_async_resolver));
4801
Qingsi Wangc129c352019-04-18 10:41:58 -07004802 FakePortAllocator allocator(rtc::Thread::Current(), nullptr);
4803 P2PTransportChannel channel("tn", 0, &allocator,
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004804 &mock_async_resolver_factory);
4805 Candidate hostname_candidate;
4806 SocketAddress hostname_address("fake.test", 1000);
4807 hostname_candidate.set_address(hostname_address);
4808 channel.AddRemoteCandidate(hostname_candidate);
4809
4810 ASSERT_EQ_WAIT(1u, channel.remote_candidates().size(), kDefaultTimeout);
4811 const RemoteCandidate& candidate = channel.remote_candidates()[0];
4812 EXPECT_FALSE(candidate.address().IsUnresolvedIP());
Zach Stein5ec2c942018-11-27 16:58:08 -08004813 WAIT(destroy_called, kShortTimeout);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004814}
4815
Qingsi Wang09619332018-09-12 22:51:55 -07004816// Test that if we signal a hostname candidate after the remote endpoint
4817// discovers a prflx remote candidate with the same underlying IP address, the
4818// prflx candidate is updated to a host candidate after the name resolution is
4819// done.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004820TEST_F(P2PTransportChannelTest,
Qingsi Wang7852d292018-10-31 11:17:07 -07004821 PeerReflexiveCandidateBeforeSignalingWithMdnsName) {
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004822 rtc::MockAsyncResolver mock_async_resolver;
4823 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4824 EXPECT_CALL(mock_async_resolver_factory, Create())
4825 .WillOnce(Return(&mock_async_resolver));
4826
Qingsi Wang09619332018-09-12 22:51:55 -07004827 // ep1 and ep2 will only gather host candidates with addresses
4828 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004829 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
Qingsi Wang09619332018-09-12 22:51:55 -07004830 // ICE parameter will be set up when creating the channels.
4831 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004832 GetEndpoint(0)->network_manager_.set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004833 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004834 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004835 CreateChannels();
Qingsi Wang09619332018-09-12 22:51:55 -07004836 // Pause sending candidates from both endpoints until we find out what port
4837 // number is assgined to ep1's host candidate.
4838 PauseCandidates(0);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004839 PauseCandidates(1);
Qingsi Wang09619332018-09-12 22:51:55 -07004840 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4841 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
4842 const auto& local_candidate =
4843 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4844 // The IP address of ep1's host candidate should be obfuscated.
4845 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
4846 // This is the underlying private IP address of the same candidate at ep1.
4847 const auto local_address = rtc::SocketAddress(
4848 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
4849 // Let ep2 signal its candidate to ep1. ep1 should form a candidate
4850 // pair and start to ping. After receiving the ping, ep2 discovers a prflx
4851 // remote candidate and form a candidate pair as well.
4852 ResumeCandidates(1);
4853 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
4854 // ep2 should have the selected connection connected to the prflx remote
4855 // candidate.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004856 const Connection* selected_connection = nullptr;
4857 ASSERT_TRUE_WAIT(
Qingsi Wang09619332018-09-12 22:51:55 -07004858 (selected_connection = ep2_ch1()->selected_connection()) != nullptr,
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004859 kMediumTimeout);
4860 EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
Qingsi Wang09619332018-09-12 22:51:55 -07004861 EXPECT_EQ(kIceUfrag[0], selected_connection->remote_candidate().username());
4862 EXPECT_EQ(kIcePwd[0], selected_connection->remote_candidate().password());
4863 // Set expectation before ep1 signals a hostname candidate.
4864 {
4865 InSequence sequencer;
4866 EXPECT_CALL(mock_async_resolver, Start(_));
4867 EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
4868 // Let the mock resolver of ep2 receives the correct resolution.
4869 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4870 .WillOnce(DoAll(SetArgPointee<1>(local_address), Return(true)));
4871 }
Zach Stein5ec2c942018-11-27 16:58:08 -08004872 // Destroy is called asynchronously after the address is resolved,
4873 // so we need a variable to wait on.
4874 bool destroy_called = false;
4875 EXPECT_CALL(mock_async_resolver, Destroy(_))
4876 .WillOnce(Assign(&destroy_called, true));
Qingsi Wang09619332018-09-12 22:51:55 -07004877 ResumeCandidates(0);
4878 // Verify ep2's selected connection is updated to use the 'local' candidate.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004879 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
Qingsi Wang09619332018-09-12 22:51:55 -07004880 ep2_ch1()->selected_connection()->remote_candidate().type(),
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004881 kMediumTimeout);
Qingsi Wang09619332018-09-12 22:51:55 -07004882 EXPECT_EQ(selected_connection, ep2_ch1()->selected_connection());
4883
Zach Stein5ec2c942018-11-27 16:58:08 -08004884 WAIT(destroy_called, kShortTimeout);
Qingsi Wang09619332018-09-12 22:51:55 -07004885 DestroyChannels();
4886}
4887
4888// Test that if we discover a prflx candidate during the process of name
4889// resolution for a remote hostname candidate, we update the prflx candidate to
4890// a host candidate if the hostname candidate turns out to have the same IP
4891// address after the resolution completes.
4892TEST_F(P2PTransportChannelTest,
Qingsi Wang7852d292018-10-31 11:17:07 -07004893 PeerReflexiveCandidateDuringResolvingHostCandidateWithMdnsName) {
Qingsi Wang09619332018-09-12 22:51:55 -07004894 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
4895 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4896 EXPECT_CALL(mock_async_resolver_factory, Create())
4897 .WillOnce(Return(&mock_async_resolver));
4898
4899 // ep1 and ep2 will only gather host candidates with addresses
4900 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
4901 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
4902 // ICE parameter will be set up when creating the channels.
4903 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004904 GetEndpoint(0)->network_manager_.set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004905 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004906 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
4907 CreateChannels();
4908 // Pause sending candidates from both endpoints until we find out what port
4909 // number is assgined to ep1's host candidate.
4910 PauseCandidates(0);
4911 PauseCandidates(1);
4912 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4913 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
4914 const auto& local_candidate =
4915 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4916 // The IP address of ep1's host candidate should be obfuscated.
4917 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
4918 // This is the underlying private IP address of the same candidate at ep1.
4919 const auto local_address = rtc::SocketAddress(
4920 kPublicAddrs[0].ipaddr(), local_candidate.address().port());
4921 bool mock_async_resolver_started = false;
4922 // Not signaling done yet, and only make sure we are in the process of
4923 // resolution.
4924 EXPECT_CALL(mock_async_resolver, Start(_))
4925 .WillOnce(InvokeWithoutArgs([&mock_async_resolver_started]() {
4926 mock_async_resolver_started = true;
4927 }));
4928 // Let ep1 signal its hostname candidate to ep2.
4929 ResumeCandidates(0);
4930 EXPECT_TRUE_WAIT(mock_async_resolver_started, kMediumTimeout);
4931 // Now that ep2 is in the process of resolving the hostname candidate signaled
4932 // by ep1. Let ep2 signal its host candidate with an IP address to ep1, so
4933 // that ep1 can form a candidate pair, select it and start to ping ep2.
4934 ResumeCandidates(1);
4935 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kMediumTimeout);
4936 // Let the mock resolver of ep2 receives the correct resolution.
4937 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
4938 .WillOnce(DoAll(SetArgPointee<1>(local_address), Return(true)));
4939 // Upon receiving a ping from ep1, ep2 adds a prflx candidate from the
4940 // unknown address and establishes a connection.
4941 //
4942 // There is a caveat in our implementation associated with this expectation.
4943 // See the big comment in P2PTransportChannel::OnUnknownAddress.
4944 ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
4945 EXPECT_EQ(PRFLX_PORT_TYPE,
4946 ep2_ch1()->selected_connection()->remote_candidate().type());
4947 // ep2 should also be able resolve the hostname candidate. The resolved remote
4948 // host candidate should be merged with the prflx remote candidate.
4949 mock_async_resolver.SignalDone(&mock_async_resolver);
4950 EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
4951 ep2_ch1()->selected_connection()->remote_candidate().type(),
4952 kMediumTimeout);
4953 EXPECT_EQ(1u, ep2_ch1()->remote_candidates().size());
4954
4955 DestroyChannels();
4956}
4957
4958// Test that if we only gather and signal a host candidate, the IP address of
4959// which is obfuscated by an mDNS name, and if the peer can complete the name
4960// resolution with the correct IP address, we can have a p2p connection.
Qingsi Wang7852d292018-10-31 11:17:07 -07004961TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) {
Qingsi Wang09619332018-09-12 22:51:55 -07004962 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
4963 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
4964 EXPECT_CALL(mock_async_resolver_factory, Create())
4965 .WillOnce(Return(&mock_async_resolver));
4966
4967 // ep1 and ep2 will only gather host candidates with addresses
4968 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
4969 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
4970 // ICE parameter will be set up when creating the channels.
4971 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07004972 GetEndpoint(0)->network_manager_.set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004973 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang09619332018-09-12 22:51:55 -07004974 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
4975 CreateChannels();
4976 // Pause sending candidates from both endpoints until we find out what port
4977 // number is assgined to ep1's host candidate.
4978 PauseCandidates(0);
4979 PauseCandidates(1);
4980 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
4981 ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size());
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004982 const auto& local_candidate_ep1 =
Qingsi Wang09619332018-09-12 22:51:55 -07004983 GetEndpoint(0)->saved_candidates_[0]->candidates[0];
4984 // The IP address of ep1's host candidate should be obfuscated.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004985 EXPECT_TRUE(local_candidate_ep1.address().IsUnresolvedIP());
Qingsi Wang09619332018-09-12 22:51:55 -07004986 // This is the underlying private IP address of the same candidate at ep1,
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004987 // and let the mock resolver of ep2 receive the correct resolution.
4988 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
4989 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
Qingsi Wang09619332018-09-12 22:51:55 -07004990
4991 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004992 .WillOnce(DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true)));
Qingsi Wang09619332018-09-12 22:51:55 -07004993 // Let ep1 signal its hostname candidate to ep2.
4994 ResumeCandidates(0);
4995
4996 // We should be able to receive a ping from ep2 and establish a connection
4997 // with a peer reflexive candidate from ep2.
4998 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
4999 kMediumTimeout);
Qingsi Wangb49b8f12018-09-16 17:48:10 -07005000 EXPECT_EQ(LOCAL_PORT_TYPE,
5001 ep1_ch1()->selected_connection()->local_candidate().type());
Qingsi Wang09619332018-09-12 22:51:55 -07005002 EXPECT_EQ(PRFLX_PORT_TYPE,
5003 ep1_ch1()->selected_connection()->remote_candidate().type());
5004
Zach Stein6fcdc2f2018-08-23 16:25:55 -07005005 DestroyChannels();
5006}
5007
Qingsi Wang1dac6d82018-12-12 15:28:47 -08005008// Test that when the IP of a host candidate is concealed by an mDNS name, the
5009// stats from the gathering ICE endpoint do not reveal the address of this local
5010// host candidate or the related address of a local srflx candidate from the
5011// same endpoint. Also, the remote ICE endpoint that successfully resolves a
5012// signaled host candidate with an mDNS name should not reveal the address of
5013// this remote host candidate in stats.
5014TEST_F(P2PTransportChannelTest,
5015 CandidatesSanitizedInStatsWhenMdnsObfuscationEnabled) {
5016 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
5017 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
5018 EXPECT_CALL(mock_async_resolver_factory, Create())
5019 .WillOnce(Return(&mock_async_resolver));
5020
5021 // ep1 and ep2 will gather host candidates with addresses
5022 // kPublicAddrs[0] and kPublicAddrs[1], respectively. ep1 also gathers a srflx
5023 // and a relay candidates.
5024 ConfigureEndpoints(OPEN, OPEN,
5025 kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_TCP,
5026 kOnlyLocalPorts);
5027 // ICE parameter will be set up when creating the channels.
5028 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
Qingsi Wangecd30542019-05-22 14:34:56 -07005029 GetEndpoint(0)->network_manager_.set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005030 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08005031 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
5032 CreateChannels();
5033 // Pause sending candidates from both endpoints until we find out what port
5034 // number is assigned to ep1's host candidate.
5035 PauseCandidates(0);
5036 PauseCandidates(1);
5037 // Ep1 has a UDP host, a srflx and a relay candidates.
5038 ASSERT_EQ_WAIT(3u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5039 ASSERT_EQ_WAIT(1u, GetEndpoint(1)->saved_candidates_.size(), kMediumTimeout);
5040
5041 for (const auto& candidates_data : GetEndpoint(0)->saved_candidates_) {
5042 ASSERT_EQ(1u, candidates_data->candidates.size());
5043 const auto& local_candidate_ep1 = candidates_data->candidates[0];
5044 if (local_candidate_ep1.type() == LOCAL_PORT_TYPE) {
5045 // This is the underlying private IP address of the same candidate at ep1,
5046 // and let the mock resolver of ep2 receive the correct resolution.
5047 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
5048 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
5049 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
5050 .WillOnce(
5051 DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true)));
5052 break;
5053 }
5054 }
5055 ResumeCandidates(0);
5056 ResumeCandidates(1);
5057
5058 ASSERT_EQ_WAIT(kIceGatheringComplete, ep1_ch1()->gathering_state(),
5059 kMediumTimeout);
5060 // We should have the following candidate pairs on both endpoints:
5061 // ep1_host <-> ep2_host, ep1_srflx <-> ep2_host, ep1_relay <-> ep2_host
5062 ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout);
5063 ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout);
5064
Jonas Oreland149dc722019-08-28 08:10:27 +02005065 IceTransportStats ice_transport_stats1;
5066 IceTransportStats ice_transport_stats2;
5067 ep1_ch1()->GetStats(&ice_transport_stats1);
5068 ep2_ch1()->GetStats(&ice_transport_stats2);
5069 EXPECT_EQ(3u, ice_transport_stats1.connection_infos.size());
5070 EXPECT_EQ(3u, ice_transport_stats1.candidate_stats_list.size());
5071 EXPECT_EQ(3u, ice_transport_stats2.connection_infos.size());
Qingsi Wang1dac6d82018-12-12 15:28:47 -08005072 // Check the stats of ep1 seen by ep1.
Jonas Oreland149dc722019-08-28 08:10:27 +02005073 for (const auto& connection_info : ice_transport_stats1.connection_infos) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08005074 const auto& local_candidate = connection_info.local_candidate;
5075 if (local_candidate.type() == LOCAL_PORT_TYPE) {
5076 EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
5077 } else if (local_candidate.type() == STUN_PORT_TYPE) {
5078 EXPECT_TRUE(local_candidate.related_address().IsAnyIP());
5079 } else if (local_candidate.type() == RELAY_PORT_TYPE) {
5080 // The related address of the relay candidate should be equal to the
5081 // srflx address. Note that NAT is not configured, hence the following
5082 // expectation.
5083 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
5084 local_candidate.related_address().ipaddr());
5085 } else {
5086 FAIL();
5087 }
5088 }
5089 // Check the stats of ep1 seen by ep2.
Jonas Oreland149dc722019-08-28 08:10:27 +02005090 for (const auto& connection_info : ice_transport_stats2.connection_infos) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08005091 const auto& remote_candidate = connection_info.remote_candidate;
5092 if (remote_candidate.type() == LOCAL_PORT_TYPE) {
5093 EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP());
5094 } else if (remote_candidate.type() == STUN_PORT_TYPE) {
5095 EXPECT_TRUE(remote_candidate.related_address().IsAnyIP());
5096 } else if (remote_candidate.type() == RELAY_PORT_TYPE) {
5097 EXPECT_EQ(kPublicAddrs[0].ipaddr(),
5098 remote_candidate.related_address().ipaddr());
5099 } else {
5100 FAIL();
5101 }
5102 }
5103 DestroyChannels();
5104}
5105
Jonas Oreland149dc722019-08-28 08:10:27 +02005106TEST_F(P2PTransportChannelTest,
5107 ConnectingIncreasesSelectedCandidatePairChanges) {
5108 rtc::ScopedFakeClock clock;
5109 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5110 kDefaultPortAllocatorFlags);
5111 CreateChannels();
5112
5113 IceTransportStats ice_transport_stats;
5114 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5115 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5116
5117 // Let the channels connect.
5118 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5119 kMediumTimeout, clock);
5120
5121 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5122 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5123
5124 DestroyChannels();
5125}
5126
5127TEST_F(P2PTransportChannelTest,
5128 DisconnectedIncreasesSelectedCandidatePairChanges) {
5129 rtc::ScopedFakeClock clock;
5130 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5131 kDefaultPortAllocatorFlags);
5132 CreateChannels();
5133
5134 IceTransportStats ice_transport_stats;
5135 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5136 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5137
5138 // Let the channels connect.
5139 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5140 kMediumTimeout, clock);
5141
5142 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5143 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5144
5145 // Prune connections and wait for disconnect.
5146 for (Connection* con : ep1_ch1()->connections()) {
5147 con->Prune();
5148 }
5149 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() == nullptr,
5150 kMediumTimeout, clock);
5151
5152 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5153 EXPECT_EQ(2u, ice_transport_stats.selected_candidate_pair_changes);
5154
5155 DestroyChannels();
5156}
5157
5158TEST_F(P2PTransportChannelTest,
5159 NewSelectionIncreasesSelectedCandidatePairChanges) {
5160 rtc::ScopedFakeClock clock;
5161 ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
5162 kDefaultPortAllocatorFlags);
5163 CreateChannels();
5164
5165 IceTransportStats ice_transport_stats;
5166 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5167 EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
5168
5169 // Let the channels connect.
5170 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5171 kMediumTimeout, clock);
5172
5173 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5174 EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
5175
5176 // Prune the currently selected connection and wait for selection
5177 // of a new one.
5178 const Connection* selected_connection = ep1_ch1()->selected_connection();
5179 for (Connection* con : ep1_ch1()->connections()) {
5180 if (con == selected_connection) {
5181 con->Prune();
5182 }
5183 }
5184 EXPECT_TRUE_SIMULATED_WAIT(
5185 ep1_ch1()->selected_connection() != nullptr &&
5186 (ep1_ch1()->GetStats(&ice_transport_stats),
5187 ice_transport_stats.selected_candidate_pair_changes >= 2u),
5188 kMediumTimeout, clock);
5189
5190 ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
5191 EXPECT_GE(ice_transport_stats.selected_candidate_pair_changes, 2u);
5192
5193 DestroyChannels();
5194}
5195
Qingsi Wange5defb12019-08-15 11:01:53 -07005196// A similar test as above to check the selected candidate pair is sanitized
5197// when it is queried via GetSelectedCandidatePair.
5198TEST_F(P2PTransportChannelTest,
5199 SelectedCandidatePairSanitizedWhenMdnsObfuscationEnabled) {
5200 NiceMock<rtc::MockAsyncResolver> mock_async_resolver;
5201 webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
5202 EXPECT_CALL(mock_async_resolver_factory, Create())
5203 .WillOnce(Return(&mock_async_resolver));
5204
5205 // ep1 and ep2 will gather host candidates with addresses
5206 // kPublicAddrs[0] and kPublicAddrs[1], respectively.
5207 ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
5208 // ICE parameter will be set up when creating the channels.
5209 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5210 GetEndpoint(0)->network_manager_.set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005211 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Qingsi Wange5defb12019-08-15 11:01:53 -07005212 GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory;
5213 CreateChannels();
5214 // Pause sending candidates from both endpoints until we find out what port
5215 // number is assigned to ep1's host candidate.
5216 PauseCandidates(0);
5217 PauseCandidates(1);
5218 ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout);
5219 const auto& candidates_data = GetEndpoint(0)->saved_candidates_[0];
5220 ASSERT_EQ(1u, candidates_data->candidates.size());
5221 const auto& local_candidate_ep1 = candidates_data->candidates[0];
5222 ASSERT_TRUE(local_candidate_ep1.type() == LOCAL_PORT_TYPE);
5223 // This is the underlying private IP address of the same candidate at ep1,
5224 // and let the mock resolver of ep2 receive the correct resolution.
5225 rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address());
5226 resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr());
5227 EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
5228 .WillOnce(DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true)));
5229 ResumeCandidates(0);
5230 ResumeCandidates(1);
5231
5232 ASSERT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr &&
5233 ep2_ch1()->selected_connection() != nullptr,
5234 kMediumTimeout);
5235
5236 const auto pair_ep1 = ep1_ch1()->GetSelectedCandidatePair();
5237 ASSERT_TRUE(pair_ep1.has_value());
5238 EXPECT_EQ(LOCAL_PORT_TYPE, pair_ep1->local_candidate().type());
5239 EXPECT_TRUE(pair_ep1->local_candidate().address().IsUnresolvedIP());
5240
5241 const auto pair_ep2 = ep2_ch1()->GetSelectedCandidatePair();
5242 ASSERT_TRUE(pair_ep2.has_value());
5243 EXPECT_EQ(LOCAL_PORT_TYPE, pair_ep2->remote_candidate().type());
5244 EXPECT_TRUE(pair_ep2->remote_candidate().address().IsUnresolvedIP());
5245
5246 DestroyChannels();
5247}
5248
Qingsi Wangfdf54f22019-10-18 15:51:40 -07005249TEST_F(P2PTransportChannelTest,
5250 NoPairOfLocalRelayCandidateWithRemoteMdnsCandidate) {
5251 const int kOnlyRelayPorts = cricket::PORTALLOCATOR_DISABLE_UDP |
5252 cricket::PORTALLOCATOR_DISABLE_STUN |
5253 cricket::PORTALLOCATOR_DISABLE_TCP;
5254 // We use one endpoint to test the behavior of adding remote candidates, and
5255 // this endpoint only gathers relay candidates.
5256 ConfigureEndpoints(OPEN, OPEN, kOnlyRelayPorts, kDefaultPortAllocatorFlags);
5257 GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
5258 0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
5259 IceConfig config;
5260 // Start gathering and we should have only a single relay port.
5261 ep1_ch1()->SetIceConfig(config);
5262 ep1_ch1()->MaybeStartGathering();
5263 EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
5264 ep1_ch1()->gathering_state(), kDefaultTimeout);
5265 EXPECT_EQ(1u, ep1_ch1()->ports().size());
5266 // Add a plain remote host candidate and three remote mDNS candidates with the
5267 // host, srflx and relay types. Note that the candidates differ in their
5268 // ports.
5269 cricket::Candidate host_candidate = CreateUdpCandidate(
5270 LOCAL_PORT_TYPE, "1.1.1.1", 1 /* port */, 0 /* priority */);
5271 ep1_ch1()->AddRemoteCandidate(host_candidate);
5272
5273 std::vector<cricket::Candidate> mdns_candidates;
5274 mdns_candidates.push_back(CreateUdpCandidate(LOCAL_PORT_TYPE, "example.local",
5275 2 /* port */, 0 /* priority */));
5276 mdns_candidates.push_back(CreateUdpCandidate(STUN_PORT_TYPE, "example.local",
5277 3 /* port */, 0 /* priority */));
5278 mdns_candidates.push_back(CreateUdpCandidate(RELAY_PORT_TYPE, "example.local",
5279 4 /* port */, 0 /* priority */));
5280 // We just resolve the hostname to 1.1.1.1, and add the candidates with this
5281 // address directly to simulate the process of adding remote candidates with
5282 // the name resolution.
5283 for (auto& mdns_candidate : mdns_candidates) {
5284 rtc::SocketAddress resolved_address(mdns_candidate.address());
5285 resolved_address.SetResolvedIP(0x1111); // 1.1.1.1
5286 mdns_candidate.set_address(resolved_address);
5287 EXPECT_FALSE(mdns_candidate.address().IsUnresolvedIP());
5288 ep1_ch1()->AddRemoteCandidate(mdns_candidate);
5289 }
5290
5291 // All remote candidates should have been successfully added.
5292 EXPECT_EQ(4u, ep1_ch1()->remote_candidates().size());
5293
5294 // Expect that there is no connection paired with any mDNS candidate.
5295 ASSERT_EQ(1u, ep1_ch1()->connections().size());
5296 ASSERT_NE(nullptr, ep1_ch1()->connections()[0]);
5297 EXPECT_EQ(
5298 "1.1.1.1:1",
5299 ep1_ch1()->connections()[0]->remote_candidate().address().ToString());
5300}
5301
Qingsi Wangecd30542019-05-22 14:34:56 -07005302class MockMdnsResponder : public webrtc::MdnsResponderInterface {
5303 public:
5304 MOCK_METHOD2(CreateNameForAddress,
5305 void(const rtc::IPAddress&, NameCreatedCallback));
5306 MOCK_METHOD2(RemoveNameForAddress,
5307 void(const rtc::IPAddress&, NameRemovedCallback));
5308};
5309
5310TEST_F(P2PTransportChannelTest,
5311 SrflxCandidateCanBeGatheredBeforeMdnsCandidateToCreateConnection) {
5312 // ep1 and ep2 will only gather host and srflx candidates with base addresses
5313 // kPublicAddrs[0] and kPublicAddrs[1], respectively, and we use a shared
5314 // socket in gathering.
5315 const auto kOnlyLocalAndStunPorts =
5316 cricket::PORTALLOCATOR_DISABLE_RELAY |
5317 cricket::PORTALLOCATOR_DISABLE_TCP |
5318 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET;
5319 // ep1 is configured with a NAT so that we do gather a srflx candidate.
5320 ConfigureEndpoints(NAT_FULL_CONE, OPEN, kOnlyLocalAndStunPorts,
5321 kOnlyLocalAndStunPorts);
5322 // ICE parameter will be set up when creating the channels.
5323 set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
5324 // Use a mock mDNS responder, which does not complete the name registration by
5325 // ignoring the completion callback.
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005326 auto mock_mdns_responder = std::make_unique<MockMdnsResponder>();
Qingsi Wangecd30542019-05-22 14:34:56 -07005327 EXPECT_CALL(*mock_mdns_responder, CreateNameForAddress(_, _))
5328 .Times(1)
5329 .WillOnce(Return());
5330 GetEndpoint(0)->network_manager_.set_mdns_responder(
5331 std::move(mock_mdns_responder));
5332
5333 CreateChannels();
5334
5335 // We should be able to form a srflx-host connection to ep2.
5336 ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
5337 kMediumTimeout);
5338 EXPECT_EQ(STUN_PORT_TYPE,
5339 ep1_ch1()->selected_connection()->local_candidate().type());
5340 EXPECT_EQ(LOCAL_PORT_TYPE,
5341 ep1_ch1()->selected_connection()->remote_candidate().type());
5342
5343 DestroyChannels();
5344}
5345
Qingsi Wangc129c352019-04-18 10:41:58 -07005346// Test that after changing the candidate filter from relay-only to allowing all
5347// types of candidates when doing continual gathering, we can gather without ICE
5348// restart the other types of candidates that are now enabled and form candidate
5349// pairs. Also, we verify that the relay candidates gathered previously are not
5350// removed and are still usable for necessary route switching.
5351TEST_F(P2PTransportChannelTest,
5352 SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005353 rtc::ScopedFakeClock clock;
5354
5355 ConfigureEndpoints(
5356 OPEN, OPEN,
5357 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5358 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5359 auto* ep1 = GetEndpoint(0);
5360 auto* ep2 = GetEndpoint(1);
5361 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5362 ep2->allocator_->SetCandidateFilter(CF_RELAY);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005363 // Enable continual gathering and also resurfacing gathered candidates upon
5364 // the candidate filter changed in the ICE configuration.
5365 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5366 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5367 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005368 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5369 kDefaultTimeout, clock);
5370 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5371 kDefaultTimeout, clock);
5372 EXPECT_EQ(RELAY_PORT_TYPE,
5373 ep1_ch1()->selected_connection()->local_candidate().type());
5374 EXPECT_EQ(RELAY_PORT_TYPE,
5375 ep2_ch1()->selected_connection()->local_candidate().type());
5376
5377 // Loosen the candidate filter at ep1.
5378 ep1->allocator_->SetCandidateFilter(CF_ALL);
5379 EXPECT_TRUE_SIMULATED_WAIT(
5380 ep1_ch1()->selected_connection() != nullptr &&
5381 ep1_ch1()->selected_connection()->local_candidate().type() ==
5382 LOCAL_PORT_TYPE,
5383 kDefaultTimeout, clock);
5384 EXPECT_EQ(RELAY_PORT_TYPE,
5385 ep1_ch1()->selected_connection()->remote_candidate().type());
5386
5387 // Loosen the candidate filter at ep2.
5388 ep2->allocator_->SetCandidateFilter(CF_ALL);
5389 EXPECT_TRUE_SIMULATED_WAIT(
5390 ep2_ch1()->selected_connection() != nullptr &&
5391 ep2_ch1()->selected_connection()->local_candidate().type() ==
5392 LOCAL_PORT_TYPE,
5393 kDefaultTimeout, clock);
5394 // We have migrated to a host-host candidate pair.
5395 EXPECT_EQ(LOCAL_PORT_TYPE,
5396 ep2_ch1()->selected_connection()->remote_candidate().type());
5397
5398 // Block the traffic over non-relay-to-relay routes and expect a route change.
5399 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kPublicAddrs[1]);
5400 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kPublicAddrs[0]);
5401 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kTurnUdpExtAddr);
5402 fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kTurnUdpExtAddr);
5403 // We should be able to reuse the previously gathered relay candidates.
5404 EXPECT_EQ_SIMULATED_WAIT(
5405 RELAY_PORT_TYPE,
5406 ep1_ch1()->selected_connection()->local_candidate().type(),
5407 kDefaultTimeout, clock);
5408 EXPECT_EQ(RELAY_PORT_TYPE,
5409 ep1_ch1()->selected_connection()->remote_candidate().type());
5410}
5411
5412// A similar test as SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll,
5413// and we should surface server-reflexive candidates that are enabled after
5414// changing the candidate filter.
5415TEST_F(P2PTransportChannelTest,
5416 SurfaceSrflxCandidateOnCandidateFilterChangeFromRelayToNoHost) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005417 rtc::ScopedFakeClock clock;
5418 // We need an actual NAT so that the host candidate is not equivalent to the
5419 // srflx candidate; otherwise, the host candidate would still surface even
5420 // though we disable it via the candidate filter below. This is a result of
5421 // the following limitation in the current implementation:
5422 // 1. We don't generate the srflx candidate when we have public IP.
5423 // 2. We keep the host candidate in this case in CheckCandidateFilter even
5424 // though we intend to filter them.
5425 ConfigureEndpoints(
5426 NAT_FULL_CONE, NAT_FULL_CONE,
5427 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5428 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5429 auto* ep1 = GetEndpoint(0);
5430 auto* ep2 = GetEndpoint(1);
5431 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5432 ep2->allocator_->SetCandidateFilter(CF_RELAY);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005433 // Enable continual gathering and also resurfacing gathered candidates upon
5434 // the candidate filter changed in the ICE configuration.
5435 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5436 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5437 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005438 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5439 kDefaultTimeout, clock);
5440 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5441 kDefaultTimeout, clock);
5442 const uint32_t kCandidateFilterNoHost = CF_ALL & ~CF_HOST;
5443 // Loosen the candidate filter at ep1.
5444 ep1->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5445 EXPECT_TRUE_SIMULATED_WAIT(
5446 ep1_ch1()->selected_connection() != nullptr &&
5447 ep1_ch1()->selected_connection()->local_candidate().type() ==
5448 STUN_PORT_TYPE,
5449 kDefaultTimeout, clock);
5450 EXPECT_EQ(RELAY_PORT_TYPE,
5451 ep1_ch1()->selected_connection()->remote_candidate().type());
5452
5453 // Loosen the candidate filter at ep2.
5454 ep2->allocator_->SetCandidateFilter(kCandidateFilterNoHost);
5455 EXPECT_TRUE_SIMULATED_WAIT(
5456 ep2_ch1()->selected_connection() != nullptr &&
5457 ep2_ch1()->selected_connection()->local_candidate().type() ==
5458 STUN_PORT_TYPE,
5459 kDefaultTimeout, clock);
5460 // We have migrated to a srflx-srflx candidate pair.
5461 EXPECT_EQ(STUN_PORT_TYPE,
5462 ep2_ch1()->selected_connection()->remote_candidate().type());
5463
5464 // Block the traffic over non-relay-to-relay routes and expect a route change.
5465 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kPublicAddrs[1]);
5466 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kPublicAddrs[0]);
5467 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kTurnUdpExtAddr);
5468 fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kTurnUdpExtAddr);
5469 // We should be able to reuse the previously gathered relay candidates.
5470 EXPECT_EQ_SIMULATED_WAIT(
5471 RELAY_PORT_TYPE,
5472 ep1_ch1()->selected_connection()->local_candidate().type(),
5473 kDefaultTimeout, clock);
5474 EXPECT_EQ(RELAY_PORT_TYPE,
5475 ep1_ch1()->selected_connection()->remote_candidate().type());
5476}
5477
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005478// This is the complement to
5479// SurfaceHostCandidateOnCandidateFilterChangeFromRelayToAll, and instead of
5480// gathering continually we only gather once, which makes the config
5481// |surface_ice_candidates_on_ice_transport_type_changed| ineffective after the
5482// gathering stopped.
5483TEST_F(P2PTransportChannelTest,
5484 CannotSurfaceTheNewlyAllowedOnFilterChangeIfNotGatheringContinually) {
5485 rtc::ScopedFakeClock clock;
5486
5487 ConfigureEndpoints(
5488 OPEN, OPEN,
5489 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5490 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5491 auto* ep1 = GetEndpoint(0);
5492 auto* ep2 = GetEndpoint(1);
5493 ep1->allocator_->SetCandidateFilter(CF_RELAY);
5494 ep2->allocator_->SetCandidateFilter(CF_RELAY);
5495 // Only gather once.
5496 IceConfig ice_config = CreateIceConfig(1000, GATHER_ONCE);
5497 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
5498 CreateChannels(ice_config, ice_config);
5499 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5500 kDefaultTimeout, clock);
5501 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5502 kDefaultTimeout, clock);
5503 // Loosen the candidate filter at ep1.
5504 ep1->allocator_->SetCandidateFilter(CF_ALL);
5505 // Wait for a period for any potential surfacing of new candidates.
5506 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5507 EXPECT_EQ(RELAY_PORT_TYPE,
5508 ep1_ch1()->selected_connection()->local_candidate().type());
5509
5510 // Loosen the candidate filter at ep2.
5511 ep2->allocator_->SetCandidateFilter(CF_ALL);
5512 EXPECT_EQ(RELAY_PORT_TYPE,
5513 ep2_ch1()->selected_connection()->local_candidate().type());
5514}
5515
Qingsi Wangc129c352019-04-18 10:41:58 -07005516// Test that when the candidate filter is updated to be more restrictive,
5517// candidates that 1) have already been gathered and signaled 2) but no longer
5518// match the filter, are not removed.
5519TEST_F(P2PTransportChannelTest,
5520 RestrictingCandidateFilterDoesNotRemoveRegatheredCandidates) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005521 rtc::ScopedFakeClock clock;
5522
5523 ConfigureEndpoints(
5524 OPEN, OPEN,
5525 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
5526 kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
5527 auto* ep1 = GetEndpoint(0);
5528 auto* ep2 = GetEndpoint(1);
5529 ep1->allocator_->SetCandidateFilter(CF_ALL);
5530 ep2->allocator_->SetCandidateFilter(CF_ALL);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005531 // Enable continual gathering and also resurfacing gathered candidates upon
5532 // the candidate filter changed in the ICE configuration.
5533 IceConfig ice_config = CreateIceConfig(1000, GATHER_CONTINUALLY);
5534 ice_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005535 // Pause candidates so we can gather all types of candidates. See
5536 // P2PTransportChannel::OnConnectionStateChange, where we would stop the
5537 // gathering when we have a strongly connected candidate pair.
5538 PauseCandidates(0);
5539 PauseCandidates(1);
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005540 CreateChannels(ice_config, ice_config);
Qingsi Wangc129c352019-04-18 10:41:58 -07005541
5542 // We have gathered host, srflx and relay candidates.
5543 EXPECT_TRUE_SIMULATED_WAIT(ep1->saved_candidates_.size() == 3u,
5544 kDefaultTimeout, clock);
5545 ResumeCandidates(0);
5546 ResumeCandidates(1);
5547 ASSERT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
5548 kDefaultTimeout, clock);
5549 ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr,
5550 kDefaultTimeout, clock);
5551 // Test that we have a host-host candidate pair selected and the number of
5552 // candidates signaled to the remote peer stays the same.
5553 auto test_invariants = [this]() {
5554 EXPECT_EQ(LOCAL_PORT_TYPE,
5555 ep1_ch1()->selected_connection()->local_candidate().type());
5556 EXPECT_EQ(LOCAL_PORT_TYPE,
5557 ep1_ch1()->selected_connection()->remote_candidate().type());
5558 EXPECT_THAT(ep2_ch1()->remote_candidates(), SizeIs(3));
5559 };
5560
5561 test_invariants();
5562
5563 // Set a more restrictive candidate filter at ep1.
5564 ep1->allocator_->SetCandidateFilter(CF_HOST | CF_REFLEXIVE);
5565 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5566 test_invariants();
5567
5568 ep1->allocator_->SetCandidateFilter(CF_HOST);
5569 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5570 test_invariants();
5571
5572 ep1->allocator_->SetCandidateFilter(CF_NONE);
5573 SIMULATED_WAIT(false, kDefaultTimeout, clock);
5574 test_invariants();
5575}
5576
Jonas Oreland1230fb72019-10-25 15:58:14 +02005577TEST_F(P2PTransportChannelPingTest, TestInitialSelectDampening0) {
5578 webrtc::test::ScopedFieldTrials field_trials(
5579 "WebRTC-IceFieldTrials/initial_select_dampening:0/");
5580
5581 constexpr int kMargin = 10;
5582 rtc::ScopedFakeClock clock;
5583 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
5584
5585 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
5586 P2PTransportChannel ch("test channel", 1, &pa);
5587 PrepareChannel(&ch);
5588 ch.SetIceConfig(ch.config());
5589 ch.MaybeStartGathering();
5590
5591 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
5592 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
5593 ASSERT_TRUE(conn1 != nullptr);
5594 EXPECT_EQ(nullptr, ch.selected_connection());
5595 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
5596 // It shall not be selected until 0ms has passed....i.e it should be connected
5597 // directly.
5598 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kMargin, clock);
5599}
5600
5601TEST_F(P2PTransportChannelPingTest, TestInitialSelectDampening) {
5602 webrtc::test::ScopedFieldTrials field_trials(
5603 "WebRTC-IceFieldTrials/initial_select_dampening:100/");
5604
5605 constexpr int kMargin = 10;
5606 rtc::ScopedFakeClock clock;
5607 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
5608
5609 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
5610 P2PTransportChannel ch("test channel", 1, &pa);
5611 PrepareChannel(&ch);
5612 ch.SetIceConfig(ch.config());
5613 ch.MaybeStartGathering();
5614
5615 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
5616 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
5617 ASSERT_TRUE(conn1 != nullptr);
5618 EXPECT_EQ(nullptr, ch.selected_connection());
5619 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
5620 // It shall not be selected until 100ms has passed.
5621 SIMULATED_WAIT(conn1 == ch.selected_connection(), 100 - kMargin, clock);
5622 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
5623}
5624
5625TEST_F(P2PTransportChannelPingTest, TestInitialSelectDampeningPingReceived) {
5626 webrtc::test::ScopedFieldTrials field_trials(
5627 "WebRTC-IceFieldTrials/initial_select_dampening_ping_received:100/");
5628
5629 constexpr int kMargin = 10;
5630 rtc::ScopedFakeClock clock;
5631 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
5632
5633 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
5634 P2PTransportChannel ch("test channel", 1, &pa);
5635 PrepareChannel(&ch);
5636 ch.SetIceConfig(ch.config());
5637 ch.MaybeStartGathering();
5638
5639 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
5640 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
5641 ASSERT_TRUE(conn1 != nullptr);
5642 EXPECT_EQ(nullptr, ch.selected_connection());
5643 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
5644 conn1->ReceivedPing("id1"); //
5645 // It shall not be selected until 100ms has passed.
5646 SIMULATED_WAIT(conn1 == ch.selected_connection(), 100 - kMargin, clock);
5647 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
5648}
5649
5650TEST_F(P2PTransportChannelPingTest, TestInitialSelectDampeningBoth) {
5651 webrtc::test::ScopedFieldTrials field_trials(
5652 "WebRTC-IceFieldTrials/"
5653 "initial_select_dampening:100,initial_select_dampening_ping_received:"
5654 "50/");
5655
5656 constexpr int kMargin = 10;
5657 rtc::ScopedFakeClock clock;
5658 clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
5659
5660 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
5661 P2PTransportChannel ch("test channel", 1, &pa);
5662 PrepareChannel(&ch);
5663 ch.SetIceConfig(ch.config());
5664 ch.MaybeStartGathering();
5665
5666 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
5667 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
5668 ASSERT_TRUE(conn1 != nullptr);
5669 EXPECT_EQ(nullptr, ch.selected_connection());
5670 conn1->ReceivedPingResponse(LOW_RTT, "id"); // Becomes writable and receiving
5671 // It shall not be selected until 100ms has passed....but only wait ~50 now.
5672 SIMULATED_WAIT(conn1 == ch.selected_connection(), 50 - kMargin, clock);
5673 // Now receiving ping and new timeout should kick in.
5674 conn1->ReceivedPing("id1"); //
5675 EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), 2 * kMargin, clock);
5676}
5677
Steve Antone9324572017-11-29 10:18:21 -08005678} // namespace cricket