blob: 16f89e946a365c51149059abf3156df49fb89c49 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2012 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#if defined(WEBRTC_POSIX)
11#include <dirent.h>
12#endif
13
deadbeef5c3c1042017-08-04 15:01:57 -070014#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070015#include <memory>
Steve Anton6c38cc72017-11-29 10:25:58 -080016#include <utility>
17#include <vector>
kwiberg3ec46792016-04-27 07:22:53 -070018
Karl Wiberg918f50c2018-07-05 11:40:33 +020019#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "p2p/base/basicpacketsocketfactory.h"
21#include "p2p/base/p2pconstants.h"
22#include "p2p/base/portallocator.h"
23#include "p2p/base/tcpport.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020024#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "p2p/base/testturnserver.h"
26#include "p2p/base/turnport.h"
27#include "p2p/base/udpport.h"
28#include "rtc_base/asynctcpsocket.h"
29#include "rtc_base/buffer.h"
30#include "rtc_base/checks.h"
31#include "rtc_base/dscp.h"
32#include "rtc_base/fakeclock.h"
33#include "rtc_base/firewallsocketserver.h"
34#include "rtc_base/gunit.h"
35#include "rtc_base/helpers.h"
36#include "rtc_base/logging.h"
37#include "rtc_base/socketadapters.h"
38#include "rtc_base/socketaddress.h"
39#include "rtc_base/ssladapter.h"
40#include "rtc_base/thread.h"
41#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042
43using rtc::SocketAddress;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044
45static const SocketAddress kLocalAddr1("11.11.11.11", 0);
46static const SocketAddress kLocalAddr2("22.22.22.22", 0);
Yves Gerey665174f2018-06-19 15:03:05 +020047static const SocketAddress kLocalIPv6Addr("2401:fa00:4:1000:be30:5bff:fee5:c3",
48 0);
49static const SocketAddress kLocalIPv6Addr2("2401:fa00:4:2000:be30:5bff:fee5:d4",
50 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
52 cricket::TURN_SERVER_PORT);
53static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
54 cricket::TURN_SERVER_PORT);
55static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +000056static const SocketAddress kTurnAlternateIntAddr("99.99.99.6",
57 cricket::TURN_SERVER_PORT);
58static const SocketAddress kTurnIntAddr("99.99.99.7",
59 cricket::TURN_SERVER_PORT);
60static const SocketAddress kTurnIPv6IntAddr(
61 "2400:4030:2:2c00:be30:abcd:efab:cdef",
62 cricket::TURN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000063static const SocketAddress kTurnUdpIPv6IntAddr(
Yves Gerey665174f2018-06-19 15:03:05 +020064 "2400:4030:1:2c00:be30:abcd:efab:cdef",
65 cricket::TURN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -070067static const char kCandidateFoundation[] = "foundation";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000068static const char kIceUfrag1[] = "TESTICEUFRAG0001";
69static const char kIceUfrag2[] = "TESTICEUFRAG0002";
70static const char kIcePwd1[] = "TESTICEPWD00000000000001";
71static const char kIcePwd2[] = "TESTICEPWD00000000000002";
72static const char kTurnUsername[] = "test";
73static const char kTurnPassword[] = "test";
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000074static const char kTestOrigin[] = "http://example.com";
Taylor Brandstetter716d07a2016-06-27 14:07:41 -070075// This test configures the virtual socket server to simulate delay so that we
76// can verify operations take no more than the expected number of round trips.
77static constexpr unsigned int kSimulatedRtt = 50;
78// Connection destruction may happen asynchronously, but it should only
79// take one simulated clock tick.
80static constexpr unsigned int kConnectionDestructionDelay = 1;
81// This used to be 1 second, but that's not always enough for getaddrinfo().
82// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5191
83static constexpr unsigned int kResolverTimeout = 10000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084
Yves Gerey665174f2018-06-19 15:03:05 +020085static const cricket::ProtocolAddress kTurnUdpProtoAddr(kTurnUdpIntAddr,
86 cricket::PROTO_UDP);
87static const cricket::ProtocolAddress kTurnTcpProtoAddr(kTurnTcpIntAddr,
88 cricket::PROTO_TCP);
hnsl277b2502016-12-13 05:17:23 -080089static const cricket::ProtocolAddress kTurnTlsProtoAddr(kTurnTcpIntAddr,
90 cricket::PROTO_TLS);
Yves Gerey665174f2018-06-19 15:03:05 +020091static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(kTurnUdpIPv6IntAddr,
92 cricket::PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000093
94static const unsigned int MSG_TESTFINISH = 0;
95
96#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
97static int GetFDCount() {
Yves Gerey665174f2018-06-19 15:03:05 +020098 struct dirent* dp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000099 int fd_count = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200100 DIR* dir = opendir("/proc/self/fd/");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000101 while ((dp = readdir(dir)) != NULL) {
102 if (dp->d_name[0] == '.')
103 continue;
104 ++fd_count;
105 }
106 closedir(dir);
107 return fd_count;
108}
109#endif
110
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700111namespace cricket {
112
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000113class TurnPortTestVirtualSocketServer : public rtc::VirtualSocketServer {
114 public:
deadbeef98e186c2017-05-16 18:00:06 -0700115 TurnPortTestVirtualSocketServer() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700116 // This configures the virtual socket server to always add a simulated
117 // delay of exactly half of kSimulatedRtt.
118 set_delay_mean(kSimulatedRtt / 2);
119 UpdateDelayDistribution();
120 }
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000121
122 using rtc::VirtualSocketServer::LookupBinding;
123};
124
deadbeef376e1232015-11-25 09:00:08 -0800125class TestConnectionWrapper : public sigslot::has_slots<> {
126 public:
Steve Anton6c38cc72017-11-29 10:25:58 -0800127 explicit TestConnectionWrapper(Connection* conn) : connection_(conn) {
deadbeef376e1232015-11-25 09:00:08 -0800128 conn->SignalDestroyed.connect(
129 this, &TestConnectionWrapper::OnConnectionDestroyed);
130 }
131
132 Connection* connection() { return connection_; }
133
134 private:
135 void OnConnectionDestroyed(Connection* conn) {
136 ASSERT_TRUE(conn == connection_);
137 connection_ = nullptr;
138 }
139
140 Connection* connection_;
141};
142
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700143// Note: This test uses a fake clock with a simulated network round trip
144// (between local port and TURN server) of kSimulatedRtt.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000145class TurnPortTest : public testing::Test,
146 public sigslot::has_slots<>,
147 public rtc::MessageHandler {
148 public:
149 TurnPortTest()
deadbeef98e186c2017-05-16 18:00:06 -0700150 : ss_(new TurnPortTestVirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700151 main_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152 socket_factory_(rtc::Thread::Current()),
nisse7eaa4ea2017-05-08 05:25:41 -0700153 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 turn_ready_(false),
155 turn_error_(false),
156 turn_unknown_address_(false),
157 turn_create_permission_success_(false),
Jonas Orelandc99dc312018-03-28 08:00:50 +0200158 turn_port_closed_(false),
159 turn_port_destroyed_(false),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160 udp_ready_(false),
161 test_finish_(false) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700162 // Some code uses "last received time == 0" to represent "nothing received
163 // so far", so we need to start the fake clock at a nonzero time...
164 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200165 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166 }
167
168 virtual void OnMessage(rtc::Message* msg) {
nissec8ee8822017-01-18 07:20:55 -0800169 RTC_CHECK(msg->message_id == MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000170 if (msg->message_id == MSG_TESTFINISH)
171 test_finish_ = true;
172 }
173
Yves Gerey665174f2018-06-19 15:03:05 +0200174 void OnTurnPortComplete(Port* port) { turn_ready_ = true; }
175 void OnTurnPortError(Port* port) { turn_error_ = true; }
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700176 void OnTurnUnknownAddress(PortInterface* port,
177 const SocketAddress& addr,
178 ProtocolType proto,
179 IceMessage* msg,
180 const std::string& rf,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000181 bool /*port_muxed*/) {
182 turn_unknown_address_ = true;
183 }
Honghai Zhangf67c5482015-12-11 15:16:54 -0800184 void OnTurnCreatePermissionResult(TurnPort* port,
185 const SocketAddress& addr,
186 int code) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187 // Ignoring the address.
Honghai Zhangf67c5482015-12-11 15:16:54 -0800188 turn_create_permission_success_ = (code == 0);
189 }
190
191 void OnTurnRefreshResult(TurnPort* port, int code) {
192 turn_refresh_success_ = (code == 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 }
Yves Gerey665174f2018-06-19 15:03:05 +0200194 void OnTurnReadPacket(Connection* conn,
195 const char* data,
196 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197 const rtc::PacketTime& packet_time) {
198 turn_packets_.push_back(rtc::Buffer(data, size));
199 }
Yves Gerey665174f2018-06-19 15:03:05 +0200200 void OnUdpPortComplete(Port* port) { udp_ready_ = true; }
201 void OnUdpReadPacket(Connection* conn,
202 const char* data,
203 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000204 const rtc::PacketTime& packet_time) {
205 udp_packets_.push_back(rtc::Buffer(data, size));
206 }
207 void OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200208 const char* data,
209 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000210 const rtc::SocketAddress& remote_addr,
211 const rtc::PacketTime& packet_time) {
212 turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
213 packet_time);
214 }
Yves Gerey665174f2018-06-19 15:03:05 +0200215 void OnTurnPortClosed(TurnPort* port) { turn_port_closed_ = true; }
216 void OnTurnPortDestroyed(PortInterface* port) { turn_port_destroyed_ = true; }
Jonas Orelandc99dc312018-03-28 08:00:50 +0200217
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000218 rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
Steve Anton31e5bf52018-05-07 10:42:55 -0700219 rtc::AsyncSocket* socket = ss_->CreateAsyncSocket(AF_INET, SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 EXPECT_GE(socket->Bind(addr), 0);
221 EXPECT_GE(socket->Listen(5), 0);
222 return socket;
223 }
224
deadbeef5c3c1042017-08-04 15:01:57 -0700225 rtc::Network* MakeNetwork(const SocketAddress& addr) {
226 networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
227 networks_.back().AddIP(addr.ipaddr());
228 return &networks_.back();
229 }
230
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231 void CreateTurnPort(const std::string& username,
232 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700233 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700234 CreateTurnPortWithAllParams(MakeNetwork(kLocalAddr1), username, password,
235 server_address, std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000236 }
237 void CreateTurnPort(const rtc::SocketAddress& local_address,
238 const std::string& username,
239 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700240 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700241 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
242 server_address, std::string());
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000243 }
244
245 // Should be identical to CreateTurnPort but specifies an origin value
246 // when creating the instance of TurnPort.
247 void CreateTurnPortWithOrigin(const rtc::SocketAddress& local_address,
248 const std::string& username,
249 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700250 const ProtocolAddress& server_address,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000251 const std::string& origin) {
deadbeef5c3c1042017-08-04 15:01:57 -0700252 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
253 server_address, origin);
254 }
255
256 void CreateTurnPortWithNetwork(rtc::Network* network,
257 const std::string& username,
258 const std::string& password,
259 const ProtocolAddress& server_address) {
260 CreateTurnPortWithAllParams(network, username, password, server_address,
261 std::string());
262 }
263
264 // Version of CreateTurnPort that takes all possible parameters; all other
265 // helper methods call this, such that "SetIceRole" and "ConnectSignals" (and
266 // possibly other things in the future) only happen in one place.
267 void CreateTurnPortWithAllParams(rtc::Network* network,
268 const std::string& username,
269 const std::string& password,
270 const ProtocolAddress& server_address,
271 const std::string& origin) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700272 RelayCredentials credentials(username, password);
Steve Antonf7dd9df2018-10-10 15:06:28 -0700273 turn_port_ = TurnPort::Create(
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000274 &main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
Steve Antona8f1e562018-10-10 11:29:44 -0700275 server_address, credentials, 0, origin, {}, {}, turn_customizer_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000276 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700277 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000278 ConnectSignals();
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000279
280 if (server_address.proto == cricket::PROTO_TLS) {
281 // The test TURN server has a self-signed certificate so will not pass
282 // the normal client validation. Instruct the client to ignore certificate
283 // errors for testing only.
284 turn_port_->SetTlsCertPolicy(
285 TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
286 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000287 }
288
289 void CreateSharedTurnPort(const std::string& username,
290 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700291 const ProtocolAddress& server_address) {
nissec8ee8822017-01-18 07:20:55 -0800292 RTC_CHECK(server_address.proto == PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000293
294 if (!socket_) {
295 socket_.reset(socket_factory_.CreateUdpSocket(
296 rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
297 ASSERT_TRUE(socket_ != NULL);
Yves Gerey665174f2018-06-19 15:03:05 +0200298 socket_->SignalReadPacket.connect(this,
299 &TurnPortTest::OnSocketReadPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000300 }
301
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700302 RelayCredentials credentials(username, password);
Steve Antonf7dd9df2018-10-10 15:06:28 -0700303 turn_port_ =
304 TurnPort::Create(&main_, &socket_factory_, MakeNetwork(kLocalAddr1),
305 socket_.get(), kIceUfrag1, kIcePwd1, server_address,
306 credentials, 0, std::string(), nullptr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000307 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700308 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000309 ConnectSignals();
310 }
311
312 void ConnectSignals() {
313 turn_port_->SignalPortComplete.connect(this,
Yves Gerey665174f2018-06-19 15:03:05 +0200314 &TurnPortTest::OnTurnPortComplete);
315 turn_port_->SignalPortError.connect(this, &TurnPortTest::OnTurnPortError);
316 turn_port_->SignalUnknownAddress.connect(
317 this, &TurnPortTest::OnTurnUnknownAddress);
318 turn_port_->SignalCreatePermissionResult.connect(
319 this, &TurnPortTest::OnTurnCreatePermissionResult);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800320 turn_port_->SignalTurnRefreshResult.connect(
321 this, &TurnPortTest::OnTurnRefreshResult);
Yves Gerey665174f2018-06-19 15:03:05 +0200322 turn_port_->SignalTurnPortClosed.connect(this,
323 &TurnPortTest::OnTurnPortClosed);
324 turn_port_->SignalDestroyed.connect(this,
325 &TurnPortTest::OnTurnPortDestroyed);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800326 }
deadbeef376e1232015-11-25 09:00:08 -0800327
328 void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
329
330 void CreateUdpPort(const SocketAddress& address) {
Steve Antona8f1e562018-10-10 11:29:44 -0700331 udp_port_ = UDPPort::Create(&main_, &socket_factory_, MakeNetwork(address),
332 0, 0, kIceUfrag2, kIcePwd2, std::string(),
333 false, absl::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000334 // UDP port will be controlled.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700335 udp_port_->SetIceRole(ICEROLE_CONTROLLED);
Yves Gerey665174f2018-06-19 15:03:05 +0200336 udp_port_->SignalPortComplete.connect(this,
337 &TurnPortTest::OnUdpPortComplete);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000338 }
339
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700340 void PrepareTurnAndUdpPorts(ProtocolType protocol_type) {
Honghai Zhangf67c5482015-12-11 15:16:54 -0800341 // turn_port_ should have been created.
342 ASSERT_TRUE(turn_port_ != nullptr);
343 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700344 ASSERT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700345 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800346
347 CreateUdpPort();
348 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700349 ASSERT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800350 }
351
Steve Antoned447ae2017-08-17 14:31:51 -0700352 // Returns the fake clock time to establish a connection over the given
353 // protocol.
354 int TimeToConnect(ProtocolType protocol_type) {
355 switch (protocol_type) {
356 case PROTO_TCP:
357 // The virtual socket server will delay by a fixed half a round trip
358 // for a TCP connection.
359 return kSimulatedRtt / 2;
Steve Anton786de702017-08-17 15:15:46 -0700360 case PROTO_TLS:
361 // TLS operates over TCP and additionally has a round of HELLO for
362 // negotiating ciphers and a round for exchanging certificates.
363 return 2 * kSimulatedRtt + TimeToConnect(PROTO_TCP);
Steve Antoned447ae2017-08-17 14:31:51 -0700364 case PROTO_UDP:
365 default:
366 // UDP requires no round trips to set up the connection.
367 return 0;
368 }
369 }
370
371 // Returns the total fake clock time to establish a connection with a TURN
372 // server over the given protocol and to allocate a TURN candidate.
373 int TimeToGetTurnCandidate(ProtocolType protocol_type) {
374 // For a simple allocation, the first Allocate message will return with an
375 // error asking for credentials and will succeed after the second Allocate
376 // message.
377 return 2 * kSimulatedRtt + TimeToConnect(protocol_type);
378 }
379
380 // Total fake clock time to do the following:
381 // 1. Connect to primary TURN server
382 // 2. Send Allocate and receive a redirect from the primary TURN server
383 // 3. Connect to alternate TURN server
384 // 4. Send Allocate and receive a request for credentials
385 // 5. Send Allocate with credentials and receive allocation
386 int TimeToGetAlternateTurnCandidate(ProtocolType protocol_type) {
387 return 3 * kSimulatedRtt + 2 * TimeToConnect(protocol_type);
388 }
389
honghaiz079a7a12016-06-22 16:26:29 -0700390 bool CheckConnectionFailedAndPruned(Connection* conn) {
hbos06495bc2017-01-02 08:08:18 -0800391 return conn && !conn->active() &&
392 conn->state() == IceCandidatePairState::FAILED;
honghaiz079a7a12016-06-22 16:26:29 -0700393 }
394
395 // Checks that |turn_port_| has a nonempty set of connections and they are all
396 // failed and pruned.
397 bool CheckAllConnectionsFailedAndPruned() {
398 auto& connections = turn_port_->connections();
399 if (connections.empty()) {
400 return false;
401 }
402 for (auto kv : connections) {
403 if (!CheckConnectionFailedAndPruned(kv.second)) {
404 return false;
405 }
406 }
407 return true;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800408 }
409
Steve Antoned447ae2017-08-17 14:31:51 -0700410 void TestReconstructedServerUrl(ProtocolType protocol_type,
411 const char* expected_url) {
412 turn_port_->PrepareAddress();
413 ASSERT_TRUE_SIMULATED_WAIT(
414 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
415 ASSERT_EQ(1U, turn_port_->Candidates().size());
416 EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_url);
417 }
418
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700419 void TestTurnAlternateServer(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000420 std::vector<rtc::SocketAddress> redirect_addresses;
421 redirect_addresses.push_back(kTurnAlternateIntAddr);
422
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700423 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000424
425 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
426 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
427 turn_server_.set_redirect_hook(&redirector);
428 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700429 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000430
431 // Retrieve the address before we run the state machine.
432 const SocketAddress old_addr = turn_port_->server_address().address;
433
434 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700435 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_,
436 TimeToGetAlternateTurnCandidate(protocol_type),
437 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000438 // Retrieve the address again, the turn port's address should be
439 // changed.
440 const SocketAddress new_addr = turn_port_->server_address().address;
441 EXPECT_NE(old_addr, new_addr);
442 ASSERT_EQ(1U, turn_port_->Candidates().size());
443 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
444 turn_port_->Candidates()[0].address().ipaddr());
445 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
446 }
447
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700448 void TestTurnAlternateServerV4toV6(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000449 std::vector<rtc::SocketAddress> redirect_addresses;
450 redirect_addresses.push_back(kTurnIPv6IntAddr);
451
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700452 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000453 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
454 turn_server_.set_redirect_hook(&redirector);
455 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700456 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000457 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700458 // Need time to connect to TURN server, send Allocate request and receive
459 // redirect notice.
460 EXPECT_TRUE_SIMULATED_WAIT(
461 turn_error_, kSimulatedRtt + TimeToConnect(protocol_type), fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000462 }
463
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700464 void TestTurnAlternateServerPingPong(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000465 std::vector<rtc::SocketAddress> redirect_addresses;
466 redirect_addresses.push_back(kTurnAlternateIntAddr);
467 redirect_addresses.push_back(kTurnIntAddr);
468
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700469 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000470
471 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
472 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
473 turn_server_.set_redirect_hook(&redirector);
474 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700475 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000476
477 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700478 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
479 TimeToGetAlternateTurnCandidate(protocol_type),
480 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000481 ASSERT_EQ(0U, turn_port_->Candidates().size());
482 rtc::SocketAddress address;
483 // Verify that we have exhausted all alternate servers instead of
484 // failure caused by other errors.
485 EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
486 }
487
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700488 void TestTurnAlternateServerDetectRepetition(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000489 std::vector<rtc::SocketAddress> redirect_addresses;
490 redirect_addresses.push_back(kTurnAlternateIntAddr);
491 redirect_addresses.push_back(kTurnAlternateIntAddr);
492
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700493 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000494
495 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
496 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
497 turn_server_.set_redirect_hook(&redirector);
498 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700499 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000500
501 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700502 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
503 TimeToGetAlternateTurnCandidate(protocol_type),
504 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000505 ASSERT_EQ(0U, turn_port_->Candidates().size());
506 }
507
deadbeeffb70b452016-10-24 13:15:59 -0700508 // A certain security exploit works by redirecting to a loopback address,
509 // which doesn't ever actually make sense. So redirects to loopback should
510 // be treated as errors.
511 // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
512 void TestTurnAlternateServerLoopback(ProtocolType protocol_type, bool ipv6) {
513 const SocketAddress& local_address = ipv6 ? kLocalIPv6Addr : kLocalAddr1;
514 const SocketAddress& server_address =
515 ipv6 ? kTurnIPv6IntAddr : kTurnIntAddr;
516
517 std::vector<rtc::SocketAddress> redirect_addresses;
deadbeef99220162016-10-27 18:30:23 -0700518 // Pick an unusual address in the 127.0.0.0/8 range to make sure more than
519 // 127.0.0.1 is covered.
520 SocketAddress loopback_address(ipv6 ? "::1" : "127.1.2.3",
deadbeeffb70b452016-10-24 13:15:59 -0700521 TURN_SERVER_PORT);
522 redirect_addresses.push_back(loopback_address);
523
524 // Make a socket and bind it to the local port, to make extra sure no
525 // packet is sent to this address.
526 std::unique_ptr<rtc::Socket> loopback_socket(ss_->CreateSocket(
Steve Anton31e5bf52018-05-07 10:42:55 -0700527 AF_INET, protocol_type == PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM));
deadbeeffb70b452016-10-24 13:15:59 -0700528 ASSERT_NE(nullptr, loopback_socket.get());
529 ASSERT_EQ(0, loopback_socket->Bind(loopback_address));
530 if (protocol_type == PROTO_TCP) {
531 ASSERT_EQ(0, loopback_socket->Listen(1));
532 }
533
534 TestTurnRedirector redirector(redirect_addresses);
535
536 turn_server_.AddInternalSocket(server_address, protocol_type);
537 turn_server_.set_redirect_hook(&redirector);
538 CreateTurnPort(local_address, kTurnUsername, kTurnPassword,
539 ProtocolAddress(server_address, protocol_type));
540
541 turn_port_->PrepareAddress();
542 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700543 turn_error_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
deadbeeffb70b452016-10-24 13:15:59 -0700544
545 // Wait for some extra time, and make sure no packets were received on the
546 // loopback port we created (or in the case of TCP, no connection attempt
547 // occurred).
548 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
549 if (protocol_type == PROTO_UDP) {
550 char buf[1];
551 EXPECT_EQ(-1, loopback_socket->Recv(&buf, 1, nullptr));
552 } else {
553 std::unique_ptr<rtc::Socket> accepted_socket(
554 loopback_socket->Accept(nullptr));
555 EXPECT_EQ(nullptr, accepted_socket.get());
556 }
557 }
558
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700559 void TestTurnConnection(ProtocolType protocol_type) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000560 // Create ports and prepare addresses.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700561 PrepareTurnAndUdpPorts(protocol_type);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000562
563 // Send ping from UDP to TURN.
Steve Anton786de702017-08-17 15:15:46 -0700564 ASSERT_GE(turn_port_->Candidates().size(), 1U);
Yves Gerey665174f2018-06-19 15:03:05 +0200565 Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
566 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000567 ASSERT_TRUE(conn1 != NULL);
568 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700569 SIMULATED_WAIT(!turn_unknown_address_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000570 EXPECT_FALSE(turn_unknown_address_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700571 EXPECT_FALSE(conn1->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000572 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
573
574 // Send ping from TURN to UDP.
Yves Gerey665174f2018-06-19 15:03:05 +0200575 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
576 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000577 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700578 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
579 fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000580 conn2->Ping(0);
581
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700582 // Two hops from TURN port to UDP port through TURN server, thus two RTTs.
583 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
584 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700585 EXPECT_TRUE(conn1->receiving());
586 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000587 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
588
589 // Send another ping from UDP to TURN.
590 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700591 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
592 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700593 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000594 }
595
honghaiz32f39962015-11-17 11:36:31 -0800596 void TestDestroyTurnConnection() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700597 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz32f39962015-11-17 11:36:31 -0800598
599 // Create connections on both ends.
600 Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
601 Port::ORIGIN_MESSAGE);
602 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
603 Port::ORIGIN_MESSAGE);
604 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700605 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
606 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800607 // Make sure turn connection can receive.
608 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700609 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
610 kSimulatedRtt * 2, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800611 EXPECT_FALSE(turn_unknown_address_);
612
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700613 // Destroy the connection on the TURN port. The TurnEntry still exists, so
614 // the TURN port should still process a ping from an unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800615 conn2->Destroy();
616 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700617 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
618 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800619
620 // Flush all requests in the invoker to destroy the TurnEntry.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700621 // Expect that it still processes an incoming ping and signals the
622 // unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800623 turn_unknown_address_ = false;
624 turn_port_->invoker()->Flush(rtc::Thread::Current());
625 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700626 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
627 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800628
629 // If the connection is created again, it will start to receive pings.
630 conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
631 Port::ORIGIN_MESSAGE);
632 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700633 EXPECT_TRUE_SIMULATED_WAIT(conn2->receiving(), kSimulatedRtt, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800634 }
635
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700636 void TestTurnSendData(ProtocolType protocol_type) {
637 PrepareTurnAndUdpPorts(protocol_type);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800638
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000639 // Create connections and send pings.
Yves Gerey665174f2018-06-19 15:03:05 +0200640 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
641 Port::ORIGIN_MESSAGE);
642 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
643 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000644 ASSERT_TRUE(conn1 != NULL);
645 ASSERT_TRUE(conn2 != NULL);
646 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
647 &TurnPortTest::OnTurnReadPacket);
648 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
649 &TurnPortTest::OnUdpReadPacket);
650 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700651 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
652 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000653 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700654 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
655 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000656
657 // Send some data.
658 size_t num_packets = 256;
659 for (size_t i = 0; i < num_packets; ++i) {
Yves Gerey665174f2018-06-19 15:03:05 +0200660 unsigned char buf[256] = {0};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000661 for (size_t j = 0; j < i + 1; ++j) {
662 buf[j] = 0xFF - static_cast<unsigned char>(j);
663 }
664 conn1->Send(buf, i + 1, options);
665 conn2->Send(buf, i + 1, options);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700666 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000667 }
668
669 // Check the data.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700670 ASSERT_EQ(num_packets, turn_packets_.size());
671 ASSERT_EQ(num_packets, udp_packets_.size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000672 for (size_t i = 0; i < num_packets; ++i) {
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000673 EXPECT_EQ(i + 1, turn_packets_[i].size());
674 EXPECT_EQ(i + 1, udp_packets_[i].size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000675 EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
676 }
677 }
678
Steve Antoned447ae2017-08-17 14:31:51 -0700679 // Test that a TURN allocation is released when the port is closed.
680 void TestTurnReleaseAllocation(ProtocolType protocol_type) {
681 PrepareTurnAndUdpPorts(protocol_type);
682 turn_port_.reset();
683 EXPECT_EQ_SIMULATED_WAIT(0U, turn_server_.server()->allocations().size(),
684 kSimulatedRtt, fake_clock_);
685 }
686
Jonas Orelandc99dc312018-03-28 08:00:50 +0200687 // Test that the TURN allocation is released by sending a refresh request
688 // with lifetime 0 when Release is called.
689 void TestTurnGracefulReleaseAllocation(ProtocolType protocol_type) {
690 PrepareTurnAndUdpPorts(protocol_type);
691
692 // Create connections and send pings.
Yves Gerey665174f2018-06-19 15:03:05 +0200693 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
694 Port::ORIGIN_MESSAGE);
695 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
696 Port::ORIGIN_MESSAGE);
Jonas Orelandc99dc312018-03-28 08:00:50 +0200697 ASSERT_TRUE(conn1 != NULL);
698 ASSERT_TRUE(conn2 != NULL);
699 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
700 &TurnPortTest::OnTurnReadPacket);
701 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
702 &TurnPortTest::OnUdpReadPacket);
703 conn1->Ping(0);
704 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
705 kSimulatedRtt * 2, fake_clock_);
706 conn2->Ping(0);
707 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
708 kSimulatedRtt * 2, fake_clock_);
709
710 // Send some data from Udp to TurnPort.
Yves Gerey665174f2018-06-19 15:03:05 +0200711 unsigned char buf[256] = {0};
Jonas Orelandc99dc312018-03-28 08:00:50 +0200712 conn2->Send(buf, sizeof(buf), options);
713
714 // Now release the TurnPort allocation.
715 // This will send a REFRESH with lifetime 0 to server.
716 turn_port_->Release();
717
718 // Wait for the TurnPort to signal closed.
719 ASSERT_TRUE_SIMULATED_WAIT(turn_port_closed_, kSimulatedRtt, fake_clock_);
720
721 // But the data should have arrived first.
722 ASSERT_EQ(1ul, turn_packets_.size());
723 EXPECT_EQ(sizeof(buf), turn_packets_[0].size());
724
725 // The allocation is released at server.
726 EXPECT_EQ(0U, turn_server_.server()->allocations().size());
727 }
728
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000729 protected:
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700730 rtc::ScopedFakeClock fake_clock_;
deadbeef5c3c1042017-08-04 15:01:57 -0700731 // When a "create port" helper method is called with an IP, we create a
732 // Network with that IP and add it to this list. Using a list instead of a
733 // vector so that when it grows, pointers aren't invalidated.
734 std::list<rtc::Network> networks_;
kwiberg3ec46792016-04-27 07:22:53 -0700735 std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700736 rtc::AutoSocketServerThread main_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000737 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700738 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700739 TestTurnServer turn_server_;
kwiberg3ec46792016-04-27 07:22:53 -0700740 std::unique_ptr<TurnPort> turn_port_;
741 std::unique_ptr<UDPPort> udp_port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000742 bool turn_ready_;
743 bool turn_error_;
744 bool turn_unknown_address_;
745 bool turn_create_permission_success_;
Jonas Orelandc99dc312018-03-28 08:00:50 +0200746 bool turn_port_closed_;
747 bool turn_port_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000748 bool udp_ready_;
749 bool test_finish_;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800750 bool turn_refresh_success_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000751 std::vector<rtc::Buffer> turn_packets_;
752 std::vector<rtc::Buffer> udp_packets_;
753 rtc::PacketOptions options;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200754 std::unique_ptr<webrtc::TurnCustomizer> turn_customizer_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000755};
756
Honghai Zhangd00c0572016-06-28 09:44:47 -0700757TEST_F(TurnPortTest, TestTurnPortType) {
758 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
759 EXPECT_EQ(cricket::RELAY_PORT_TYPE, turn_port_->Type());
760}
761
zhihuang26d99c22017-02-13 12:47:27 -0800762// Tests that the URL of the servers can be correctly reconstructed when
763// gathering the candidates.
Steve Antoned447ae2017-08-17 14:31:51 -0700764TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv4) {
zhihuang26d99c22017-02-13 12:47:27 -0800765 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700766 TestReconstructedServerUrl(PROTO_UDP, "turn:99.99.99.3:3478?transport=udp");
767}
zhihuang26d99c22017-02-13 12:47:27 -0800768
Steve Antoned447ae2017-08-17 14:31:51 -0700769TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv6) {
zhihuang26d99c22017-02-13 12:47:27 -0800770 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
771 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
772 kTurnUdpIPv6ProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700773 TestReconstructedServerUrl(
774 PROTO_UDP,
775 "turn:2400:4030:1:2c00:be30:abcd:efab:cdef:3478?transport=udp");
776}
zhihuang26d99c22017-02-13 12:47:27 -0800777
Steve Antoned447ae2017-08-17 14:31:51 -0700778TEST_F(TurnPortTest, TestReconstructedServerUrlForTcp) {
zhihuang26d99c22017-02-13 12:47:27 -0800779 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
780 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700781 TestReconstructedServerUrl(PROTO_TCP, "turn:99.99.99.4:3478?transport=tcp");
zhihuang26d99c22017-02-13 12:47:27 -0800782}
783
Steve Anton786de702017-08-17 15:15:46 -0700784TEST_F(TurnPortTest, TestReconstructedServerUrlForTls) {
785 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
786 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
787 TestReconstructedServerUrl(PROTO_TLS, "turns:99.99.99.4:3478?transport=tcp");
788}
789
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000790// Do a normal TURN allocation.
791TEST_F(TurnPortTest, TestTurnAllocate) {
792 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Yves Gerey665174f2018-06-19 15:03:05 +0200793 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000794 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700795 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000796 ASSERT_EQ(1U, turn_port_->Candidates().size());
797 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
798 turn_port_->Candidates()[0].address().ipaddr());
799 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
800}
801
802// Testing a normal UDP allocation using TCP connection.
803TEST_F(TurnPortTest, TestTurnTcpAllocate) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700804 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000805 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Yves Gerey665174f2018-06-19 15:03:05 +0200806 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000807 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700808 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000809 ASSERT_EQ(1U, turn_port_->Candidates().size());
810 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
811 turn_port_->Candidates()[0].address().ipaddr());
812 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
813}
814
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000815// Test case for WebRTC issue 3927 where a proxy binds to the local host address
816// instead the address that TurnPort originally bound to. The candidate pair
817// impacted by this behavior should still be used.
818TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
deadbeef5c3c1042017-08-04 15:01:57 -0700819 SocketAddress local_address("127.0.0.1", 0);
820 // After calling this, when TurnPort attempts to get a socket bound to
821 // kLocalAddr, it will end up using localhost instead.
822 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), local_address.ipaddr());
823
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700824 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef5c3c1042017-08-04 15:01:57 -0700825 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000826 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
827 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700828 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000829 ASSERT_EQ(1U, turn_port_->Candidates().size());
830 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
831 turn_port_->Candidates()[0].address().ipaddr());
832 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
deadbeef5c3c1042017-08-04 15:01:57 -0700833
834 // Verify that the socket actually used localhost, otherwise this test isn't
835 // doing what it meant to.
836 ASSERT_EQ(local_address.ipaddr(),
837 turn_port_->Candidates()[0].related_address().ipaddr());
838}
839
840// If the address the socket ends up bound to does not match any address of the
841// TurnPort's Network, then the socket should be discarded and no candidates
842// should be signaled. In the context of ICE, where one TurnPort is created for
843// each Network, when this happens it's likely that the unexpected address is
844// associated with some other Network, which another TurnPort is already
845// covering.
846TEST_F(TurnPortTest,
847 TurnTcpAllocationDiscardedIfBoundAddressDoesNotMatchNetwork) {
848 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
849 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
850
851 // Set up TURN server to use TCP (this logic only exists for TCP).
852 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
853
854 // Create TURN port and tell it to start allocation.
855 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
856 turn_port_->PrepareAddress();
857
858 // Shouldn't take more than 1 RTT to realize the bound address isn't the one
859 // expected.
860 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
861}
862
863// A caveat for the above logic: if the socket ends up bound to one of the IPs
864// associated with the Network, just not the "best" one, this is ok.
865TEST_F(TurnPortTest, TurnTcpAllocationNotDiscardedIfNotBoundToBestIP) {
866 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
867 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
868
869 // Set up a network with kLocalAddr1 as the "best" IP, and kLocalAddr2 as an
870 // alternate.
871 rtc::Network* network = MakeNetwork(kLocalAddr1);
872 network->AddIP(kLocalAddr2.ipaddr());
873 ASSERT_EQ(kLocalAddr1.ipaddr(), network->GetBestIP());
874
875 // Set up TURN server to use TCP (this logic only exists for TCP).
876 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
877
878 // Create TURN port using our special Network, and tell it to start
879 // allocation.
880 CreateTurnPortWithNetwork(network, kTurnUsername, kTurnPassword,
881 kTurnTcpProtoAddr);
882 turn_port_->PrepareAddress();
883
884 // Candidate should be gathered as normally.
885 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
886 ASSERT_EQ(1U, turn_port_->Candidates().size());
887
888 // Verify that the socket actually used the alternate address, otherwise this
889 // test isn't doing what it meant to.
890 ASSERT_EQ(kLocalAddr2.ipaddr(),
891 turn_port_->Candidates()[0].related_address().ipaddr());
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000892}
893
Taylor Brandstetter01cb5f22018-03-07 15:49:32 -0800894// Regression test for crbug.com/webrtc/8972, caused by buggy comparison
895// between rtc::IPAddress and rtc::InterfaceAddress.
896TEST_F(TurnPortTest, TCPPortNotDiscardedIfBoundToTemporaryIP) {
897 networks_.emplace_back("unittest", "unittest", kLocalIPv6Addr.ipaddr(), 32);
898 networks_.back().AddIP(rtc::InterfaceAddress(
899 kLocalIPv6Addr.ipaddr(), rtc::IPV6_ADDRESS_FLAG_TEMPORARY));
900
901 // Set up TURN server to use TCP (this logic only exists for TCP).
902 turn_server_.AddInternalSocket(kTurnIPv6IntAddr, PROTO_TCP);
903
904 // Create TURN port using our special Network, and tell it to start
905 // allocation.
906 CreateTurnPortWithNetwork(
907 &networks_.back(), kTurnUsername, kTurnPassword,
908 cricket::ProtocolAddress(kTurnIPv6IntAddr, PROTO_TCP));
909 turn_port_->PrepareAddress();
910
911 // Candidate should be gathered as normally.
912 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
913 ASSERT_EQ(1U, turn_port_->Candidates().size());
914}
915
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000916// Testing turn port will attempt to create TCP socket on address resolution
917// failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700918TEST_F(TurnPortTest, TestTurnTcpOnAddressResolveFailure) {
919 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
920 CreateTurnPort(kTurnUsername, kTurnPassword,
921 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
922 PROTO_TCP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000923 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700924 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000925 // As VSS doesn't provide a DNS resolution, name resolve will fail. TurnPort
926 // will proceed in creating a TCP socket which will fail as there is no
927 // server on the above domain and error will be set to SOCKET_ERROR.
928 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
929}
930
Steve Anton786de702017-08-17 15:15:46 -0700931// Testing turn port will attempt to create TLS socket on address resolution
932// failure.
933TEST_F(TurnPortTest, TestTurnTlsOnAddressResolveFailure) {
934 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
935 CreateTurnPort(kTurnUsername, kTurnPassword,
936 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
937 PROTO_TLS));
938 turn_port_->PrepareAddress();
939 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
940 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
941}
942
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000943// In case of UDP on address resolve failure, TurnPort will not create socket
944// and return allocate failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700945TEST_F(TurnPortTest, TestTurnUdpOnAddressResolveFailure) {
946 CreateTurnPort(kTurnUsername, kTurnPassword,
947 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
948 PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000949 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700950 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000951 // Error from turn port will not be socket error.
952 EXPECT_NE(SOCKET_ERROR, turn_port_->error());
953}
954
955// Try to do a TURN allocation with an invalid password.
956TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
957 CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
958 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700959 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000960 ASSERT_EQ(0U, turn_port_->Candidates().size());
961}
962
honghaizc463e202016-02-01 15:19:08 -0800963// Tests that TURN port nonce will be reset when receiving an ALLOCATE MISMATCH
964// error.
965TEST_F(TurnPortTest, TestTurnAllocateNonceResetAfterAllocateMismatch) {
966 // Do a normal allocation first.
967 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
968 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700969 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -0800970 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
971 // Destroy the turnport while keeping the drop probability to 1 to
972 // suppress the release of the allocation at the server.
973 ss_->set_drop_probability(1.0);
974 turn_port_.reset();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700975 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -0800976 ss_->set_drop_probability(0.0);
977
978 // Force the socket server to assign the same port.
979 ss_->SetNextPortForTesting(first_addr.port());
980 turn_ready_ = false;
981 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
982
983 // It is expected that the turn port will first get a nonce from the server
984 // using timestamp |ts_before| but then get an allocate mismatch error and
985 // receive an even newer nonce based on the system clock. |ts_before| is
986 // chosen so that the two NONCEs generated by the server will be different.
nisse1bffc1d2016-05-02 08:18:55 -0700987 int64_t ts_before = rtc::TimeMillis() - 1;
honghaizc463e202016-02-01 15:19:08 -0800988 std::string first_nonce =
989 turn_server_.server()->SetTimestampForNextNonce(ts_before);
990 turn_port_->PrepareAddress();
991
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700992 // Four round trips; first we'll get "stale nonce", then
993 // "allocate mismatch", then "stale nonce" again, then finally it will
994 // succeed.
995 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -0800996 EXPECT_NE(first_nonce, turn_port_->nonce());
997}
998
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000999// Tests that a new local address is created after
1000// STUN_ERROR_ALLOCATION_MISMATCH.
1001TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
1002 // Do a normal allocation first.
1003 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1004 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001005 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001006 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1007
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001008 // Clear connected_ flag on turnport to suppress the release of
1009 // the allocation.
1010 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1011
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001012 // Forces the socket server to assign the same port.
1013 ss_->SetNextPortForTesting(first_addr.port());
1014
1015 turn_ready_ = false;
1016 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1017 turn_port_->PrepareAddress();
1018
1019 // Verifies that the new port has the same address.
1020 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1021
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001022 // Four round trips; first we'll get "stale nonce", then
1023 // "allocate mismatch", then "stale nonce" again, then finally it will
1024 // succeed.
1025 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001026
1027 // Verifies that the new port has a different address now.
1028 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
Sergey Ulanov17fa6722016-05-10 10:20:47 -07001029
1030 // Verify that all packets received from the shared socket are ignored.
1031 std::string test_packet = "Test packet";
1032 EXPECT_FALSE(turn_port_->HandleIncomingPacket(
1033 socket_.get(), test_packet.data(), test_packet.size(),
1034 rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0),
1035 rtc::CreatePacketTime(0)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001036}
1037
1038// Tests that a shared-socket-TurnPort creates its own socket after
1039// STUN_ERROR_ALLOCATION_MISMATCH.
1040TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
1041 // Do a normal allocation first.
1042 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1043 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001044 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001045 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1046
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001047 // Clear connected_ flag on turnport to suppress the release of
1048 // the allocation.
1049 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1050
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001051 turn_ready_ = false;
1052 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1053
1054 // Verifies that the new port has the same address.
1055 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1056 EXPECT_TRUE(turn_port_->SharedSocket());
1057
1058 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001059 // Extra 2 round trips due to allocate mismatch.
1060 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001061
1062 // Verifies that the new port has a different address now.
1063 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1064 EXPECT_FALSE(turn_port_->SharedSocket());
1065}
1066
1067TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001068 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001069 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1070
1071 // Do a normal allocation first.
1072 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001073 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001074 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1075
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001076 // Clear connected_ flag on turnport to suppress the release of
1077 // the allocation.
1078 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1079
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001080 // Forces the socket server to assign the same port.
1081 ss_->SetNextPortForTesting(first_addr.port());
1082
1083 turn_ready_ = false;
1084 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1085 turn_port_->PrepareAddress();
1086
1087 // Verifies that the new port has the same address.
1088 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1089
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001090 // Extra 2 round trips due to allocate mismatch.
1091 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 5, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001092
1093 // Verifies that the new port has a different address now.
1094 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1095}
1096
Honghai Zhangf67c5482015-12-11 15:16:54 -08001097TEST_F(TurnPortTest, TestRefreshRequestGetsErrorResponse) {
1098 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001099 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz6b9ab922016-01-05 09:06:12 -08001100 turn_port_->CreateConnection(udp_port_->Candidates()[0],
1101 Port::ORIGIN_MESSAGE);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001102 // Set bad credentials.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001103 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001104 turn_port_->set_credentials(bad_credentials);
1105 turn_refresh_success_ = false;
1106 // This sends out the first RefreshRequest with correct credentials.
1107 // When this succeeds, it will schedule a new RefreshRequest with the bad
1108 // credential.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001109 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1110 EXPECT_TRUE_SIMULATED_WAIT(turn_refresh_success_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001111 // Flush it again, it will receive a bad response.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001112 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1113 EXPECT_TRUE_SIMULATED_WAIT(!turn_refresh_success_, kSimulatedRtt,
1114 fake_clock_);
1115 EXPECT_FALSE(turn_port_->connected());
1116 EXPECT_TRUE(CheckAllConnectionsFailedAndPruned());
1117 EXPECT_FALSE(turn_port_->HasRequests());
Honghai Zhangf67c5482015-12-11 15:16:54 -08001118}
1119
honghaiz9dfed792016-01-29 13:22:31 -08001120// Test that TurnPort will not handle any incoming packets once it has been
1121// closed.
1122TEST_F(TurnPortTest, TestStopProcessingPacketsAfterClosed) {
1123 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001124 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz9dfed792016-01-29 13:22:31 -08001125 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1126 Port::ORIGIN_MESSAGE);
1127 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1128 Port::ORIGIN_MESSAGE);
1129 ASSERT_TRUE(conn1 != NULL);
1130 ASSERT_TRUE(conn2 != NULL);
1131 // Make sure conn2 is writable.
1132 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001133 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
1134 kSimulatedRtt * 2, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001135
1136 turn_port_->Close();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001137 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001138 turn_unknown_address_ = false;
1139 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001140 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001141 // Since the turn port does not handle packets any more, it should not
1142 // SignalUnknownAddress.
1143 EXPECT_FALSE(turn_unknown_address_);
1144}
1145
honghaizb19eba32015-08-03 10:23:31 -07001146// Test that CreateConnection will return null if port becomes disconnected.
1147TEST_F(TurnPortTest, TestCreateConnectionWhenSocketClosed) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001148 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001149 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001150 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001151 // Create a connection.
1152 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1153 Port::ORIGIN_MESSAGE);
1154 ASSERT_TRUE(conn1 != NULL);
1155
1156 // Close the socket and create a connection again.
1157 turn_port_->OnSocketClose(turn_port_->socket(), 1);
1158 conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1159 Port::ORIGIN_MESSAGE);
1160 ASSERT_TRUE(conn1 == NULL);
1161}
1162
honghaiz079a7a12016-06-22 16:26:29 -07001163// Tests that when a TCP socket is closed, the respective TURN connection will
1164// be destroyed.
1165TEST_F(TurnPortTest, TestSocketCloseWillDestroyConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001166 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001167 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001168 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001169 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1170 Port::ORIGIN_MESSAGE);
1171 EXPECT_NE(nullptr, conn);
1172 EXPECT_TRUE(!turn_port_->connections().empty());
1173 turn_port_->socket()->SignalClose(turn_port_->socket(), 1);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001174 EXPECT_TRUE_SIMULATED_WAIT(turn_port_->connections().empty(),
1175 kConnectionDestructionDelay, fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001176}
1177
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001178// Test try-alternate-server feature.
1179TEST_F(TurnPortTest, TestTurnAlternateServerUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001180 TestTurnAlternateServer(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001181}
1182
1183TEST_F(TurnPortTest, TestTurnAlternateServerTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001184 TestTurnAlternateServer(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001185}
1186
Steve Anton786de702017-08-17 15:15:46 -07001187TEST_F(TurnPortTest, TestTurnAlternateServerTLS) {
1188 TestTurnAlternateServer(PROTO_TLS);
1189}
1190
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001191// Test that we fail when we redirect to an address different from
1192// current IP family.
1193TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6UDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001194 TestTurnAlternateServerV4toV6(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001195}
1196
1197TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001198 TestTurnAlternateServerV4toV6(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001199}
1200
Steve Anton786de702017-08-17 15:15:46 -07001201TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TLS) {
1202 TestTurnAlternateServerV4toV6(PROTO_TLS);
1203}
1204
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001205// Test try-alternate-server catches the case of pingpong.
1206TEST_F(TurnPortTest, TestTurnAlternateServerPingPongUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001207 TestTurnAlternateServerPingPong(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001208}
1209
1210TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001211 TestTurnAlternateServerPingPong(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001212}
1213
Steve Anton786de702017-08-17 15:15:46 -07001214TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTLS) {
1215 TestTurnAlternateServerPingPong(PROTO_TLS);
1216}
1217
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001218// Test try-alternate-server catch the case of repeated server.
1219TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001220 TestTurnAlternateServerDetectRepetition(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001221}
1222
1223TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001224 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001225}
1226
Steve Anton786de702017-08-17 15:15:46 -07001227TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTLS) {
1228 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
1229}
1230
deadbeeffb70b452016-10-24 13:15:59 -07001231// Test catching the case of a redirect to loopback.
1232TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv4) {
1233 TestTurnAlternateServerLoopback(PROTO_UDP, false);
1234}
1235
1236TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv6) {
1237 TestTurnAlternateServerLoopback(PROTO_UDP, true);
1238}
1239
1240TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv4) {
1241 TestTurnAlternateServerLoopback(PROTO_TCP, false);
1242}
1243
1244TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv6) {
1245 TestTurnAlternateServerLoopback(PROTO_TCP, true);
1246}
1247
Steve Anton786de702017-08-17 15:15:46 -07001248TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv4) {
1249 TestTurnAlternateServerLoopback(PROTO_TLS, false);
1250}
1251
1252TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv6) {
1253 TestTurnAlternateServerLoopback(PROTO_TLS, true);
1254}
1255
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001256// Do a TURN allocation and try to send a packet to it from the outside.
1257// The packet should be dropped. Then, try to send a packet from TURN to the
1258// outside. It should reach its destination. Finally, try again from the
1259// outside. It should now work as well.
1260TEST_F(TurnPortTest, TestTurnConnection) {
1261 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001262 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001263}
1264
1265// Similar to above, except that this test will use the shared socket.
1266TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
1267 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001268 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001269}
1270
1271// Test that we can establish a TCP connection with TURN server.
1272TEST_F(TurnPortTest, TestTurnTcpConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001273 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001274 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001275 TestTurnConnection(PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001276}
1277
Steve Anton786de702017-08-17 15:15:46 -07001278// Test that we can establish a TLS connection with TURN server.
1279TEST_F(TurnPortTest, TestTurnTlsConnection) {
1280 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1281 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1282 TestTurnConnection(PROTO_TLS);
1283}
1284
honghaiz32f39962015-11-17 11:36:31 -08001285// Test that if a connection on a TURN port is destroyed, the TURN port can
1286// still receive ping on that connection as if it is from an unknown address.
1287// If the connection is created again, it will be used to receive ping.
1288TEST_F(TurnPortTest, TestDestroyTurnConnection) {
1289 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1290 TestDestroyTurnConnection();
1291}
1292
1293// Similar to above, except that this test will use the shared socket.
1294TEST_F(TurnPortTest, TestDestroyTurnConnectionUsingSharedSocket) {
1295 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1296 TestDestroyTurnConnection();
1297}
1298
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001299// Run TurnConnectionTest with one-time-use nonce feature.
1300// Here server will send a 438 STALE_NONCE error message for
1301// every TURN transaction.
1302TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
1303 turn_server_.set_enable_otu_nonce(true);
1304 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001305 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001306}
1307
Honghai Zhang85975432015-11-12 11:07:12 -08001308// Test that CreatePermissionRequest will be scheduled after the success
Honghai Zhangf67c5482015-12-11 15:16:54 -08001309// of the first create permission request and the request will get an
1310// ErrorResponse if the ufrag and pwd are incorrect.
Honghai Zhang85975432015-11-12 11:07:12 -08001311TEST_F(TurnPortTest, TestRefreshCreatePermissionRequest) {
1312 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001313 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhang85975432015-11-12 11:07:12 -08001314
1315 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1316 Port::ORIGIN_MESSAGE);
1317 ASSERT_TRUE(conn != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001318 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1319 fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001320 turn_create_permission_success_ = false;
1321 // A create-permission-request should be pending.
Honghai Zhangf67c5482015-12-11 15:16:54 -08001322 // After the next create-permission-response is received, it will schedule
1323 // another request with bad_ufrag and bad_pwd.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001324 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001325 turn_port_->set_credentials(bad_credentials);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001326 turn_port_->FlushRequests(kAllRequests);
1327 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1328 fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001329 // Flush the requests again; the create-permission-request will fail.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001330 turn_port_->FlushRequests(kAllRequests);
1331 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1332 fake_clock_);
1333 EXPECT_TRUE(CheckConnectionFailedAndPruned(conn));
Honghai Zhangf67c5482015-12-11 15:16:54 -08001334}
1335
1336TEST_F(TurnPortTest, TestChannelBindGetErrorResponse) {
1337 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001338 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001339 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1340 Port::ORIGIN_MESSAGE);
1341 ASSERT_TRUE(conn1 != nullptr);
1342 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1343 Port::ORIGIN_MESSAGE);
Honghai Zhang3d77deb2016-06-22 15:22:22 -07001344
honghaiz079a7a12016-06-22 16:26:29 -07001345 ASSERT_TRUE(conn2 != nullptr);
1346 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001347 EXPECT_TRUE_SIMULATED_WAIT(conn1->writable(), kSimulatedRtt * 2, fake_clock_);
1348 // TODO(deadbeef): SetEntryChannelId should not be a public method.
1349 // Instead we should set an option on the fake TURN server to force it to
1350 // send a channel bind errors.
1351 ASSERT_TRUE(
1352 turn_port_->SetEntryChannelId(udp_port_->Candidates()[0].address(), -1));
honghaiz079a7a12016-06-22 16:26:29 -07001353
1354 std::string data = "ABC";
1355 conn1->Send(data.data(), data.length(), options);
1356
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001357 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn1),
1358 kSimulatedRtt, fake_clock_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001359 // Verify that packets are allowed to be sent after a bind request error.
1360 // They'll just use a send indication instead.
honghaiz079a7a12016-06-22 16:26:29 -07001361 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
1362 &TurnPortTest::OnUdpReadPacket);
1363 conn1->Send(data.data(), data.length(), options);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001364 EXPECT_TRUE_SIMULATED_WAIT(!udp_packets_.empty(), kSimulatedRtt, fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001365}
1366
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001367// Do a TURN allocation, establish a UDP connection, and send some data.
1368TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
1369 // Create ports and prepare addresses.
1370 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001371 TestTurnSendData(PROTO_UDP);
1372 EXPECT_EQ(UDP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001373}
1374
1375// Do a TURN allocation, establish a TCP connection, and send some data.
1376TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001377 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001378 // Create ports and prepare addresses.
1379 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001380 TestTurnSendData(PROTO_TCP);
1381 EXPECT_EQ(TCP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001382}
1383
Steve Anton786de702017-08-17 15:15:46 -07001384// Do a TURN allocation, establish a TLS connection, and send some data.
1385TEST_F(TurnPortTest, TestTurnSendDataTurnTlsToUdp) {
1386 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1387 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1388 TestTurnSendData(PROTO_TLS);
1389 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1390}
1391
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001392// Test TURN fails to make a connection from IPv6 address to a server which has
1393// IPv4 address.
1394TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001395 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001396 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1397 kTurnUdpProtoAddr);
1398 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001399 ASSERT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001400 EXPECT_TRUE(turn_port_->Candidates().empty());
1401}
1402
1403// Test TURN make a connection from IPv6 address to a server which has
1404// IPv6 intenal address. But in this test external address is a IPv4 address,
1405// hence allocated address will be a IPv4 address.
1406TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001407 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001408 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1409 kTurnUdpIPv6ProtoAddr);
1410 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001411 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001412 ASSERT_EQ(1U, turn_port_->Candidates().size());
1413 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
1414 turn_port_->Candidates()[0].address().ipaddr());
1415 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
1416}
1417
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001418// Tests that the local and remote candidate address families should match when
1419// a connection is created. Specifically, if a TURN port has an IPv6 address,
1420// its local candidate will still be an IPv4 address and it can only create
1421// connections with IPv4 remote candidates.
1422TEST_F(TurnPortTest, TestCandidateAddressFamilyMatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001423 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001424
1425 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1426 kTurnUdpIPv6ProtoAddr);
1427 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001428 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001429 ASSERT_EQ(1U, turn_port_->Candidates().size());
1430
1431 // Create an IPv4 candidate. It will match the TURN candidate.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001432 Candidate remote_candidate(ICE_CANDIDATE_COMPONENT_RTP, "udp", kLocalAddr2, 0,
1433 "", "", "local", 0, kCandidateFoundation);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001434 remote_candidate.set_address(kLocalAddr2);
1435 Connection* conn =
1436 turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1437 EXPECT_NE(nullptr, conn);
1438
1439 // Set the candidate address family to IPv6. It won't match the TURN
1440 // candidate.
1441 remote_candidate.set_address(kLocalIPv6Addr2);
1442 conn = turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1443 EXPECT_EQ(nullptr, conn);
1444}
1445
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001446TEST_F(TurnPortTest, TestOriginHeader) {
1447 CreateTurnPortWithOrigin(kLocalAddr1, kTurnUsername, kTurnPassword,
1448 kTurnUdpProtoAddr, kTestOrigin);
1449 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001450 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001451 ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
1452 SocketAddress local_address = turn_port_->GetLocalAddress();
1453 ASSERT_TRUE(turn_server_.FindAllocation(local_address) != NULL);
1454 EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
1455}
1456
deadbeef376e1232015-11-25 09:00:08 -08001457// Test that a CreatePermission failure will result in the connection being
honghaiz079a7a12016-06-22 16:26:29 -07001458// pruned and failed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001459TEST_F(TurnPortTest, TestConnectionFailedAndPrunedOnCreatePermissionFailure) {
1460 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef376e1232015-11-25 09:00:08 -08001461 turn_server_.server()->set_reject_private_addresses(true);
1462 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1463 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001464 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001465
1466 CreateUdpPort(SocketAddress("10.0.0.10", 0));
1467 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001468 EXPECT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001469 // Create a connection.
1470 TestConnectionWrapper conn(turn_port_->CreateConnection(
1471 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE));
honghaiz079a7a12016-06-22 16:26:29 -07001472 EXPECT_TRUE(conn.connection() != nullptr);
deadbeef376e1232015-11-25 09:00:08 -08001473
honghaiz079a7a12016-06-22 16:26:29 -07001474 // Asynchronously, CreatePermission request should be sent and fail, which
1475 // will make the connection pruned and failed.
1476 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn.connection()),
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001477 kSimulatedRtt, fake_clock_);
1478 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1479 fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001480 // Check that the connection is not deleted asynchronously.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001481 SIMULATED_WAIT(conn.connection() == nullptr, kConnectionDestructionDelay,
1482 fake_clock_);
1483 EXPECT_NE(nullptr, conn.connection());
deadbeef376e1232015-11-25 09:00:08 -08001484}
1485
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001486// Test that a TURN allocation is released when the port is closed.
1487TEST_F(TurnPortTest, TestTurnReleaseAllocation) {
1488 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001489 TestTurnReleaseAllocation(PROTO_UDP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001490}
1491
1492// Test that a TURN TCP allocation is released when the port is closed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001493TEST_F(TurnPortTest, TestTurnTCPReleaseAllocation) {
1494 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001495 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001496 TestTurnReleaseAllocation(PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001497}
1498
Steve Anton786de702017-08-17 15:15:46 -07001499TEST_F(TurnPortTest, TestTurnTLSReleaseAllocation) {
1500 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1501 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1502 TestTurnReleaseAllocation(PROTO_TLS);
1503}
1504
Jonas Orelandc99dc312018-03-28 08:00:50 +02001505TEST_F(TurnPortTest, TestTurnUDPGracefulReleaseAllocation) {
1506 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_UDP);
1507 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1508 TestTurnGracefulReleaseAllocation(PROTO_UDP);
1509}
1510
1511TEST_F(TurnPortTest, TestTurnTCPGracefulReleaseAllocation) {
1512 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
1513 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1514 TestTurnGracefulReleaseAllocation(PROTO_TCP);
1515}
1516
1517TEST_F(TurnPortTest, TestTurnTLSGracefulReleaseAllocation) {
1518 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1519 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1520 TestTurnGracefulReleaseAllocation(PROTO_TLS);
1521}
1522
Taylor Brandstetterd65ae4a2017-10-08 11:46:15 -07001523// Test that nothing bad happens if we try to create a connection to the same
1524// remote address twice. Previously there was a bug that caused this to hit a
1525// DCHECK.
1526TEST_F(TurnPortTest, CanCreateTwoConnectionsToSameAddress) {
1527 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1528 PrepareTurnAndUdpPorts(PROTO_UDP);
1529 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1530 Port::ORIGIN_MESSAGE);
1531 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1532 Port::ORIGIN_MESSAGE);
1533 EXPECT_NE(conn1, conn2);
1534}
1535
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001536// This test verifies any FD's are not leaked after TurnPort is destroyed.
1537// https://code.google.com/p/webrtc/issues/detail?id=2651
1538#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001539
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001540TEST_F(TurnPortTest, TestResolverShutdown) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001541 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001542 int last_fd_count = GetFDCount();
1543 // Need to supply unresolved address to kick off resolver.
1544 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001545 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
1546 PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001547 turn_port_->PrepareAddress();
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001548 ASSERT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001549 EXPECT_TRUE(turn_port_->Candidates().empty());
1550 turn_port_.reset();
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001551 rtc::Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001552 // Waiting for above message to be processed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001553 ASSERT_TRUE_SIMULATED_WAIT(test_finish_, 1, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001554 EXPECT_EQ(last_fd_count, GetFDCount());
1555}
1556#endif
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001557
Yves Gerey665174f2018-06-19 15:03:05 +02001558class MessageObserver : public StunMessageObserver {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001559 public:
Yves Gerey665174f2018-06-19 15:03:05 +02001560 MessageObserver(unsigned int* message_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001561 unsigned int* channel_data_counter,
Yves Gerey665174f2018-06-19 15:03:05 +02001562 unsigned int* attr_counter)
Jonas Orelandbdcee282017-10-10 14:01:40 +02001563 : message_counter_(message_counter),
1564 channel_data_counter_(channel_data_counter),
1565 attr_counter_(attr_counter) {}
1566 virtual ~MessageObserver() {}
Steve Anton6c38cc72017-11-29 10:25:58 -08001567 void ReceivedMessage(const TurnMessage* msg) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001568 if (message_counter_ != nullptr) {
1569 (*message_counter_)++;
1570 }
1571 // Implementation defined attributes are returned as ByteString
Yves Gerey665174f2018-06-19 15:03:05 +02001572 const StunByteStringAttribute* attr =
1573 msg->GetByteString(TestTurnCustomizer::STUN_ATTR_COUNTER);
Jonas Orelandbdcee282017-10-10 14:01:40 +02001574 if (attr != nullptr && attr_counter_ != nullptr) {
1575 rtc::ByteBufferReader buf(attr->bytes(), attr->length());
1576 unsigned int val = ~0u;
1577 buf.ReadUInt32(&val);
1578 (*attr_counter_)++;
1579 }
1580 }
1581
Steve Anton6c38cc72017-11-29 10:25:58 -08001582 void ReceivedChannelData(const char* data, size_t size) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001583 if (channel_data_counter_ != nullptr) {
1584 (*channel_data_counter_)++;
1585 }
1586 }
1587
1588 // Number of TurnMessages observed.
1589 unsigned int* message_counter_ = nullptr;
1590
1591 // Number of channel data observed.
1592 unsigned int* channel_data_counter_ = nullptr;
1593
1594 // Number of TurnMessages that had STUN_ATTR_COUNTER.
1595 unsigned int* attr_counter_ = nullptr;
1596};
1597
1598// Do a TURN allocation, establish a TLS connection, and send some data.
1599// Add customizer and check that it get called.
1600TEST_F(TurnPortTest, TestTurnCustomizerCount) {
1601 unsigned int observer_message_counter = 0;
1602 unsigned int observer_channel_data_counter = 0;
1603 unsigned int observer_attr_counter = 0;
1604 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1605 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001606 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001607 &observer_attr_counter));
1608
1609 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1610 turn_customizer_.reset(customizer);
1611 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1612
1613 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1614 TestTurnSendData(PROTO_TLS);
1615 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1616
1617 // There should have been at least turn_packets_.size() calls to |customizer|.
1618 EXPECT_GE(customizer->modify_cnt_ + customizer->allow_channel_data_cnt_,
1619 turn_packets_.size());
1620
1621 // Some channel data should be received.
1622 EXPECT_GE(observer_channel_data_counter, 0u);
1623
1624 // Need to release TURN port before the customizer.
1625 turn_port_.reset(nullptr);
1626}
1627
1628// Do a TURN allocation, establish a TLS connection, and send some data.
1629// Add customizer and check that it can can prevent usage of channel data.
1630TEST_F(TurnPortTest, TestTurnCustomizerDisallowChannelData) {
1631 unsigned int observer_message_counter = 0;
1632 unsigned int observer_channel_data_counter = 0;
1633 unsigned int observer_attr_counter = 0;
1634 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1635 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001636 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001637 &observer_attr_counter));
1638 customizer->allow_channel_data_ = false;
1639 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1640 turn_customizer_.reset(customizer);
1641 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1642
1643 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1644 TestTurnSendData(PROTO_TLS);
1645 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1646
1647 // There should have been at least turn_packets_.size() calls to |customizer|.
1648 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1649
1650 // No channel data should be received.
1651 EXPECT_EQ(observer_channel_data_counter, 0u);
1652
1653 // Need to release TURN port before the customizer.
1654 turn_port_.reset(nullptr);
1655}
1656
1657// Do a TURN allocation, establish a TLS connection, and send some data.
1658// Add customizer and check that it can add attribute to messages.
1659TEST_F(TurnPortTest, TestTurnCustomizerAddAttribute) {
1660 unsigned int observer_message_counter = 0;
1661 unsigned int observer_channel_data_counter = 0;
1662 unsigned int observer_attr_counter = 0;
1663 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1664 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001665 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001666 &observer_attr_counter));
1667 customizer->allow_channel_data_ = false;
1668 customizer->add_counter_ = true;
1669 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1670 turn_customizer_.reset(customizer);
1671 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1672
1673 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1674 TestTurnSendData(PROTO_TLS);
1675 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1676
1677 // There should have been at least turn_packets_.size() calls to |customizer|.
1678 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1679
1680 // Everything will be sent as messages since channel data is disallowed.
1681 EXPECT_GE(customizer->modify_cnt_, observer_message_counter);
1682
1683 // All messages should have attribute.
1684 EXPECT_EQ(observer_message_counter, observer_attr_counter);
1685
1686 // At least allow_channel_data_cnt_ messages should have been sent.
1687 EXPECT_GE(customizer->modify_cnt_, customizer->allow_channel_data_cnt_);
1688 EXPECT_GE(customizer->allow_channel_data_cnt_, 0u);
1689
1690 // No channel data should be received.
1691 EXPECT_EQ(observer_channel_data_counter, 0u);
1692
1693 // Need to release TURN port before the customizer.
1694 turn_port_.reset(nullptr);
1695}
1696
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001697} // namespace cricket