blob: bd88bd107c368ee4b94f19ed3b02e1e7dc692666 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "p2p/base/basicpacketsocketfactory.h"
20#include "p2p/base/p2pconstants.h"
21#include "p2p/base/portallocator.h"
22#include "p2p/base/tcpport.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020023#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "p2p/base/testturnserver.h"
25#include "p2p/base/turnport.h"
26#include "p2p/base/udpport.h"
27#include "rtc_base/asynctcpsocket.h"
28#include "rtc_base/buffer.h"
29#include "rtc_base/checks.h"
30#include "rtc_base/dscp.h"
31#include "rtc_base/fakeclock.h"
32#include "rtc_base/firewallsocketserver.h"
33#include "rtc_base/gunit.h"
34#include "rtc_base/helpers.h"
35#include "rtc_base/logging.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020036#include "rtc_base/ptr_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#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);
47static const SocketAddress kLocalIPv6Addr(
48 "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -070049static const SocketAddress kLocalIPv6Addr2(
50 "2401:fa00:4:2000:be30:5bff:fee5:d4", 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(
64 "2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -070066static const char kCandidateFoundation[] = "foundation";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067static const char kIceUfrag1[] = "TESTICEUFRAG0001";
68static const char kIceUfrag2[] = "TESTICEUFRAG0002";
69static const char kIcePwd1[] = "TESTICEPWD00000000000001";
70static const char kIcePwd2[] = "TESTICEPWD00000000000002";
71static const char kTurnUsername[] = "test";
72static const char kTurnPassword[] = "test";
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000073static const char kTestOrigin[] = "http://example.com";
Taylor Brandstetter716d07a2016-06-27 14:07:41 -070074// This test configures the virtual socket server to simulate delay so that we
75// can verify operations take no more than the expected number of round trips.
76static constexpr unsigned int kSimulatedRtt = 50;
77// Connection destruction may happen asynchronously, but it should only
78// take one simulated clock tick.
79static constexpr unsigned int kConnectionDestructionDelay = 1;
80// This used to be 1 second, but that's not always enough for getaddrinfo().
81// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5191
82static constexpr unsigned int kResolverTimeout = 10000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083
84static const cricket::ProtocolAddress kTurnUdpProtoAddr(
85 kTurnUdpIntAddr, cricket::PROTO_UDP);
86static const cricket::ProtocolAddress kTurnTcpProtoAddr(
87 kTurnTcpIntAddr, cricket::PROTO_TCP);
hnsl277b2502016-12-13 05:17:23 -080088static const cricket::ProtocolAddress kTurnTlsProtoAddr(kTurnTcpIntAddr,
89 cricket::PROTO_TLS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(
91 kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
92
93static const unsigned int MSG_TESTFINISH = 0;
94
95#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
96static int GetFDCount() {
97 struct dirent *dp;
98 int fd_count = 0;
99 DIR *dir = opendir("/proc/self/fd/");
100 while ((dp = readdir(dir)) != NULL) {
101 if (dp->d_name[0] == '.')
102 continue;
103 ++fd_count;
104 }
105 closedir(dir);
106 return fd_count;
107}
108#endif
109
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700110namespace cricket {
111
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000112class TurnPortTestVirtualSocketServer : public rtc::VirtualSocketServer {
113 public:
deadbeef98e186c2017-05-16 18:00:06 -0700114 TurnPortTestVirtualSocketServer() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700115 // This configures the virtual socket server to always add a simulated
116 // delay of exactly half of kSimulatedRtt.
117 set_delay_mean(kSimulatedRtt / 2);
118 UpdateDelayDistribution();
119 }
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000120
121 using rtc::VirtualSocketServer::LookupBinding;
122};
123
deadbeef376e1232015-11-25 09:00:08 -0800124class TestConnectionWrapper : public sigslot::has_slots<> {
125 public:
Steve Anton6c38cc72017-11-29 10:25:58 -0800126 explicit TestConnectionWrapper(Connection* conn) : connection_(conn) {
deadbeef376e1232015-11-25 09:00:08 -0800127 conn->SignalDestroyed.connect(
128 this, &TestConnectionWrapper::OnConnectionDestroyed);
129 }
130
131 Connection* connection() { return connection_; }
132
133 private:
134 void OnConnectionDestroyed(Connection* conn) {
135 ASSERT_TRUE(conn == connection_);
136 connection_ = nullptr;
137 }
138
139 Connection* connection_;
140};
141
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700142// Note: This test uses a fake clock with a simulated network round trip
143// (between local port and TURN server) of kSimulatedRtt.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000144class TurnPortTest : public testing::Test,
145 public sigslot::has_slots<>,
146 public rtc::MessageHandler {
147 public:
148 TurnPortTest()
deadbeef98e186c2017-05-16 18:00:06 -0700149 : ss_(new TurnPortTestVirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700150 main_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151 socket_factory_(rtc::Thread::Current()),
nisse7eaa4ea2017-05-08 05:25:41 -0700152 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000153 turn_ready_(false),
154 turn_error_(false),
155 turn_unknown_address_(false),
156 turn_create_permission_success_(false),
Jonas Orelandc99dc312018-03-28 08:00:50 +0200157 turn_port_closed_(false),
158 turn_port_destroyed_(false),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159 udp_ready_(false),
160 test_finish_(false) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700161 // Some code uses "last received time == 0" to represent "nothing received
162 // so far", so we need to start the fake clock at a nonzero time...
163 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200164 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165 }
166
167 virtual void OnMessage(rtc::Message* msg) {
nissec8ee8822017-01-18 07:20:55 -0800168 RTC_CHECK(msg->message_id == MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000169 if (msg->message_id == MSG_TESTFINISH)
170 test_finish_ = true;
171 }
172
173 void OnTurnPortComplete(Port* port) {
174 turn_ready_ = true;
175 }
176 void OnTurnPortError(Port* port) {
177 turn_error_ = true;
178 }
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700179 void OnTurnUnknownAddress(PortInterface* port,
180 const SocketAddress& addr,
181 ProtocolType proto,
182 IceMessage* msg,
183 const std::string& rf,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184 bool /*port_muxed*/) {
185 turn_unknown_address_ = true;
186 }
Honghai Zhangf67c5482015-12-11 15:16:54 -0800187 void OnTurnCreatePermissionResult(TurnPort* port,
188 const SocketAddress& addr,
189 int code) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190 // Ignoring the address.
Honghai Zhangf67c5482015-12-11 15:16:54 -0800191 turn_create_permission_success_ = (code == 0);
192 }
193
194 void OnTurnRefreshResult(TurnPort* port, int code) {
195 turn_refresh_success_ = (code == 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000196 }
197 void OnTurnReadPacket(Connection* conn, const char* data, size_t size,
198 const rtc::PacketTime& packet_time) {
199 turn_packets_.push_back(rtc::Buffer(data, size));
200 }
201 void OnUdpPortComplete(Port* port) {
202 udp_ready_ = true;
203 }
204 void OnUdpReadPacket(Connection* conn, const char* data, size_t size,
205 const rtc::PacketTime& packet_time) {
206 udp_packets_.push_back(rtc::Buffer(data, size));
207 }
208 void OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
209 const char* data, size_t size,
210 const rtc::SocketAddress& remote_addr,
211 const rtc::PacketTime& packet_time) {
212 turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
213 packet_time);
214 }
Jonas Orelandc99dc312018-03-28 08:00:50 +0200215 void OnTurnPortClosed(TurnPort* port) {
216 turn_port_closed_ = true;
217 }
218 void OnTurnPortDestroyed(PortInterface* port) {
219 turn_port_destroyed_ = true;
220 }
221
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222 rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
Steve Anton31e5bf52018-05-07 10:42:55 -0700223 rtc::AsyncSocket* socket = ss_->CreateAsyncSocket(AF_INET, SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000224 EXPECT_GE(socket->Bind(addr), 0);
225 EXPECT_GE(socket->Listen(5), 0);
226 return socket;
227 }
228
deadbeef5c3c1042017-08-04 15:01:57 -0700229 rtc::Network* MakeNetwork(const SocketAddress& addr) {
230 networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
231 networks_.back().AddIP(addr.ipaddr());
232 return &networks_.back();
233 }
234
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000235 void CreateTurnPort(const std::string& username,
236 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700237 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700238 CreateTurnPortWithAllParams(MakeNetwork(kLocalAddr1), username, password,
239 server_address, std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000240 }
241 void CreateTurnPort(const rtc::SocketAddress& local_address,
242 const std::string& username,
243 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700244 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700245 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
246 server_address, std::string());
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000247 }
248
249 // Should be identical to CreateTurnPort but specifies an origin value
250 // when creating the instance of TurnPort.
251 void CreateTurnPortWithOrigin(const rtc::SocketAddress& local_address,
252 const std::string& username,
253 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700254 const ProtocolAddress& server_address,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000255 const std::string& origin) {
deadbeef5c3c1042017-08-04 15:01:57 -0700256 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
257 server_address, origin);
258 }
259
260 void CreateTurnPortWithNetwork(rtc::Network* network,
261 const std::string& username,
262 const std::string& password,
263 const ProtocolAddress& server_address) {
264 CreateTurnPortWithAllParams(network, username, password, server_address,
265 std::string());
266 }
267
268 // Version of CreateTurnPort that takes all possible parameters; all other
269 // helper methods call this, such that "SetIceRole" and "ConnectSignals" (and
270 // possibly other things in the future) only happen in one place.
271 void CreateTurnPortWithAllParams(rtc::Network* network,
272 const std::string& username,
273 const std::string& password,
274 const ProtocolAddress& server_address,
275 const std::string& origin) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700276 RelayCredentials credentials(username, password);
Diogo Real1dca9d52017-08-29 12:18:32 -0700277 turn_port_.reset(TurnPort::Create(
278 &main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700279 server_address, credentials, 0, origin, std::vector<std::string>(),
Jonas Orelandbdcee282017-10-10 14:01:40 +0200280 std::vector<std::string>(), turn_customizer_.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000281 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700282 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000283 ConnectSignals();
Steve Anton786de702017-08-17 15:15:46 -0700284
285 if (server_address.proto == cricket::PROTO_TLS) {
286 // The test TURN server has a self-signed certificate so will not pass
287 // the normal client validation. Instruct the client to ignore certificate
288 // errors for testing only.
289 turn_port_->SetTlsCertPolicy(
290 TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
291 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000292 }
293
294 void CreateSharedTurnPort(const std::string& username,
295 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700296 const ProtocolAddress& server_address) {
nissec8ee8822017-01-18 07:20:55 -0800297 RTC_CHECK(server_address.proto == PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000298
299 if (!socket_) {
300 socket_.reset(socket_factory_.CreateUdpSocket(
301 rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
302 ASSERT_TRUE(socket_ != NULL);
303 socket_->SignalReadPacket.connect(
304 this, &TurnPortTest::OnSocketReadPacket);
305 }
306
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700307 RelayCredentials credentials(username, password);
maxmorine9ef9072017-08-29 04:49:00 -0700308 turn_port_.reset(TurnPort::Create(
309 &main_, &socket_factory_, MakeNetwork(kLocalAddr1), socket_.get(),
Jonas Orelandbdcee282017-10-10 14:01:40 +0200310 kIceUfrag1, kIcePwd1, server_address, credentials, 0, std::string(),
311 nullptr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000312 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700313 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000314 ConnectSignals();
315 }
316
317 void ConnectSignals() {
318 turn_port_->SignalPortComplete.connect(this,
319 &TurnPortTest::OnTurnPortComplete);
320 turn_port_->SignalPortError.connect(this,
321 &TurnPortTest::OnTurnPortError);
322 turn_port_->SignalUnknownAddress.connect(this,
323 &TurnPortTest::OnTurnUnknownAddress);
324 turn_port_->SignalCreatePermissionResult.connect(this,
325 &TurnPortTest::OnTurnCreatePermissionResult);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800326 turn_port_->SignalTurnRefreshResult.connect(
327 this, &TurnPortTest::OnTurnRefreshResult);
Jonas Orelandc99dc312018-03-28 08:00:50 +0200328 turn_port_->SignalTurnPortClosed.connect(
329 this, &TurnPortTest::OnTurnPortClosed);
330 turn_port_->SignalDestroyed.connect(
331 this, &TurnPortTest::OnTurnPortDestroyed);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800332 }
deadbeef376e1232015-11-25 09:00:08 -0800333
334 void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
335
336 void CreateUdpPort(const SocketAddress& address) {
Qingsi Wang4ff54432018-03-01 18:25:20 -0800337 udp_port_.reset(UDPPort::Create(
338 &main_, &socket_factory_, MakeNetwork(address), 0, 0, kIceUfrag2,
339 kIcePwd2, std::string(), false, rtc::nullopt));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000340 // UDP port will be controlled.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700341 udp_port_->SetIceRole(ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000342 udp_port_->SignalPortComplete.connect(
343 this, &TurnPortTest::OnUdpPortComplete);
344 }
345
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700346 void PrepareTurnAndUdpPorts(ProtocolType protocol_type) {
Honghai Zhangf67c5482015-12-11 15:16:54 -0800347 // turn_port_ should have been created.
348 ASSERT_TRUE(turn_port_ != nullptr);
349 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700350 ASSERT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700351 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800352
353 CreateUdpPort();
354 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700355 ASSERT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800356 }
357
Steve Antoned447ae2017-08-17 14:31:51 -0700358 // Returns the fake clock time to establish a connection over the given
359 // protocol.
360 int TimeToConnect(ProtocolType protocol_type) {
361 switch (protocol_type) {
362 case PROTO_TCP:
363 // The virtual socket server will delay by a fixed half a round trip
364 // for a TCP connection.
365 return kSimulatedRtt / 2;
Steve Anton786de702017-08-17 15:15:46 -0700366 case PROTO_TLS:
367 // TLS operates over TCP and additionally has a round of HELLO for
368 // negotiating ciphers and a round for exchanging certificates.
369 return 2 * kSimulatedRtt + TimeToConnect(PROTO_TCP);
Steve Antoned447ae2017-08-17 14:31:51 -0700370 case PROTO_UDP:
371 default:
372 // UDP requires no round trips to set up the connection.
373 return 0;
374 }
375 }
376
377 // Returns the total fake clock time to establish a connection with a TURN
378 // server over the given protocol and to allocate a TURN candidate.
379 int TimeToGetTurnCandidate(ProtocolType protocol_type) {
380 // For a simple allocation, the first Allocate message will return with an
381 // error asking for credentials and will succeed after the second Allocate
382 // message.
383 return 2 * kSimulatedRtt + TimeToConnect(protocol_type);
384 }
385
386 // Total fake clock time to do the following:
387 // 1. Connect to primary TURN server
388 // 2. Send Allocate and receive a redirect from the primary TURN server
389 // 3. Connect to alternate TURN server
390 // 4. Send Allocate and receive a request for credentials
391 // 5. Send Allocate with credentials and receive allocation
392 int TimeToGetAlternateTurnCandidate(ProtocolType protocol_type) {
393 return 3 * kSimulatedRtt + 2 * TimeToConnect(protocol_type);
394 }
395
honghaiz079a7a12016-06-22 16:26:29 -0700396 bool CheckConnectionFailedAndPruned(Connection* conn) {
hbos06495bc2017-01-02 08:08:18 -0800397 return conn && !conn->active() &&
398 conn->state() == IceCandidatePairState::FAILED;
honghaiz079a7a12016-06-22 16:26:29 -0700399 }
400
401 // Checks that |turn_port_| has a nonempty set of connections and they are all
402 // failed and pruned.
403 bool CheckAllConnectionsFailedAndPruned() {
404 auto& connections = turn_port_->connections();
405 if (connections.empty()) {
406 return false;
407 }
408 for (auto kv : connections) {
409 if (!CheckConnectionFailedAndPruned(kv.second)) {
410 return false;
411 }
412 }
413 return true;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800414 }
415
Steve Antoned447ae2017-08-17 14:31:51 -0700416 void TestReconstructedServerUrl(ProtocolType protocol_type,
417 const char* expected_url) {
418 turn_port_->PrepareAddress();
419 ASSERT_TRUE_SIMULATED_WAIT(
420 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
421 ASSERT_EQ(1U, turn_port_->Candidates().size());
422 EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_url);
423 }
424
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700425 void TestTurnAlternateServer(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000426 std::vector<rtc::SocketAddress> redirect_addresses;
427 redirect_addresses.push_back(kTurnAlternateIntAddr);
428
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700429 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000430
431 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
432 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
433 turn_server_.set_redirect_hook(&redirector);
434 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700435 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000436
437 // Retrieve the address before we run the state machine.
438 const SocketAddress old_addr = turn_port_->server_address().address;
439
440 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700441 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_,
442 TimeToGetAlternateTurnCandidate(protocol_type),
443 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000444 // Retrieve the address again, the turn port's address should be
445 // changed.
446 const SocketAddress new_addr = turn_port_->server_address().address;
447 EXPECT_NE(old_addr, new_addr);
448 ASSERT_EQ(1U, turn_port_->Candidates().size());
449 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
450 turn_port_->Candidates()[0].address().ipaddr());
451 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
452 }
453
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700454 void TestTurnAlternateServerV4toV6(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000455 std::vector<rtc::SocketAddress> redirect_addresses;
456 redirect_addresses.push_back(kTurnIPv6IntAddr);
457
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700458 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000459 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
460 turn_server_.set_redirect_hook(&redirector);
461 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700462 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000463 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700464 // Need time to connect to TURN server, send Allocate request and receive
465 // redirect notice.
466 EXPECT_TRUE_SIMULATED_WAIT(
467 turn_error_, kSimulatedRtt + TimeToConnect(protocol_type), fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000468 }
469
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700470 void TestTurnAlternateServerPingPong(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000471 std::vector<rtc::SocketAddress> redirect_addresses;
472 redirect_addresses.push_back(kTurnAlternateIntAddr);
473 redirect_addresses.push_back(kTurnIntAddr);
474
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700475 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000476
477 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
478 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
479 turn_server_.set_redirect_hook(&redirector);
480 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700481 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000482
483 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700484 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
485 TimeToGetAlternateTurnCandidate(protocol_type),
486 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000487 ASSERT_EQ(0U, turn_port_->Candidates().size());
488 rtc::SocketAddress address;
489 // Verify that we have exhausted all alternate servers instead of
490 // failure caused by other errors.
491 EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
492 }
493
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700494 void TestTurnAlternateServerDetectRepetition(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000495 std::vector<rtc::SocketAddress> redirect_addresses;
496 redirect_addresses.push_back(kTurnAlternateIntAddr);
497 redirect_addresses.push_back(kTurnAlternateIntAddr);
498
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700499 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000500
501 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
502 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
503 turn_server_.set_redirect_hook(&redirector);
504 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700505 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000506
507 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700508 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
509 TimeToGetAlternateTurnCandidate(protocol_type),
510 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000511 ASSERT_EQ(0U, turn_port_->Candidates().size());
512 }
513
deadbeeffb70b452016-10-24 13:15:59 -0700514 // A certain security exploit works by redirecting to a loopback address,
515 // which doesn't ever actually make sense. So redirects to loopback should
516 // be treated as errors.
517 // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
518 void TestTurnAlternateServerLoopback(ProtocolType protocol_type, bool ipv6) {
519 const SocketAddress& local_address = ipv6 ? kLocalIPv6Addr : kLocalAddr1;
520 const SocketAddress& server_address =
521 ipv6 ? kTurnIPv6IntAddr : kTurnIntAddr;
522
523 std::vector<rtc::SocketAddress> redirect_addresses;
deadbeef99220162016-10-27 18:30:23 -0700524 // Pick an unusual address in the 127.0.0.0/8 range to make sure more than
525 // 127.0.0.1 is covered.
526 SocketAddress loopback_address(ipv6 ? "::1" : "127.1.2.3",
deadbeeffb70b452016-10-24 13:15:59 -0700527 TURN_SERVER_PORT);
528 redirect_addresses.push_back(loopback_address);
529
530 // Make a socket and bind it to the local port, to make extra sure no
531 // packet is sent to this address.
532 std::unique_ptr<rtc::Socket> loopback_socket(ss_->CreateSocket(
Steve Anton31e5bf52018-05-07 10:42:55 -0700533 AF_INET, protocol_type == PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM));
deadbeeffb70b452016-10-24 13:15:59 -0700534 ASSERT_NE(nullptr, loopback_socket.get());
535 ASSERT_EQ(0, loopback_socket->Bind(loopback_address));
536 if (protocol_type == PROTO_TCP) {
537 ASSERT_EQ(0, loopback_socket->Listen(1));
538 }
539
540 TestTurnRedirector redirector(redirect_addresses);
541
542 turn_server_.AddInternalSocket(server_address, protocol_type);
543 turn_server_.set_redirect_hook(&redirector);
544 CreateTurnPort(local_address, kTurnUsername, kTurnPassword,
545 ProtocolAddress(server_address, protocol_type));
546
547 turn_port_->PrepareAddress();
548 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700549 turn_error_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
deadbeeffb70b452016-10-24 13:15:59 -0700550
551 // Wait for some extra time, and make sure no packets were received on the
552 // loopback port we created (or in the case of TCP, no connection attempt
553 // occurred).
554 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
555 if (protocol_type == PROTO_UDP) {
556 char buf[1];
557 EXPECT_EQ(-1, loopback_socket->Recv(&buf, 1, nullptr));
558 } else {
559 std::unique_ptr<rtc::Socket> accepted_socket(
560 loopback_socket->Accept(nullptr));
561 EXPECT_EQ(nullptr, accepted_socket.get());
562 }
563 }
564
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700565 void TestTurnConnection(ProtocolType protocol_type) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000566 // Create ports and prepare addresses.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700567 PrepareTurnAndUdpPorts(protocol_type);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000568
569 // Send ping from UDP to TURN.
Steve Anton786de702017-08-17 15:15:46 -0700570 ASSERT_GE(turn_port_->Candidates().size(), 1U);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000571 Connection* conn1 = udp_port_->CreateConnection(
572 turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
573 ASSERT_TRUE(conn1 != NULL);
574 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700575 SIMULATED_WAIT(!turn_unknown_address_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000576 EXPECT_FALSE(turn_unknown_address_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700577 EXPECT_FALSE(conn1->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000578 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
579
580 // Send ping from TURN to UDP.
581 Connection* conn2 = turn_port_->CreateConnection(
582 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
583 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700584 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
585 fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000586 conn2->Ping(0);
587
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700588 // Two hops from TURN port to UDP port through TURN server, thus two RTTs.
589 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
590 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700591 EXPECT_TRUE(conn1->receiving());
592 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000593 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
594
595 // Send another ping from UDP to TURN.
596 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700597 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
598 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700599 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000600 }
601
honghaiz32f39962015-11-17 11:36:31 -0800602 void TestDestroyTurnConnection() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700603 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz32f39962015-11-17 11:36:31 -0800604
605 // Create connections on both ends.
606 Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
607 Port::ORIGIN_MESSAGE);
608 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
609 Port::ORIGIN_MESSAGE);
610 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700611 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
612 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800613 // Make sure turn connection can receive.
614 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700615 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
616 kSimulatedRtt * 2, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800617 EXPECT_FALSE(turn_unknown_address_);
618
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700619 // Destroy the connection on the TURN port. The TurnEntry still exists, so
620 // the TURN port should still process a ping from an unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800621 conn2->Destroy();
622 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700623 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
624 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800625
626 // Flush all requests in the invoker to destroy the TurnEntry.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700627 // Expect that it still processes an incoming ping and signals the
628 // unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800629 turn_unknown_address_ = false;
630 turn_port_->invoker()->Flush(rtc::Thread::Current());
631 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700632 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
633 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800634
635 // If the connection is created again, it will start to receive pings.
636 conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
637 Port::ORIGIN_MESSAGE);
638 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700639 EXPECT_TRUE_SIMULATED_WAIT(conn2->receiving(), kSimulatedRtt, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800640 }
641
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700642 void TestTurnSendData(ProtocolType protocol_type) {
643 PrepareTurnAndUdpPorts(protocol_type);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800644
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000645 // Create connections and send pings.
646 Connection* conn1 = turn_port_->CreateConnection(
647 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
648 Connection* conn2 = udp_port_->CreateConnection(
649 turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
650 ASSERT_TRUE(conn1 != NULL);
651 ASSERT_TRUE(conn2 != NULL);
652 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
653 &TurnPortTest::OnTurnReadPacket);
654 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
655 &TurnPortTest::OnUdpReadPacket);
656 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700657 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
658 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000659 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700660 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
661 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000662
663 // Send some data.
664 size_t num_packets = 256;
665 for (size_t i = 0; i < num_packets; ++i) {
666 unsigned char buf[256] = { 0 };
667 for (size_t j = 0; j < i + 1; ++j) {
668 buf[j] = 0xFF - static_cast<unsigned char>(j);
669 }
670 conn1->Send(buf, i + 1, options);
671 conn2->Send(buf, i + 1, options);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700672 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000673 }
674
675 // Check the data.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700676 ASSERT_EQ(num_packets, turn_packets_.size());
677 ASSERT_EQ(num_packets, udp_packets_.size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000678 for (size_t i = 0; i < num_packets; ++i) {
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000679 EXPECT_EQ(i + 1, turn_packets_[i].size());
680 EXPECT_EQ(i + 1, udp_packets_[i].size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000681 EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
682 }
683 }
684
Steve Antoned447ae2017-08-17 14:31:51 -0700685 // Test that a TURN allocation is released when the port is closed.
686 void TestTurnReleaseAllocation(ProtocolType protocol_type) {
687 PrepareTurnAndUdpPorts(protocol_type);
688 turn_port_.reset();
689 EXPECT_EQ_SIMULATED_WAIT(0U, turn_server_.server()->allocations().size(),
690 kSimulatedRtt, fake_clock_);
691 }
692
Jonas Orelandc99dc312018-03-28 08:00:50 +0200693 // Test that the TURN allocation is released by sending a refresh request
694 // with lifetime 0 when Release is called.
695 void TestTurnGracefulReleaseAllocation(ProtocolType protocol_type) {
696 PrepareTurnAndUdpPorts(protocol_type);
697
698 // Create connections and send pings.
699 Connection* conn1 = turn_port_->CreateConnection(
700 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
701 Connection* conn2 = udp_port_->CreateConnection(
702 turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
703 ASSERT_TRUE(conn1 != NULL);
704 ASSERT_TRUE(conn2 != NULL);
705 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
706 &TurnPortTest::OnTurnReadPacket);
707 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
708 &TurnPortTest::OnUdpReadPacket);
709 conn1->Ping(0);
710 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
711 kSimulatedRtt * 2, fake_clock_);
712 conn2->Ping(0);
713 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
714 kSimulatedRtt * 2, fake_clock_);
715
716 // Send some data from Udp to TurnPort.
717 unsigned char buf[256] = { 0 };
718 conn2->Send(buf, sizeof(buf), options);
719
720 // Now release the TurnPort allocation.
721 // This will send a REFRESH with lifetime 0 to server.
722 turn_port_->Release();
723
724 // Wait for the TurnPort to signal closed.
725 ASSERT_TRUE_SIMULATED_WAIT(turn_port_closed_, kSimulatedRtt, fake_clock_);
726
727 // But the data should have arrived first.
728 ASSERT_EQ(1ul, turn_packets_.size());
729 EXPECT_EQ(sizeof(buf), turn_packets_[0].size());
730
731 // The allocation is released at server.
732 EXPECT_EQ(0U, turn_server_.server()->allocations().size());
733 }
734
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000735 protected:
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700736 rtc::ScopedFakeClock fake_clock_;
deadbeef5c3c1042017-08-04 15:01:57 -0700737 // When a "create port" helper method is called with an IP, we create a
738 // Network with that IP and add it to this list. Using a list instead of a
739 // vector so that when it grows, pointers aren't invalidated.
740 std::list<rtc::Network> networks_;
kwiberg3ec46792016-04-27 07:22:53 -0700741 std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700742 rtc::AutoSocketServerThread main_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000743 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700744 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700745 TestTurnServer turn_server_;
kwiberg3ec46792016-04-27 07:22:53 -0700746 std::unique_ptr<TurnPort> turn_port_;
747 std::unique_ptr<UDPPort> udp_port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000748 bool turn_ready_;
749 bool turn_error_;
750 bool turn_unknown_address_;
751 bool turn_create_permission_success_;
Jonas Orelandc99dc312018-03-28 08:00:50 +0200752 bool turn_port_closed_;
753 bool turn_port_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000754 bool udp_ready_;
755 bool test_finish_;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800756 bool turn_refresh_success_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000757 std::vector<rtc::Buffer> turn_packets_;
758 std::vector<rtc::Buffer> udp_packets_;
759 rtc::PacketOptions options;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200760 std::unique_ptr<webrtc::TurnCustomizer> turn_customizer_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000761};
762
Honghai Zhangd00c0572016-06-28 09:44:47 -0700763TEST_F(TurnPortTest, TestTurnPortType) {
764 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
765 EXPECT_EQ(cricket::RELAY_PORT_TYPE, turn_port_->Type());
766}
767
zhihuang26d99c22017-02-13 12:47:27 -0800768// Tests that the URL of the servers can be correctly reconstructed when
769// gathering the candidates.
Steve Antoned447ae2017-08-17 14:31:51 -0700770TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv4) {
zhihuang26d99c22017-02-13 12:47:27 -0800771 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700772 TestReconstructedServerUrl(PROTO_UDP, "turn:99.99.99.3:3478?transport=udp");
773}
zhihuang26d99c22017-02-13 12:47:27 -0800774
Steve Antoned447ae2017-08-17 14:31:51 -0700775TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv6) {
zhihuang26d99c22017-02-13 12:47:27 -0800776 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
777 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
778 kTurnUdpIPv6ProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700779 TestReconstructedServerUrl(
780 PROTO_UDP,
781 "turn:2400:4030:1:2c00:be30:abcd:efab:cdef:3478?transport=udp");
782}
zhihuang26d99c22017-02-13 12:47:27 -0800783
Steve Antoned447ae2017-08-17 14:31:51 -0700784TEST_F(TurnPortTest, TestReconstructedServerUrlForTcp) {
zhihuang26d99c22017-02-13 12:47:27 -0800785 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
786 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700787 TestReconstructedServerUrl(PROTO_TCP, "turn:99.99.99.4:3478?transport=tcp");
zhihuang26d99c22017-02-13 12:47:27 -0800788}
789
Steve Anton786de702017-08-17 15:15:46 -0700790TEST_F(TurnPortTest, TestReconstructedServerUrlForTls) {
791 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
792 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
793 TestReconstructedServerUrl(PROTO_TLS, "turns:99.99.99.4:3478?transport=tcp");
794}
795
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000796// Do a normal TURN allocation.
797TEST_F(TurnPortTest, TestTurnAllocate) {
798 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
799 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
800 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700801 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000802 ASSERT_EQ(1U, turn_port_->Candidates().size());
803 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
804 turn_port_->Candidates()[0].address().ipaddr());
805 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
806}
807
808// Testing a normal UDP allocation using TCP connection.
809TEST_F(TurnPortTest, TestTurnTcpAllocate) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700810 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000811 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
812 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
813 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700814 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000815 ASSERT_EQ(1U, turn_port_->Candidates().size());
816 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
817 turn_port_->Candidates()[0].address().ipaddr());
818 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
819}
820
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000821// Test case for WebRTC issue 3927 where a proxy binds to the local host address
822// instead the address that TurnPort originally bound to. The candidate pair
823// impacted by this behavior should still be used.
824TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
deadbeef5c3c1042017-08-04 15:01:57 -0700825 SocketAddress local_address("127.0.0.1", 0);
826 // After calling this, when TurnPort attempts to get a socket bound to
827 // kLocalAddr, it will end up using localhost instead.
828 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), local_address.ipaddr());
829
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700830 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef5c3c1042017-08-04 15:01:57 -0700831 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000832 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
833 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700834 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000835 ASSERT_EQ(1U, turn_port_->Candidates().size());
836 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
837 turn_port_->Candidates()[0].address().ipaddr());
838 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
deadbeef5c3c1042017-08-04 15:01:57 -0700839
840 // Verify that the socket actually used localhost, otherwise this test isn't
841 // doing what it meant to.
842 ASSERT_EQ(local_address.ipaddr(),
843 turn_port_->Candidates()[0].related_address().ipaddr());
844}
845
846// If the address the socket ends up bound to does not match any address of the
847// TurnPort's Network, then the socket should be discarded and no candidates
848// should be signaled. In the context of ICE, where one TurnPort is created for
849// each Network, when this happens it's likely that the unexpected address is
850// associated with some other Network, which another TurnPort is already
851// covering.
852TEST_F(TurnPortTest,
853 TurnTcpAllocationDiscardedIfBoundAddressDoesNotMatchNetwork) {
854 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
855 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
856
857 // Set up TURN server to use TCP (this logic only exists for TCP).
858 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
859
860 // Create TURN port and tell it to start allocation.
861 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
862 turn_port_->PrepareAddress();
863
864 // Shouldn't take more than 1 RTT to realize the bound address isn't the one
865 // expected.
866 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
867}
868
869// A caveat for the above logic: if the socket ends up bound to one of the IPs
870// associated with the Network, just not the "best" one, this is ok.
871TEST_F(TurnPortTest, TurnTcpAllocationNotDiscardedIfNotBoundToBestIP) {
872 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
873 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
874
875 // Set up a network with kLocalAddr1 as the "best" IP, and kLocalAddr2 as an
876 // alternate.
877 rtc::Network* network = MakeNetwork(kLocalAddr1);
878 network->AddIP(kLocalAddr2.ipaddr());
879 ASSERT_EQ(kLocalAddr1.ipaddr(), network->GetBestIP());
880
881 // Set up TURN server to use TCP (this logic only exists for TCP).
882 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
883
884 // Create TURN port using our special Network, and tell it to start
885 // allocation.
886 CreateTurnPortWithNetwork(network, kTurnUsername, kTurnPassword,
887 kTurnTcpProtoAddr);
888 turn_port_->PrepareAddress();
889
890 // Candidate should be gathered as normally.
891 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
892 ASSERT_EQ(1U, turn_port_->Candidates().size());
893
894 // Verify that the socket actually used the alternate address, otherwise this
895 // test isn't doing what it meant to.
896 ASSERT_EQ(kLocalAddr2.ipaddr(),
897 turn_port_->Candidates()[0].related_address().ipaddr());
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000898}
899
Taylor Brandstetter01cb5f22018-03-07 15:49:32 -0800900// Regression test for crbug.com/webrtc/8972, caused by buggy comparison
901// between rtc::IPAddress and rtc::InterfaceAddress.
902TEST_F(TurnPortTest, TCPPortNotDiscardedIfBoundToTemporaryIP) {
903 networks_.emplace_back("unittest", "unittest", kLocalIPv6Addr.ipaddr(), 32);
904 networks_.back().AddIP(rtc::InterfaceAddress(
905 kLocalIPv6Addr.ipaddr(), rtc::IPV6_ADDRESS_FLAG_TEMPORARY));
906
907 // Set up TURN server to use TCP (this logic only exists for TCP).
908 turn_server_.AddInternalSocket(kTurnIPv6IntAddr, PROTO_TCP);
909
910 // Create TURN port using our special Network, and tell it to start
911 // allocation.
912 CreateTurnPortWithNetwork(
913 &networks_.back(), kTurnUsername, kTurnPassword,
914 cricket::ProtocolAddress(kTurnIPv6IntAddr, PROTO_TCP));
915 turn_port_->PrepareAddress();
916
917 // Candidate should be gathered as normally.
918 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
919 ASSERT_EQ(1U, turn_port_->Candidates().size());
920}
921
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000922// Testing turn port will attempt to create TCP socket on address resolution
923// failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700924TEST_F(TurnPortTest, TestTurnTcpOnAddressResolveFailure) {
925 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
926 CreateTurnPort(kTurnUsername, kTurnPassword,
927 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
928 PROTO_TCP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000929 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700930 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000931 // As VSS doesn't provide a DNS resolution, name resolve will fail. TurnPort
932 // will proceed in creating a TCP socket which will fail as there is no
933 // server on the above domain and error will be set to SOCKET_ERROR.
934 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
935}
936
Steve Anton786de702017-08-17 15:15:46 -0700937// Testing turn port will attempt to create TLS socket on address resolution
938// failure.
939TEST_F(TurnPortTest, TestTurnTlsOnAddressResolveFailure) {
940 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
941 CreateTurnPort(kTurnUsername, kTurnPassword,
942 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
943 PROTO_TLS));
944 turn_port_->PrepareAddress();
945 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
946 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
947}
948
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000949// In case of UDP on address resolve failure, TurnPort will not create socket
950// and return allocate failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700951TEST_F(TurnPortTest, TestTurnUdpOnAddressResolveFailure) {
952 CreateTurnPort(kTurnUsername, kTurnPassword,
953 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
954 PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000955 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700956 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000957 // Error from turn port will not be socket error.
958 EXPECT_NE(SOCKET_ERROR, turn_port_->error());
959}
960
961// Try to do a TURN allocation with an invalid password.
962TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
963 CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
964 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700965 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000966 ASSERT_EQ(0U, turn_port_->Candidates().size());
967}
968
honghaizc463e202016-02-01 15:19:08 -0800969// Tests that TURN port nonce will be reset when receiving an ALLOCATE MISMATCH
970// error.
971TEST_F(TurnPortTest, TestTurnAllocateNonceResetAfterAllocateMismatch) {
972 // Do a normal allocation first.
973 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
974 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700975 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -0800976 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
977 // Destroy the turnport while keeping the drop probability to 1 to
978 // suppress the release of the allocation at the server.
979 ss_->set_drop_probability(1.0);
980 turn_port_.reset();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700981 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -0800982 ss_->set_drop_probability(0.0);
983
984 // Force the socket server to assign the same port.
985 ss_->SetNextPortForTesting(first_addr.port());
986 turn_ready_ = false;
987 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
988
989 // It is expected that the turn port will first get a nonce from the server
990 // using timestamp |ts_before| but then get an allocate mismatch error and
991 // receive an even newer nonce based on the system clock. |ts_before| is
992 // chosen so that the two NONCEs generated by the server will be different.
nisse1bffc1d2016-05-02 08:18:55 -0700993 int64_t ts_before = rtc::TimeMillis() - 1;
honghaizc463e202016-02-01 15:19:08 -0800994 std::string first_nonce =
995 turn_server_.server()->SetTimestampForNextNonce(ts_before);
996 turn_port_->PrepareAddress();
997
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700998 // Four round trips; first we'll get "stale nonce", then
999 // "allocate mismatch", then "stale nonce" again, then finally it will
1000 // succeed.
1001 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -08001002 EXPECT_NE(first_nonce, turn_port_->nonce());
1003}
1004
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001005// Tests that a new local address is created after
1006// STUN_ERROR_ALLOCATION_MISMATCH.
1007TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
1008 // Do a normal allocation first.
1009 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1010 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001011 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001012 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1013
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001014 // Clear connected_ flag on turnport to suppress the release of
1015 // the allocation.
1016 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1017
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001018 // Forces the socket server to assign the same port.
1019 ss_->SetNextPortForTesting(first_addr.port());
1020
1021 turn_ready_ = false;
1022 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1023 turn_port_->PrepareAddress();
1024
1025 // Verifies that the new port has the same address.
1026 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1027
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001028 // Four round trips; first we'll get "stale nonce", then
1029 // "allocate mismatch", then "stale nonce" again, then finally it will
1030 // succeed.
1031 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001032
1033 // Verifies that the new port has a different address now.
1034 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
Sergey Ulanov17fa6722016-05-10 10:20:47 -07001035
1036 // Verify that all packets received from the shared socket are ignored.
1037 std::string test_packet = "Test packet";
1038 EXPECT_FALSE(turn_port_->HandleIncomingPacket(
1039 socket_.get(), test_packet.data(), test_packet.size(),
1040 rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0),
1041 rtc::CreatePacketTime(0)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001042}
1043
1044// Tests that a shared-socket-TurnPort creates its own socket after
1045// STUN_ERROR_ALLOCATION_MISMATCH.
1046TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
1047 // Do a normal allocation first.
1048 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1049 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001050 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001051 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1052
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001053 // Clear connected_ flag on turnport to suppress the release of
1054 // the allocation.
1055 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1056
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001057 turn_ready_ = false;
1058 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1059
1060 // Verifies that the new port has the same address.
1061 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1062 EXPECT_TRUE(turn_port_->SharedSocket());
1063
1064 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001065 // Extra 2 round trips due to allocate mismatch.
1066 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001067
1068 // Verifies that the new port has a different address now.
1069 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1070 EXPECT_FALSE(turn_port_->SharedSocket());
1071}
1072
1073TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001074 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001075 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1076
1077 // Do a normal allocation first.
1078 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001079 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001080 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1081
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001082 // Clear connected_ flag on turnport to suppress the release of
1083 // the allocation.
1084 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1085
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001086 // Forces the socket server to assign the same port.
1087 ss_->SetNextPortForTesting(first_addr.port());
1088
1089 turn_ready_ = false;
1090 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1091 turn_port_->PrepareAddress();
1092
1093 // Verifies that the new port has the same address.
1094 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1095
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001096 // Extra 2 round trips due to allocate mismatch.
1097 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 5, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001098
1099 // Verifies that the new port has a different address now.
1100 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1101}
1102
Honghai Zhangf67c5482015-12-11 15:16:54 -08001103TEST_F(TurnPortTest, TestRefreshRequestGetsErrorResponse) {
1104 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001105 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz6b9ab922016-01-05 09:06:12 -08001106 turn_port_->CreateConnection(udp_port_->Candidates()[0],
1107 Port::ORIGIN_MESSAGE);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001108 // Set bad credentials.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001109 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001110 turn_port_->set_credentials(bad_credentials);
1111 turn_refresh_success_ = false;
1112 // This sends out the first RefreshRequest with correct credentials.
1113 // When this succeeds, it will schedule a new RefreshRequest with the bad
1114 // credential.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001115 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1116 EXPECT_TRUE_SIMULATED_WAIT(turn_refresh_success_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001117 // Flush it again, it will receive a bad response.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001118 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1119 EXPECT_TRUE_SIMULATED_WAIT(!turn_refresh_success_, kSimulatedRtt,
1120 fake_clock_);
1121 EXPECT_FALSE(turn_port_->connected());
1122 EXPECT_TRUE(CheckAllConnectionsFailedAndPruned());
1123 EXPECT_FALSE(turn_port_->HasRequests());
Honghai Zhangf67c5482015-12-11 15:16:54 -08001124}
1125
honghaiz9dfed792016-01-29 13:22:31 -08001126// Test that TurnPort will not handle any incoming packets once it has been
1127// closed.
1128TEST_F(TurnPortTest, TestStopProcessingPacketsAfterClosed) {
1129 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001130 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz9dfed792016-01-29 13:22:31 -08001131 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1132 Port::ORIGIN_MESSAGE);
1133 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1134 Port::ORIGIN_MESSAGE);
1135 ASSERT_TRUE(conn1 != NULL);
1136 ASSERT_TRUE(conn2 != NULL);
1137 // Make sure conn2 is writable.
1138 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001139 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
1140 kSimulatedRtt * 2, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001141
1142 turn_port_->Close();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001143 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001144 turn_unknown_address_ = false;
1145 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001146 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001147 // Since the turn port does not handle packets any more, it should not
1148 // SignalUnknownAddress.
1149 EXPECT_FALSE(turn_unknown_address_);
1150}
1151
honghaizb19eba32015-08-03 10:23:31 -07001152// Test that CreateConnection will return null if port becomes disconnected.
1153TEST_F(TurnPortTest, TestCreateConnectionWhenSocketClosed) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001154 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001155 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001156 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001157 // Create a connection.
1158 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1159 Port::ORIGIN_MESSAGE);
1160 ASSERT_TRUE(conn1 != NULL);
1161
1162 // Close the socket and create a connection again.
1163 turn_port_->OnSocketClose(turn_port_->socket(), 1);
1164 conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1165 Port::ORIGIN_MESSAGE);
1166 ASSERT_TRUE(conn1 == NULL);
1167}
1168
honghaiz079a7a12016-06-22 16:26:29 -07001169// Tests that when a TCP socket is closed, the respective TURN connection will
1170// be destroyed.
1171TEST_F(TurnPortTest, TestSocketCloseWillDestroyConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001172 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001173 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001174 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001175 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1176 Port::ORIGIN_MESSAGE);
1177 EXPECT_NE(nullptr, conn);
1178 EXPECT_TRUE(!turn_port_->connections().empty());
1179 turn_port_->socket()->SignalClose(turn_port_->socket(), 1);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001180 EXPECT_TRUE_SIMULATED_WAIT(turn_port_->connections().empty(),
1181 kConnectionDestructionDelay, fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001182}
1183
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001184// Test try-alternate-server feature.
1185TEST_F(TurnPortTest, TestTurnAlternateServerUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001186 TestTurnAlternateServer(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001187}
1188
1189TEST_F(TurnPortTest, TestTurnAlternateServerTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001190 TestTurnAlternateServer(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001191}
1192
Steve Anton786de702017-08-17 15:15:46 -07001193TEST_F(TurnPortTest, TestTurnAlternateServerTLS) {
1194 TestTurnAlternateServer(PROTO_TLS);
1195}
1196
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001197// Test that we fail when we redirect to an address different from
1198// current IP family.
1199TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6UDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001200 TestTurnAlternateServerV4toV6(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001201}
1202
1203TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001204 TestTurnAlternateServerV4toV6(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001205}
1206
Steve Anton786de702017-08-17 15:15:46 -07001207TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TLS) {
1208 TestTurnAlternateServerV4toV6(PROTO_TLS);
1209}
1210
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001211// Test try-alternate-server catches the case of pingpong.
1212TEST_F(TurnPortTest, TestTurnAlternateServerPingPongUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001213 TestTurnAlternateServerPingPong(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001214}
1215
1216TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001217 TestTurnAlternateServerPingPong(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001218}
1219
Steve Anton786de702017-08-17 15:15:46 -07001220TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTLS) {
1221 TestTurnAlternateServerPingPong(PROTO_TLS);
1222}
1223
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001224// Test try-alternate-server catch the case of repeated server.
1225TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001226 TestTurnAlternateServerDetectRepetition(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001227}
1228
1229TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001230 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001231}
1232
Steve Anton786de702017-08-17 15:15:46 -07001233TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTLS) {
1234 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
1235}
1236
deadbeeffb70b452016-10-24 13:15:59 -07001237// Test catching the case of a redirect to loopback.
1238TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv4) {
1239 TestTurnAlternateServerLoopback(PROTO_UDP, false);
1240}
1241
1242TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv6) {
1243 TestTurnAlternateServerLoopback(PROTO_UDP, true);
1244}
1245
1246TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv4) {
1247 TestTurnAlternateServerLoopback(PROTO_TCP, false);
1248}
1249
1250TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv6) {
1251 TestTurnAlternateServerLoopback(PROTO_TCP, true);
1252}
1253
Steve Anton786de702017-08-17 15:15:46 -07001254TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv4) {
1255 TestTurnAlternateServerLoopback(PROTO_TLS, false);
1256}
1257
1258TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv6) {
1259 TestTurnAlternateServerLoopback(PROTO_TLS, true);
1260}
1261
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001262// Do a TURN allocation and try to send a packet to it from the outside.
1263// The packet should be dropped. Then, try to send a packet from TURN to the
1264// outside. It should reach its destination. Finally, try again from the
1265// outside. It should now work as well.
1266TEST_F(TurnPortTest, TestTurnConnection) {
1267 CreateTurnPort(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// Similar to above, except that this test will use the shared socket.
1272TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
1273 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001274 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001275}
1276
1277// Test that we can establish a TCP connection with TURN server.
1278TEST_F(TurnPortTest, TestTurnTcpConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001279 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001280 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001281 TestTurnConnection(PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001282}
1283
Steve Anton786de702017-08-17 15:15:46 -07001284// Test that we can establish a TLS connection with TURN server.
1285TEST_F(TurnPortTest, TestTurnTlsConnection) {
1286 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1287 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1288 TestTurnConnection(PROTO_TLS);
1289}
1290
honghaiz32f39962015-11-17 11:36:31 -08001291// Test that if a connection on a TURN port is destroyed, the TURN port can
1292// still receive ping on that connection as if it is from an unknown address.
1293// If the connection is created again, it will be used to receive ping.
1294TEST_F(TurnPortTest, TestDestroyTurnConnection) {
1295 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1296 TestDestroyTurnConnection();
1297}
1298
1299// Similar to above, except that this test will use the shared socket.
1300TEST_F(TurnPortTest, TestDestroyTurnConnectionUsingSharedSocket) {
1301 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1302 TestDestroyTurnConnection();
1303}
1304
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001305// Run TurnConnectionTest with one-time-use nonce feature.
1306// Here server will send a 438 STALE_NONCE error message for
1307// every TURN transaction.
1308TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
1309 turn_server_.set_enable_otu_nonce(true);
1310 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001311 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001312}
1313
Honghai Zhang85975432015-11-12 11:07:12 -08001314// Test that CreatePermissionRequest will be scheduled after the success
Honghai Zhangf67c5482015-12-11 15:16:54 -08001315// of the first create permission request and the request will get an
1316// ErrorResponse if the ufrag and pwd are incorrect.
Honghai Zhang85975432015-11-12 11:07:12 -08001317TEST_F(TurnPortTest, TestRefreshCreatePermissionRequest) {
1318 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001319 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhang85975432015-11-12 11:07:12 -08001320
1321 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1322 Port::ORIGIN_MESSAGE);
1323 ASSERT_TRUE(conn != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001324 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1325 fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001326 turn_create_permission_success_ = false;
1327 // A create-permission-request should be pending.
Honghai Zhangf67c5482015-12-11 15:16:54 -08001328 // After the next create-permission-response is received, it will schedule
1329 // another request with bad_ufrag and bad_pwd.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001330 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001331 turn_port_->set_credentials(bad_credentials);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001332 turn_port_->FlushRequests(kAllRequests);
1333 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1334 fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001335 // Flush the requests again; the create-permission-request will fail.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001336 turn_port_->FlushRequests(kAllRequests);
1337 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1338 fake_clock_);
1339 EXPECT_TRUE(CheckConnectionFailedAndPruned(conn));
Honghai Zhangf67c5482015-12-11 15:16:54 -08001340}
1341
1342TEST_F(TurnPortTest, TestChannelBindGetErrorResponse) {
1343 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001344 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001345 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1346 Port::ORIGIN_MESSAGE);
1347 ASSERT_TRUE(conn1 != nullptr);
1348 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1349 Port::ORIGIN_MESSAGE);
Honghai Zhang3d77deb2016-06-22 15:22:22 -07001350
honghaiz079a7a12016-06-22 16:26:29 -07001351 ASSERT_TRUE(conn2 != nullptr);
1352 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001353 EXPECT_TRUE_SIMULATED_WAIT(conn1->writable(), kSimulatedRtt * 2, fake_clock_);
1354 // TODO(deadbeef): SetEntryChannelId should not be a public method.
1355 // Instead we should set an option on the fake TURN server to force it to
1356 // send a channel bind errors.
1357 ASSERT_TRUE(
1358 turn_port_->SetEntryChannelId(udp_port_->Candidates()[0].address(), -1));
honghaiz079a7a12016-06-22 16:26:29 -07001359
1360 std::string data = "ABC";
1361 conn1->Send(data.data(), data.length(), options);
1362
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001363 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn1),
1364 kSimulatedRtt, fake_clock_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001365 // Verify that packets are allowed to be sent after a bind request error.
1366 // They'll just use a send indication instead.
honghaiz079a7a12016-06-22 16:26:29 -07001367 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
1368 &TurnPortTest::OnUdpReadPacket);
1369 conn1->Send(data.data(), data.length(), options);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001370 EXPECT_TRUE_SIMULATED_WAIT(!udp_packets_.empty(), kSimulatedRtt, fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001371}
1372
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001373// Do a TURN allocation, establish a UDP connection, and send some data.
1374TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
1375 // Create ports and prepare addresses.
1376 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001377 TestTurnSendData(PROTO_UDP);
1378 EXPECT_EQ(UDP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001379}
1380
1381// Do a TURN allocation, establish a TCP connection, and send some data.
1382TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001383 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001384 // Create ports and prepare addresses.
1385 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001386 TestTurnSendData(PROTO_TCP);
1387 EXPECT_EQ(TCP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001388}
1389
Steve Anton786de702017-08-17 15:15:46 -07001390// Do a TURN allocation, establish a TLS connection, and send some data.
1391TEST_F(TurnPortTest, TestTurnSendDataTurnTlsToUdp) {
1392 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1393 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1394 TestTurnSendData(PROTO_TLS);
1395 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1396}
1397
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001398// Test TURN fails to make a connection from IPv6 address to a server which has
1399// IPv4 address.
1400TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001401 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001402 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1403 kTurnUdpProtoAddr);
1404 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001405 ASSERT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001406 EXPECT_TRUE(turn_port_->Candidates().empty());
1407}
1408
1409// Test TURN make a connection from IPv6 address to a server which has
1410// IPv6 intenal address. But in this test external address is a IPv4 address,
1411// hence allocated address will be a IPv4 address.
1412TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001413 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001414 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1415 kTurnUdpIPv6ProtoAddr);
1416 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001417 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001418 ASSERT_EQ(1U, turn_port_->Candidates().size());
1419 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
1420 turn_port_->Candidates()[0].address().ipaddr());
1421 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
1422}
1423
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001424// Tests that the local and remote candidate address families should match when
1425// a connection is created. Specifically, if a TURN port has an IPv6 address,
1426// its local candidate will still be an IPv4 address and it can only create
1427// connections with IPv4 remote candidates.
1428TEST_F(TurnPortTest, TestCandidateAddressFamilyMatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001429 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001430
1431 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1432 kTurnUdpIPv6ProtoAddr);
1433 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001434 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001435 ASSERT_EQ(1U, turn_port_->Candidates().size());
1436
1437 // Create an IPv4 candidate. It will match the TURN candidate.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001438 Candidate remote_candidate(ICE_CANDIDATE_COMPONENT_RTP, "udp", kLocalAddr2, 0,
1439 "", "", "local", 0, kCandidateFoundation);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001440 remote_candidate.set_address(kLocalAddr2);
1441 Connection* conn =
1442 turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1443 EXPECT_NE(nullptr, conn);
1444
1445 // Set the candidate address family to IPv6. It won't match the TURN
1446 // candidate.
1447 remote_candidate.set_address(kLocalIPv6Addr2);
1448 conn = turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1449 EXPECT_EQ(nullptr, conn);
1450}
1451
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001452TEST_F(TurnPortTest, TestOriginHeader) {
1453 CreateTurnPortWithOrigin(kLocalAddr1, kTurnUsername, kTurnPassword,
1454 kTurnUdpProtoAddr, kTestOrigin);
1455 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001456 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001457 ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
1458 SocketAddress local_address = turn_port_->GetLocalAddress();
1459 ASSERT_TRUE(turn_server_.FindAllocation(local_address) != NULL);
1460 EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
1461}
1462
deadbeef376e1232015-11-25 09:00:08 -08001463// Test that a CreatePermission failure will result in the connection being
honghaiz079a7a12016-06-22 16:26:29 -07001464// pruned and failed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001465TEST_F(TurnPortTest, TestConnectionFailedAndPrunedOnCreatePermissionFailure) {
1466 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef376e1232015-11-25 09:00:08 -08001467 turn_server_.server()->set_reject_private_addresses(true);
1468 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1469 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001470 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001471
1472 CreateUdpPort(SocketAddress("10.0.0.10", 0));
1473 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001474 EXPECT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001475 // Create a connection.
1476 TestConnectionWrapper conn(turn_port_->CreateConnection(
1477 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE));
honghaiz079a7a12016-06-22 16:26:29 -07001478 EXPECT_TRUE(conn.connection() != nullptr);
deadbeef376e1232015-11-25 09:00:08 -08001479
honghaiz079a7a12016-06-22 16:26:29 -07001480 // Asynchronously, CreatePermission request should be sent and fail, which
1481 // will make the connection pruned and failed.
1482 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn.connection()),
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001483 kSimulatedRtt, fake_clock_);
1484 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1485 fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001486 // Check that the connection is not deleted asynchronously.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001487 SIMULATED_WAIT(conn.connection() == nullptr, kConnectionDestructionDelay,
1488 fake_clock_);
1489 EXPECT_NE(nullptr, conn.connection());
deadbeef376e1232015-11-25 09:00:08 -08001490}
1491
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001492// Test that a TURN allocation is released when the port is closed.
1493TEST_F(TurnPortTest, TestTurnReleaseAllocation) {
1494 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001495 TestTurnReleaseAllocation(PROTO_UDP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001496}
1497
1498// Test that a TURN TCP allocation is released when the port is closed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001499TEST_F(TurnPortTest, TestTurnTCPReleaseAllocation) {
1500 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001501 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001502 TestTurnReleaseAllocation(PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001503}
1504
Steve Anton786de702017-08-17 15:15:46 -07001505TEST_F(TurnPortTest, TestTurnTLSReleaseAllocation) {
1506 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1507 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1508 TestTurnReleaseAllocation(PROTO_TLS);
1509}
1510
Jonas Orelandc99dc312018-03-28 08:00:50 +02001511TEST_F(TurnPortTest, TestTurnUDPGracefulReleaseAllocation) {
1512 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_UDP);
1513 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1514 TestTurnGracefulReleaseAllocation(PROTO_UDP);
1515}
1516
1517TEST_F(TurnPortTest, TestTurnTCPGracefulReleaseAllocation) {
1518 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
1519 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1520 TestTurnGracefulReleaseAllocation(PROTO_TCP);
1521}
1522
1523TEST_F(TurnPortTest, TestTurnTLSGracefulReleaseAllocation) {
1524 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1525 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1526 TestTurnGracefulReleaseAllocation(PROTO_TLS);
1527}
1528
Taylor Brandstetterd65ae4a2017-10-08 11:46:15 -07001529// Test that nothing bad happens if we try to create a connection to the same
1530// remote address twice. Previously there was a bug that caused this to hit a
1531// DCHECK.
1532TEST_F(TurnPortTest, CanCreateTwoConnectionsToSameAddress) {
1533 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1534 PrepareTurnAndUdpPorts(PROTO_UDP);
1535 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1536 Port::ORIGIN_MESSAGE);
1537 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1538 Port::ORIGIN_MESSAGE);
1539 EXPECT_NE(conn1, conn2);
1540}
1541
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001542// This test verifies any FD's are not leaked after TurnPort is destroyed.
1543// https://code.google.com/p/webrtc/issues/detail?id=2651
1544#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001545
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001546TEST_F(TurnPortTest, TestResolverShutdown) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001547 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001548 int last_fd_count = GetFDCount();
1549 // Need to supply unresolved address to kick off resolver.
1550 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001551 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
1552 PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001553 turn_port_->PrepareAddress();
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001554 ASSERT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001555 EXPECT_TRUE(turn_port_->Candidates().empty());
1556 turn_port_.reset();
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001557 rtc::Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001558 // Waiting for above message to be processed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001559 ASSERT_TRUE_SIMULATED_WAIT(test_finish_, 1, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001560 EXPECT_EQ(last_fd_count, GetFDCount());
1561}
1562#endif
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001563
Jonas Orelandbdcee282017-10-10 14:01:40 +02001564class MessageObserver : public StunMessageObserver{
1565 public:
1566 MessageObserver(unsigned int *message_counter,
1567 unsigned int* channel_data_counter,
1568 unsigned int *attr_counter)
1569 : message_counter_(message_counter),
1570 channel_data_counter_(channel_data_counter),
1571 attr_counter_(attr_counter) {}
1572 virtual ~MessageObserver() {}
Steve Anton6c38cc72017-11-29 10:25:58 -08001573 void ReceivedMessage(const TurnMessage* msg) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001574 if (message_counter_ != nullptr) {
1575 (*message_counter_)++;
1576 }
1577 // Implementation defined attributes are returned as ByteString
1578 const StunByteStringAttribute* attr = msg->GetByteString(
1579 TestTurnCustomizer::STUN_ATTR_COUNTER);
1580 if (attr != nullptr && attr_counter_ != nullptr) {
1581 rtc::ByteBufferReader buf(attr->bytes(), attr->length());
1582 unsigned int val = ~0u;
1583 buf.ReadUInt32(&val);
1584 (*attr_counter_)++;
1585 }
1586 }
1587
Steve Anton6c38cc72017-11-29 10:25:58 -08001588 void ReceivedChannelData(const char* data, size_t size) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001589 if (channel_data_counter_ != nullptr) {
1590 (*channel_data_counter_)++;
1591 }
1592 }
1593
1594 // Number of TurnMessages observed.
1595 unsigned int* message_counter_ = nullptr;
1596
1597 // Number of channel data observed.
1598 unsigned int* channel_data_counter_ = nullptr;
1599
1600 // Number of TurnMessages that had STUN_ATTR_COUNTER.
1601 unsigned int* attr_counter_ = nullptr;
1602};
1603
1604// Do a TURN allocation, establish a TLS connection, and send some data.
1605// Add customizer and check that it get called.
1606TEST_F(TurnPortTest, TestTurnCustomizerCount) {
1607 unsigned int observer_message_counter = 0;
1608 unsigned int observer_channel_data_counter = 0;
1609 unsigned int observer_attr_counter = 0;
1610 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1611 std::unique_ptr<MessageObserver> validator(new MessageObserver(
1612 &observer_message_counter,
1613 &observer_channel_data_counter,
1614 &observer_attr_counter));
1615
1616 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1617 turn_customizer_.reset(customizer);
1618 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1619
1620 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1621 TestTurnSendData(PROTO_TLS);
1622 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1623
1624 // There should have been at least turn_packets_.size() calls to |customizer|.
1625 EXPECT_GE(customizer->modify_cnt_ + customizer->allow_channel_data_cnt_,
1626 turn_packets_.size());
1627
1628 // Some channel data should be received.
1629 EXPECT_GE(observer_channel_data_counter, 0u);
1630
1631 // Need to release TURN port before the customizer.
1632 turn_port_.reset(nullptr);
1633}
1634
1635// Do a TURN allocation, establish a TLS connection, and send some data.
1636// Add customizer and check that it can can prevent usage of channel data.
1637TEST_F(TurnPortTest, TestTurnCustomizerDisallowChannelData) {
1638 unsigned int observer_message_counter = 0;
1639 unsigned int observer_channel_data_counter = 0;
1640 unsigned int observer_attr_counter = 0;
1641 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1642 std::unique_ptr<MessageObserver> validator(new MessageObserver(
1643 &observer_message_counter,
1644 &observer_channel_data_counter,
1645 &observer_attr_counter));
1646 customizer->allow_channel_data_ = false;
1647 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1648 turn_customizer_.reset(customizer);
1649 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1650
1651 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1652 TestTurnSendData(PROTO_TLS);
1653 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1654
1655 // There should have been at least turn_packets_.size() calls to |customizer|.
1656 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1657
1658 // No channel data should be received.
1659 EXPECT_EQ(observer_channel_data_counter, 0u);
1660
1661 // Need to release TURN port before the customizer.
1662 turn_port_.reset(nullptr);
1663}
1664
1665// Do a TURN allocation, establish a TLS connection, and send some data.
1666// Add customizer and check that it can add attribute to messages.
1667TEST_F(TurnPortTest, TestTurnCustomizerAddAttribute) {
1668 unsigned int observer_message_counter = 0;
1669 unsigned int observer_channel_data_counter = 0;
1670 unsigned int observer_attr_counter = 0;
1671 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1672 std::unique_ptr<MessageObserver> validator(new MessageObserver(
1673 &observer_message_counter,
1674 &observer_channel_data_counter,
1675 &observer_attr_counter));
1676 customizer->allow_channel_data_ = false;
1677 customizer->add_counter_ = true;
1678 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1679 turn_customizer_.reset(customizer);
1680 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1681
1682 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1683 TestTurnSendData(PROTO_TLS);
1684 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1685
1686 // There should have been at least turn_packets_.size() calls to |customizer|.
1687 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1688
1689 // Everything will be sent as messages since channel data is disallowed.
1690 EXPECT_GE(customizer->modify_cnt_, observer_message_counter);
1691
1692 // All messages should have attribute.
1693 EXPECT_EQ(observer_message_counter, observer_attr_counter);
1694
1695 // At least allow_channel_data_cnt_ messages should have been sent.
1696 EXPECT_GE(customizer->modify_cnt_, customizer->allow_channel_data_cnt_);
1697 EXPECT_GE(customizer->allow_channel_data_cnt_, 0u);
1698
1699 // No channel data should be received.
1700 EXPECT_EQ(observer_channel_data_counter, 0u);
1701
1702 // Need to release TURN port before the customizer.
1703 turn_port_.reset(nullptr);
1704}
1705
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001706} // namespace cricket