blob: f9e0205cd682438713caf57a4dfa372387271d54 [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
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "absl/types/optional.h"
20#include "api/units/time_delta.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "p2p/base/basic_packet_socket_factory.h"
Jonas Orelande8e7d7b2019-05-29 09:30:55 +020022#include "p2p/base/connection.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "p2p/base/p2p_constants.h"
24#include "p2p/base/port_allocator.h"
25#include "p2p/base/stun_port.h"
26#include "p2p/base/test_turn_customizer.h"
27#include "p2p/base/test_turn_server.h"
28#include "p2p/base/transport_description.h"
29#include "p2p/base/turn_port.h"
30#include "p2p/base/turn_server.h"
31#include "rtc_base/async_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/byte_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010037#include "rtc_base/location.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "rtc_base/message_handler.h"
39#include "rtc_base/net_helper.h"
40#include "rtc_base/socket_address.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/time_utils.h"
43#include "rtc_base/virtual_socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010044#include "test/gtest.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000045
46using rtc::SocketAddress;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047
48static const SocketAddress kLocalAddr1("11.11.11.11", 0);
49static const SocketAddress kLocalAddr2("22.22.22.22", 0);
Yves Gerey665174f2018-06-19 15:03:05 +020050static const SocketAddress kLocalIPv6Addr("2401:fa00:4:1000:be30:5bff:fee5:c3",
51 0);
52static const SocketAddress kLocalIPv6Addr2("2401:fa00:4:2000:be30:5bff:fee5:d4",
53 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
55 cricket::TURN_SERVER_PORT);
56static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
57 cricket::TURN_SERVER_PORT);
58static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +000059static const SocketAddress kTurnAlternateIntAddr("99.99.99.6",
60 cricket::TURN_SERVER_PORT);
61static const SocketAddress kTurnIntAddr("99.99.99.7",
62 cricket::TURN_SERVER_PORT);
63static const SocketAddress kTurnIPv6IntAddr(
64 "2400:4030:2:2c00:be30:abcd:efab:cdef",
65 cricket::TURN_SERVER_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066static const SocketAddress kTurnUdpIPv6IntAddr(
Yves Gerey665174f2018-06-19 15:03:05 +020067 "2400:4030:1:2c00:be30:abcd:efab:cdef",
68 cricket::TURN_SERVER_PORT);
Eldar Relloda13ea22019-06-01 12:23:43 +030069static const SocketAddress kTurnInvalidAddr("www.google.invalid", 3478);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -070071static const char kCandidateFoundation[] = "foundation";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072static const char kIceUfrag1[] = "TESTICEUFRAG0001";
73static const char kIceUfrag2[] = "TESTICEUFRAG0002";
74static const char kIcePwd1[] = "TESTICEPWD00000000000001";
75static const char kIcePwd2[] = "TESTICEPWD00000000000002";
76static const char kTurnUsername[] = "test";
77static const char kTurnPassword[] = "test";
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000078static const char kTestOrigin[] = "http://example.com";
Taylor Brandstetter716d07a2016-06-27 14:07:41 -070079// This test configures the virtual socket server to simulate delay so that we
80// can verify operations take no more than the expected number of round trips.
81static constexpr unsigned int kSimulatedRtt = 50;
82// Connection destruction may happen asynchronously, but it should only
83// take one simulated clock tick.
84static constexpr unsigned int kConnectionDestructionDelay = 1;
85// This used to be 1 second, but that's not always enough for getaddrinfo().
86// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5191
87static constexpr unsigned int kResolverTimeout = 10000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000088
Yves Gerey665174f2018-06-19 15:03:05 +020089static const cricket::ProtocolAddress kTurnUdpProtoAddr(kTurnUdpIntAddr,
90 cricket::PROTO_UDP);
91static const cricket::ProtocolAddress kTurnTcpProtoAddr(kTurnTcpIntAddr,
92 cricket::PROTO_TCP);
hnsl277b2502016-12-13 05:17:23 -080093static const cricket::ProtocolAddress kTurnTlsProtoAddr(kTurnTcpIntAddr,
94 cricket::PROTO_TLS);
Yves Gerey665174f2018-06-19 15:03:05 +020095static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(kTurnUdpIPv6IntAddr,
96 cricket::PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097
98static const unsigned int MSG_TESTFINISH = 0;
99
100#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
101static int GetFDCount() {
Yves Gerey665174f2018-06-19 15:03:05 +0200102 struct dirent* dp;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103 int fd_count = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200104 DIR* dir = opendir("/proc/self/fd/");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105 while ((dp = readdir(dir)) != NULL) {
106 if (dp->d_name[0] == '.')
107 continue;
108 ++fd_count;
109 }
110 closedir(dir);
111 return fd_count;
112}
113#endif
114
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700115namespace cricket {
116
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000117class TurnPortTestVirtualSocketServer : public rtc::VirtualSocketServer {
118 public:
deadbeef98e186c2017-05-16 18:00:06 -0700119 TurnPortTestVirtualSocketServer() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700120 // This configures the virtual socket server to always add a simulated
121 // delay of exactly half of kSimulatedRtt.
122 set_delay_mean(kSimulatedRtt / 2);
123 UpdateDelayDistribution();
124 }
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000125
126 using rtc::VirtualSocketServer::LookupBinding;
127};
128
deadbeef376e1232015-11-25 09:00:08 -0800129class TestConnectionWrapper : public sigslot::has_slots<> {
130 public:
Steve Anton6c38cc72017-11-29 10:25:58 -0800131 explicit TestConnectionWrapper(Connection* conn) : connection_(conn) {
deadbeef376e1232015-11-25 09:00:08 -0800132 conn->SignalDestroyed.connect(
133 this, &TestConnectionWrapper::OnConnectionDestroyed);
134 }
135
136 Connection* connection() { return connection_; }
137
138 private:
139 void OnConnectionDestroyed(Connection* conn) {
140 ASSERT_TRUE(conn == connection_);
141 connection_ = nullptr;
142 }
143
144 Connection* connection_;
145};
146
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700147// Note: This test uses a fake clock with a simulated network round trip
148// (between local port and TURN server) of kSimulatedRtt.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200149class TurnPortTest : public ::testing::Test,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000150 public sigslot::has_slots<>,
151 public rtc::MessageHandler {
152 public:
153 TurnPortTest()
deadbeef98e186c2017-05-16 18:00:06 -0700154 : ss_(new TurnPortTestVirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700155 main_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156 socket_factory_(rtc::Thread::Current()),
nisse7eaa4ea2017-05-08 05:25:41 -0700157 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000158 turn_ready_(false),
159 turn_error_(false),
160 turn_unknown_address_(false),
161 turn_create_permission_success_(false),
Jonas Orelandc99dc312018-03-28 08:00:50 +0200162 turn_port_closed_(false),
163 turn_port_destroyed_(false),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164 udp_ready_(false),
165 test_finish_(false) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700166 // Some code uses "last received time == 0" to represent "nothing received
167 // so far", so we need to start the fake clock at a nonzero time...
168 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200169 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000170 }
171
172 virtual void OnMessage(rtc::Message* msg) {
nissec8ee8822017-01-18 07:20:55 -0800173 RTC_CHECK(msg->message_id == MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000174 if (msg->message_id == MSG_TESTFINISH)
175 test_finish_ = true;
176 }
177
Yves Gerey665174f2018-06-19 15:03:05 +0200178 void OnTurnPortComplete(Port* port) { turn_ready_ = true; }
179 void OnTurnPortError(Port* port) { turn_error_ = true; }
Eldar Relloda13ea22019-06-01 12:23:43 +0300180 void OnCandidateError(Port* port,
181 const cricket::IceCandidateErrorEvent& event) {
182 error_event_ = event;
183 }
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700184 void OnTurnUnknownAddress(PortInterface* port,
185 const SocketAddress& addr,
186 ProtocolType proto,
187 IceMessage* msg,
188 const std::string& rf,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000189 bool /*port_muxed*/) {
190 turn_unknown_address_ = true;
191 }
Honghai Zhangf67c5482015-12-11 15:16:54 -0800192 void OnTurnCreatePermissionResult(TurnPort* port,
193 const SocketAddress& addr,
194 int code) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000195 // Ignoring the address.
Honghai Zhangf67c5482015-12-11 15:16:54 -0800196 turn_create_permission_success_ = (code == 0);
197 }
198
199 void OnTurnRefreshResult(TurnPort* port, int code) {
200 turn_refresh_success_ = (code == 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000201 }
Yves Gerey665174f2018-06-19 15:03:05 +0200202 void OnTurnReadPacket(Connection* conn,
203 const char* data,
204 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +0100205 int64_t packet_time_us) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206 turn_packets_.push_back(rtc::Buffer(data, size));
207 }
Yves Gerey665174f2018-06-19 15:03:05 +0200208 void OnUdpPortComplete(Port* port) { udp_ready_ = true; }
209 void OnUdpReadPacket(Connection* conn,
210 const char* data,
211 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +0100212 int64_t packet_time_us) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000213 udp_packets_.push_back(rtc::Buffer(data, size));
214 }
215 void OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200216 const char* data,
217 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000218 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100219 const int64_t& packet_time_us) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100221 packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222 }
Yves Gerey665174f2018-06-19 15:03:05 +0200223 void OnTurnPortClosed(TurnPort* port) { turn_port_closed_ = true; }
224 void OnTurnPortDestroyed(PortInterface* port) { turn_port_destroyed_ = true; }
Jonas Orelandc99dc312018-03-28 08:00:50 +0200225
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000226 rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
Steve Anton31e5bf52018-05-07 10:42:55 -0700227 rtc::AsyncSocket* socket = ss_->CreateAsyncSocket(AF_INET, SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000228 EXPECT_GE(socket->Bind(addr), 0);
229 EXPECT_GE(socket->Listen(5), 0);
230 return socket;
231 }
232
deadbeef5c3c1042017-08-04 15:01:57 -0700233 rtc::Network* MakeNetwork(const SocketAddress& addr) {
234 networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
235 networks_.back().AddIP(addr.ipaddr());
236 return &networks_.back();
237 }
238
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000239 void CreateTurnPort(const std::string& username,
240 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700241 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700242 CreateTurnPortWithAllParams(MakeNetwork(kLocalAddr1), username, password,
243 server_address, std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000244 }
245 void CreateTurnPort(const rtc::SocketAddress& local_address,
246 const std::string& username,
247 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700248 const ProtocolAddress& server_address) {
deadbeef5c3c1042017-08-04 15:01:57 -0700249 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
250 server_address, std::string());
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000251 }
252
253 // Should be identical to CreateTurnPort but specifies an origin value
254 // when creating the instance of TurnPort.
255 void CreateTurnPortWithOrigin(const rtc::SocketAddress& local_address,
256 const std::string& username,
257 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700258 const ProtocolAddress& server_address,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000259 const std::string& origin) {
deadbeef5c3c1042017-08-04 15:01:57 -0700260 CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
261 server_address, origin);
262 }
263
264 void CreateTurnPortWithNetwork(rtc::Network* network,
265 const std::string& username,
266 const std::string& password,
267 const ProtocolAddress& server_address) {
268 CreateTurnPortWithAllParams(network, username, password, server_address,
269 std::string());
270 }
271
272 // Version of CreateTurnPort that takes all possible parameters; all other
273 // helper methods call this, such that "SetIceRole" and "ConnectSignals" (and
274 // possibly other things in the future) only happen in one place.
275 void CreateTurnPortWithAllParams(rtc::Network* network,
276 const std::string& username,
277 const std::string& password,
278 const ProtocolAddress& server_address,
279 const std::string& origin) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700280 RelayCredentials credentials(username, password);
Steve Antonf7dd9df2018-10-10 15:06:28 -0700281 turn_port_ = TurnPort::Create(
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000282 &main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
Steve Antona8f1e562018-10-10 11:29:44 -0700283 server_address, credentials, 0, origin, {}, {}, turn_customizer_.get());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000284 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700285 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000286 ConnectSignals();
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000287
288 if (server_address.proto == cricket::PROTO_TLS) {
289 // The test TURN server has a self-signed certificate so will not pass
290 // the normal client validation. Instruct the client to ignore certificate
291 // errors for testing only.
292 turn_port_->SetTlsCertPolicy(
293 TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
294 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000295 }
296
297 void CreateSharedTurnPort(const std::string& username,
298 const std::string& password,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700299 const ProtocolAddress& server_address) {
nissec8ee8822017-01-18 07:20:55 -0800300 RTC_CHECK(server_address.proto == PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301
302 if (!socket_) {
303 socket_.reset(socket_factory_.CreateUdpSocket(
304 rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
305 ASSERT_TRUE(socket_ != NULL);
Yves Gerey665174f2018-06-19 15:03:05 +0200306 socket_->SignalReadPacket.connect(this,
307 &TurnPortTest::OnSocketReadPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000308 }
309
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700310 RelayCredentials credentials(username, password);
Steve Antonf7dd9df2018-10-10 15:06:28 -0700311 turn_port_ =
312 TurnPort::Create(&main_, &socket_factory_, MakeNetwork(kLocalAddr1),
313 socket_.get(), kIceUfrag1, kIcePwd1, server_address,
314 credentials, 0, std::string(), nullptr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000315 // This TURN port will be the controlling.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700316 turn_port_->SetIceRole(ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000317 ConnectSignals();
318 }
319
320 void ConnectSignals() {
321 turn_port_->SignalPortComplete.connect(this,
Yves Gerey665174f2018-06-19 15:03:05 +0200322 &TurnPortTest::OnTurnPortComplete);
323 turn_port_->SignalPortError.connect(this, &TurnPortTest::OnTurnPortError);
Eldar Relloda13ea22019-06-01 12:23:43 +0300324 turn_port_->SignalCandidateError.connect(this,
325 &TurnPortTest::OnCandidateError);
Yves Gerey665174f2018-06-19 15:03:05 +0200326 turn_port_->SignalUnknownAddress.connect(
327 this, &TurnPortTest::OnTurnUnknownAddress);
328 turn_port_->SignalCreatePermissionResult.connect(
329 this, &TurnPortTest::OnTurnCreatePermissionResult);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800330 turn_port_->SignalTurnRefreshResult.connect(
331 this, &TurnPortTest::OnTurnRefreshResult);
Yves Gerey665174f2018-06-19 15:03:05 +0200332 turn_port_->SignalTurnPortClosed.connect(this,
333 &TurnPortTest::OnTurnPortClosed);
334 turn_port_->SignalDestroyed.connect(this,
335 &TurnPortTest::OnTurnPortDestroyed);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800336 }
deadbeef376e1232015-11-25 09:00:08 -0800337
338 void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
339
340 void CreateUdpPort(const SocketAddress& address) {
Steve Antona8f1e562018-10-10 11:29:44 -0700341 udp_port_ = UDPPort::Create(&main_, &socket_factory_, MakeNetwork(address),
342 0, 0, kIceUfrag2, kIcePwd2, std::string(),
343 false, absl::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000344 // UDP port will be controlled.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700345 udp_port_->SetIceRole(ICEROLE_CONTROLLED);
Yves Gerey665174f2018-06-19 15:03:05 +0200346 udp_port_->SignalPortComplete.connect(this,
347 &TurnPortTest::OnUdpPortComplete);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000348 }
349
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700350 void PrepareTurnAndUdpPorts(ProtocolType protocol_type) {
Honghai Zhangf67c5482015-12-11 15:16:54 -0800351 // turn_port_ should have been created.
352 ASSERT_TRUE(turn_port_ != nullptr);
353 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700354 ASSERT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700355 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800356
357 CreateUdpPort();
358 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700359 ASSERT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800360 }
361
Steve Antoned447ae2017-08-17 14:31:51 -0700362 // Returns the fake clock time to establish a connection over the given
363 // protocol.
364 int TimeToConnect(ProtocolType protocol_type) {
365 switch (protocol_type) {
366 case PROTO_TCP:
367 // The virtual socket server will delay by a fixed half a round trip
368 // for a TCP connection.
369 return kSimulatedRtt / 2;
Steve Anton786de702017-08-17 15:15:46 -0700370 case PROTO_TLS:
371 // TLS operates over TCP and additionally has a round of HELLO for
372 // negotiating ciphers and a round for exchanging certificates.
373 return 2 * kSimulatedRtt + TimeToConnect(PROTO_TCP);
Steve Antoned447ae2017-08-17 14:31:51 -0700374 case PROTO_UDP:
375 default:
376 // UDP requires no round trips to set up the connection.
377 return 0;
378 }
379 }
380
381 // Returns the total fake clock time to establish a connection with a TURN
382 // server over the given protocol and to allocate a TURN candidate.
383 int TimeToGetTurnCandidate(ProtocolType protocol_type) {
384 // For a simple allocation, the first Allocate message will return with an
385 // error asking for credentials and will succeed after the second Allocate
386 // message.
387 return 2 * kSimulatedRtt + TimeToConnect(protocol_type);
388 }
389
390 // Total fake clock time to do the following:
391 // 1. Connect to primary TURN server
392 // 2. Send Allocate and receive a redirect from the primary TURN server
393 // 3. Connect to alternate TURN server
394 // 4. Send Allocate and receive a request for credentials
395 // 5. Send Allocate with credentials and receive allocation
396 int TimeToGetAlternateTurnCandidate(ProtocolType protocol_type) {
397 return 3 * kSimulatedRtt + 2 * TimeToConnect(protocol_type);
398 }
399
honghaiz079a7a12016-06-22 16:26:29 -0700400 bool CheckConnectionFailedAndPruned(Connection* conn) {
hbos06495bc2017-01-02 08:08:18 -0800401 return conn && !conn->active() &&
402 conn->state() == IceCandidatePairState::FAILED;
honghaiz079a7a12016-06-22 16:26:29 -0700403 }
404
405 // Checks that |turn_port_| has a nonempty set of connections and they are all
406 // failed and pruned.
407 bool CheckAllConnectionsFailedAndPruned() {
408 auto& connections = turn_port_->connections();
409 if (connections.empty()) {
410 return false;
411 }
Mirko Bonadei739baf02019-01-27 17:29:42 +0100412 for (const auto& kv : connections) {
honghaiz079a7a12016-06-22 16:26:29 -0700413 if (!CheckConnectionFailedAndPruned(kv.second)) {
414 return false;
415 }
416 }
417 return true;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800418 }
419
Steve Antoned447ae2017-08-17 14:31:51 -0700420 void TestReconstructedServerUrl(ProtocolType protocol_type,
421 const char* expected_url) {
422 turn_port_->PrepareAddress();
423 ASSERT_TRUE_SIMULATED_WAIT(
424 turn_ready_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
425 ASSERT_EQ(1U, turn_port_->Candidates().size());
426 EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_url);
427 }
428
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700429 void TestTurnAlternateServer(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000430 std::vector<rtc::SocketAddress> redirect_addresses;
431 redirect_addresses.push_back(kTurnAlternateIntAddr);
432
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700433 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000434
435 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
436 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
437 turn_server_.set_redirect_hook(&redirector);
438 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700439 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000440
441 // Retrieve the address before we run the state machine.
442 const SocketAddress old_addr = turn_port_->server_address().address;
443
444 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700445 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_,
446 TimeToGetAlternateTurnCandidate(protocol_type),
447 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000448 // Retrieve the address again, the turn port's address should be
449 // changed.
450 const SocketAddress new_addr = turn_port_->server_address().address;
451 EXPECT_NE(old_addr, new_addr);
452 ASSERT_EQ(1U, turn_port_->Candidates().size());
453 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
454 turn_port_->Candidates()[0].address().ipaddr());
455 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
456 }
457
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700458 void TestTurnAlternateServerV4toV6(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000459 std::vector<rtc::SocketAddress> redirect_addresses;
460 redirect_addresses.push_back(kTurnIPv6IntAddr);
461
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700462 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000463 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
464 turn_server_.set_redirect_hook(&redirector);
465 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700466 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000467 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700468 // Need time to connect to TURN server, send Allocate request and receive
469 // redirect notice.
470 EXPECT_TRUE_SIMULATED_WAIT(
471 turn_error_, kSimulatedRtt + TimeToConnect(protocol_type), fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000472 }
473
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700474 void TestTurnAlternateServerPingPong(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000475 std::vector<rtc::SocketAddress> redirect_addresses;
476 redirect_addresses.push_back(kTurnAlternateIntAddr);
477 redirect_addresses.push_back(kTurnIntAddr);
478
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700479 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000480
481 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
482 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
483 turn_server_.set_redirect_hook(&redirector);
484 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700485 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000486
487 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700488 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
489 TimeToGetAlternateTurnCandidate(protocol_type),
490 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000491 ASSERT_EQ(0U, turn_port_->Candidates().size());
492 rtc::SocketAddress address;
493 // Verify that we have exhausted all alternate servers instead of
494 // failure caused by other errors.
495 EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
496 }
497
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700498 void TestTurnAlternateServerDetectRepetition(ProtocolType protocol_type) {
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000499 std::vector<rtc::SocketAddress> redirect_addresses;
500 redirect_addresses.push_back(kTurnAlternateIntAddr);
501 redirect_addresses.push_back(kTurnAlternateIntAddr);
502
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700503 TestTurnRedirector redirector(redirect_addresses);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000504
505 turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
506 turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
507 turn_server_.set_redirect_hook(&redirector);
508 CreateTurnPort(kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700509 ProtocolAddress(kTurnIntAddr, protocol_type));
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000510
511 turn_port_->PrepareAddress();
Steve Antoned447ae2017-08-17 14:31:51 -0700512 EXPECT_TRUE_SIMULATED_WAIT(turn_error_,
513 TimeToGetAlternateTurnCandidate(protocol_type),
514 fake_clock_);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000515 ASSERT_EQ(0U, turn_port_->Candidates().size());
516 }
517
deadbeeffb70b452016-10-24 13:15:59 -0700518 // A certain security exploit works by redirecting to a loopback address,
519 // which doesn't ever actually make sense. So redirects to loopback should
520 // be treated as errors.
521 // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
522 void TestTurnAlternateServerLoopback(ProtocolType protocol_type, bool ipv6) {
523 const SocketAddress& local_address = ipv6 ? kLocalIPv6Addr : kLocalAddr1;
524 const SocketAddress& server_address =
525 ipv6 ? kTurnIPv6IntAddr : kTurnIntAddr;
526
527 std::vector<rtc::SocketAddress> redirect_addresses;
deadbeef99220162016-10-27 18:30:23 -0700528 // Pick an unusual address in the 127.0.0.0/8 range to make sure more than
529 // 127.0.0.1 is covered.
530 SocketAddress loopback_address(ipv6 ? "::1" : "127.1.2.3",
deadbeeffb70b452016-10-24 13:15:59 -0700531 TURN_SERVER_PORT);
532 redirect_addresses.push_back(loopback_address);
533
534 // Make a socket and bind it to the local port, to make extra sure no
535 // packet is sent to this address.
536 std::unique_ptr<rtc::Socket> loopback_socket(ss_->CreateSocket(
Steve Anton31e5bf52018-05-07 10:42:55 -0700537 AF_INET, protocol_type == PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM));
deadbeeffb70b452016-10-24 13:15:59 -0700538 ASSERT_NE(nullptr, loopback_socket.get());
539 ASSERT_EQ(0, loopback_socket->Bind(loopback_address));
540 if (protocol_type == PROTO_TCP) {
541 ASSERT_EQ(0, loopback_socket->Listen(1));
542 }
543
544 TestTurnRedirector redirector(redirect_addresses);
545
546 turn_server_.AddInternalSocket(server_address, protocol_type);
547 turn_server_.set_redirect_hook(&redirector);
548 CreateTurnPort(local_address, kTurnUsername, kTurnPassword,
549 ProtocolAddress(server_address, protocol_type));
550
551 turn_port_->PrepareAddress();
552 EXPECT_TRUE_SIMULATED_WAIT(
Steve Antoned447ae2017-08-17 14:31:51 -0700553 turn_error_, TimeToGetTurnCandidate(protocol_type), fake_clock_);
deadbeeffb70b452016-10-24 13:15:59 -0700554
555 // Wait for some extra time, and make sure no packets were received on the
556 // loopback port we created (or in the case of TCP, no connection attempt
557 // occurred).
558 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
559 if (protocol_type == PROTO_UDP) {
560 char buf[1];
561 EXPECT_EQ(-1, loopback_socket->Recv(&buf, 1, nullptr));
562 } else {
563 std::unique_ptr<rtc::Socket> accepted_socket(
564 loopback_socket->Accept(nullptr));
565 EXPECT_EQ(nullptr, accepted_socket.get());
566 }
567 }
568
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700569 void TestTurnConnection(ProtocolType protocol_type) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000570 // Create ports and prepare addresses.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700571 PrepareTurnAndUdpPorts(protocol_type);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000572
573 // Send ping from UDP to TURN.
Steve Anton786de702017-08-17 15:15:46 -0700574 ASSERT_GE(turn_port_->Candidates().size(), 1U);
Yves Gerey665174f2018-06-19 15:03:05 +0200575 Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
576 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000577 ASSERT_TRUE(conn1 != NULL);
578 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700579 SIMULATED_WAIT(!turn_unknown_address_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000580 EXPECT_FALSE(turn_unknown_address_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700581 EXPECT_FALSE(conn1->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000582 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
583
584 // Send ping from TURN to UDP.
Yves Gerey665174f2018-06-19 15:03:05 +0200585 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
586 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000587 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700588 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
589 fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000590 conn2->Ping(0);
591
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700592 // Two hops from TURN port to UDP port through TURN server, thus two RTTs.
593 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
594 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700595 EXPECT_TRUE(conn1->receiving());
596 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000597 EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
598
599 // Send another ping from UDP to TURN.
600 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700601 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
602 kSimulatedRtt * 2, fake_clock_);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700603 EXPECT_TRUE(conn2->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000604 }
605
honghaiz32f39962015-11-17 11:36:31 -0800606 void TestDestroyTurnConnection() {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700607 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz32f39962015-11-17 11:36:31 -0800608
609 // Create connections on both ends.
610 Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
611 Port::ORIGIN_MESSAGE);
612 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
613 Port::ORIGIN_MESSAGE);
614 ASSERT_TRUE(conn2 != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700615 ASSERT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
616 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800617 // Make sure turn connection can receive.
618 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700619 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
620 kSimulatedRtt * 2, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800621 EXPECT_FALSE(turn_unknown_address_);
622
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700623 // Destroy the connection on the TURN port. The TurnEntry still exists, so
624 // the TURN port should still process a ping from an unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800625 conn2->Destroy();
626 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700627 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
628 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800629
630 // Flush all requests in the invoker to destroy the TurnEntry.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700631 // Expect that it still processes an incoming ping and signals the
632 // unknown address.
honghaiz32f39962015-11-17 11:36:31 -0800633 turn_unknown_address_ = false;
634 turn_port_->invoker()->Flush(rtc::Thread::Current());
635 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700636 EXPECT_TRUE_SIMULATED_WAIT(turn_unknown_address_, kSimulatedRtt,
637 fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800638
639 // If the connection is created again, it will start to receive pings.
640 conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
641 Port::ORIGIN_MESSAGE);
642 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700643 EXPECT_TRUE_SIMULATED_WAIT(conn2->receiving(), kSimulatedRtt, fake_clock_);
honghaiz32f39962015-11-17 11:36:31 -0800644 }
645
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700646 void TestTurnSendData(ProtocolType protocol_type) {
647 PrepareTurnAndUdpPorts(protocol_type);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800648
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000649 // Create connections and send pings.
Yves Gerey665174f2018-06-19 15:03:05 +0200650 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
651 Port::ORIGIN_MESSAGE);
652 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
653 Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000654 ASSERT_TRUE(conn1 != NULL);
655 ASSERT_TRUE(conn2 != NULL);
656 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
657 &TurnPortTest::OnTurnReadPacket);
658 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
659 &TurnPortTest::OnUdpReadPacket);
660 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700661 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
662 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000663 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700664 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
665 kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000666
667 // Send some data.
668 size_t num_packets = 256;
669 for (size_t i = 0; i < num_packets; ++i) {
Yves Gerey665174f2018-06-19 15:03:05 +0200670 unsigned char buf[256] = {0};
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000671 for (size_t j = 0; j < i + 1; ++j) {
672 buf[j] = 0xFF - static_cast<unsigned char>(j);
673 }
674 conn1->Send(buf, i + 1, options);
675 conn2->Send(buf, i + 1, options);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700676 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000677 }
678
679 // Check the data.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700680 ASSERT_EQ(num_packets, turn_packets_.size());
681 ASSERT_EQ(num_packets, udp_packets_.size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000682 for (size_t i = 0; i < num_packets; ++i) {
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000683 EXPECT_EQ(i + 1, turn_packets_[i].size());
684 EXPECT_EQ(i + 1, udp_packets_[i].size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000685 EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
686 }
687 }
688
Steve Antoned447ae2017-08-17 14:31:51 -0700689 // Test that a TURN allocation is released when the port is closed.
690 void TestTurnReleaseAllocation(ProtocolType protocol_type) {
691 PrepareTurnAndUdpPorts(protocol_type);
692 turn_port_.reset();
693 EXPECT_EQ_SIMULATED_WAIT(0U, turn_server_.server()->allocations().size(),
694 kSimulatedRtt, fake_clock_);
695 }
696
Jonas Orelandc99dc312018-03-28 08:00:50 +0200697 // Test that the TURN allocation is released by sending a refresh request
698 // with lifetime 0 when Release is called.
699 void TestTurnGracefulReleaseAllocation(ProtocolType protocol_type) {
700 PrepareTurnAndUdpPorts(protocol_type);
701
702 // Create connections and send pings.
Yves Gerey665174f2018-06-19 15:03:05 +0200703 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
704 Port::ORIGIN_MESSAGE);
705 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
706 Port::ORIGIN_MESSAGE);
Jonas Orelandc99dc312018-03-28 08:00:50 +0200707 ASSERT_TRUE(conn1 != NULL);
708 ASSERT_TRUE(conn2 != NULL);
709 conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
710 &TurnPortTest::OnTurnReadPacket);
711 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
712 &TurnPortTest::OnUdpReadPacket);
713 conn1->Ping(0);
714 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn1->write_state(),
715 kSimulatedRtt * 2, fake_clock_);
716 conn2->Ping(0);
717 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
718 kSimulatedRtt * 2, fake_clock_);
719
720 // Send some data from Udp to TurnPort.
Yves Gerey665174f2018-06-19 15:03:05 +0200721 unsigned char buf[256] = {0};
Jonas Orelandc99dc312018-03-28 08:00:50 +0200722 conn2->Send(buf, sizeof(buf), options);
723
724 // Now release the TurnPort allocation.
725 // This will send a REFRESH with lifetime 0 to server.
726 turn_port_->Release();
727
728 // Wait for the TurnPort to signal closed.
729 ASSERT_TRUE_SIMULATED_WAIT(turn_port_closed_, kSimulatedRtt, fake_clock_);
730
731 // But the data should have arrived first.
732 ASSERT_EQ(1ul, turn_packets_.size());
733 EXPECT_EQ(sizeof(buf), turn_packets_[0].size());
734
735 // The allocation is released at server.
736 EXPECT_EQ(0U, turn_server_.server()->allocations().size());
737 }
738
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000739 protected:
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700740 rtc::ScopedFakeClock fake_clock_;
deadbeef5c3c1042017-08-04 15:01:57 -0700741 // When a "create port" helper method is called with an IP, we create a
742 // Network with that IP and add it to this list. Using a list instead of a
743 // vector so that when it grows, pointers aren't invalidated.
744 std::list<rtc::Network> networks_;
kwiberg3ec46792016-04-27 07:22:53 -0700745 std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700746 rtc::AutoSocketServerThread main_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000747 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700748 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700749 TestTurnServer turn_server_;
kwiberg3ec46792016-04-27 07:22:53 -0700750 std::unique_ptr<TurnPort> turn_port_;
751 std::unique_ptr<UDPPort> udp_port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000752 bool turn_ready_;
753 bool turn_error_;
754 bool turn_unknown_address_;
755 bool turn_create_permission_success_;
Jonas Orelandc99dc312018-03-28 08:00:50 +0200756 bool turn_port_closed_;
757 bool turn_port_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000758 bool udp_ready_;
759 bool test_finish_;
Honghai Zhangf67c5482015-12-11 15:16:54 -0800760 bool turn_refresh_success_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000761 std::vector<rtc::Buffer> turn_packets_;
762 std::vector<rtc::Buffer> udp_packets_;
763 rtc::PacketOptions options;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200764 std::unique_ptr<webrtc::TurnCustomizer> turn_customizer_;
Eldar Relloda13ea22019-06-01 12:23:43 +0300765 cricket::IceCandidateErrorEvent error_event_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000766};
767
Honghai Zhangd00c0572016-06-28 09:44:47 -0700768TEST_F(TurnPortTest, TestTurnPortType) {
769 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
770 EXPECT_EQ(cricket::RELAY_PORT_TYPE, turn_port_->Type());
771}
772
zhihuang26d99c22017-02-13 12:47:27 -0800773// Tests that the URL of the servers can be correctly reconstructed when
774// gathering the candidates.
Steve Antoned447ae2017-08-17 14:31:51 -0700775TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv4) {
zhihuang26d99c22017-02-13 12:47:27 -0800776 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700777 TestReconstructedServerUrl(PROTO_UDP, "turn:99.99.99.3:3478?transport=udp");
778}
zhihuang26d99c22017-02-13 12:47:27 -0800779
Steve Antoned447ae2017-08-17 14:31:51 -0700780TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv6) {
zhihuang26d99c22017-02-13 12:47:27 -0800781 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
782 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
783 kTurnUdpIPv6ProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700784 TestReconstructedServerUrl(
785 PROTO_UDP,
786 "turn:2400:4030:1:2c00:be30:abcd:efab:cdef:3478?transport=udp");
787}
zhihuang26d99c22017-02-13 12:47:27 -0800788
Steve Antoned447ae2017-08-17 14:31:51 -0700789TEST_F(TurnPortTest, TestReconstructedServerUrlForTcp) {
zhihuang26d99c22017-02-13 12:47:27 -0800790 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
791 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -0700792 TestReconstructedServerUrl(PROTO_TCP, "turn:99.99.99.4:3478?transport=tcp");
zhihuang26d99c22017-02-13 12:47:27 -0800793}
794
Steve Anton786de702017-08-17 15:15:46 -0700795TEST_F(TurnPortTest, TestReconstructedServerUrlForTls) {
796 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
797 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
798 TestReconstructedServerUrl(PROTO_TLS, "turns:99.99.99.4:3478?transport=tcp");
799}
800
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000801// Do a normal TURN allocation.
802TEST_F(TurnPortTest, TestTurnAllocate) {
803 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Yves Gerey665174f2018-06-19 15:03:05 +0200804 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000805 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700806 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000807 ASSERT_EQ(1U, turn_port_->Candidates().size());
808 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
809 turn_port_->Candidates()[0].address().ipaddr());
810 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
811}
812
Jonas Oreland3c028422019-08-22 16:16:35 +0200813class TurnLoggingIdValidator : public StunMessageObserver {
814 public:
815 explicit TurnLoggingIdValidator(const char* expect_val)
816 : expect_val_(expect_val) {}
817 ~TurnLoggingIdValidator() {}
818 void ReceivedMessage(const TurnMessage* msg) override {
819 if (msg->type() == cricket::STUN_ALLOCATE_REQUEST) {
820 const StunByteStringAttribute* attr =
821 msg->GetByteString(cricket::STUN_ATTR_TURN_LOGGING_ID);
822 if (expect_val_) {
823 ASSERT_NE(nullptr, attr);
824 ASSERT_EQ(expect_val_, attr->GetString());
825 } else {
826 EXPECT_EQ(nullptr, attr);
827 }
828 }
829 }
830 void ReceivedChannelData(const char* data, size_t size) override {}
831
832 private:
833 const char* expect_val_;
834};
835
836TEST_F(TurnPortTest, TestTurnAllocateWithLoggingId) {
837 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
838 turn_port_->SetTurnLoggingId("KESO");
839 turn_server_.server()->SetStunMessageObserver(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200840 std::make_unique<TurnLoggingIdValidator>("KESO"));
Jonas Oreland3c028422019-08-22 16:16:35 +0200841 turn_port_->PrepareAddress();
842 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
843 ASSERT_EQ(1U, turn_port_->Candidates().size());
844 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
845 turn_port_->Candidates()[0].address().ipaddr());
846 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
847}
848
849TEST_F(TurnPortTest, TestTurnAllocateWithoutLoggingId) {
850 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
851 turn_server_.server()->SetStunMessageObserver(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200852 std::make_unique<TurnLoggingIdValidator>(nullptr));
Jonas Oreland3c028422019-08-22 16:16:35 +0200853 turn_port_->PrepareAddress();
854 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
855 ASSERT_EQ(1U, turn_port_->Candidates().size());
856 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
857 turn_port_->Candidates()[0].address().ipaddr());
858 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
859}
860
Eldar Relloda13ea22019-06-01 12:23:43 +0300861// Test bad credentials.
862TEST_F(TurnPortTest, TestTurnBadCredentials) {
863 CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
864 turn_port_->PrepareAddress();
865 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt * 3, fake_clock_);
866 ASSERT_EQ(0U, turn_port_->Candidates().size());
867 EXPECT_EQ_SIMULATED_WAIT(error_event_.error_code, STUN_ERROR_UNAUTHORIZED,
868 kSimulatedRtt * 3, fake_clock_);
869 EXPECT_EQ(error_event_.error_text, "Unauthorized");
870}
871
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000872// Testing a normal UDP allocation using TCP connection.
873TEST_F(TurnPortTest, TestTurnTcpAllocate) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700874 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000875 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Yves Gerey665174f2018-06-19 15:03:05 +0200876 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000877 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700878 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000879 ASSERT_EQ(1U, turn_port_->Candidates().size());
880 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
881 turn_port_->Candidates()[0].address().ipaddr());
882 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
883}
884
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000885// Test case for WebRTC issue 3927 where a proxy binds to the local host address
886// instead the address that TurnPort originally bound to. The candidate pair
887// impacted by this behavior should still be used.
888TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
deadbeef5c3c1042017-08-04 15:01:57 -0700889 SocketAddress local_address("127.0.0.1", 0);
890 // After calling this, when TurnPort attempts to get a socket bound to
891 // kLocalAddr, it will end up using localhost instead.
892 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), local_address.ipaddr());
893
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700894 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef5c3c1042017-08-04 15:01:57 -0700895 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000896 EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
897 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700898 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000899 ASSERT_EQ(1U, turn_port_->Candidates().size());
900 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
901 turn_port_->Candidates()[0].address().ipaddr());
902 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
deadbeef5c3c1042017-08-04 15:01:57 -0700903
904 // Verify that the socket actually used localhost, otherwise this test isn't
905 // doing what it meant to.
906 ASSERT_EQ(local_address.ipaddr(),
907 turn_port_->Candidates()[0].related_address().ipaddr());
908}
909
910// If the address the socket ends up bound to does not match any address of the
911// TurnPort's Network, then the socket should be discarded and no candidates
912// should be signaled. In the context of ICE, where one TurnPort is created for
913// each Network, when this happens it's likely that the unexpected address is
914// associated with some other Network, which another TurnPort is already
915// covering.
916TEST_F(TurnPortTest,
917 TurnTcpAllocationDiscardedIfBoundAddressDoesNotMatchNetwork) {
918 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
919 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
920
921 // Set up TURN server to use TCP (this logic only exists for TCP).
922 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
923
924 // Create TURN port and tell it to start allocation.
925 CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
926 turn_port_->PrepareAddress();
927
928 // Shouldn't take more than 1 RTT to realize the bound address isn't the one
929 // expected.
930 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
Eldar Relloda13ea22019-06-01 12:23:43 +0300931 EXPECT_EQ_SIMULATED_WAIT(error_event_.error_code, STUN_ERROR_GLOBAL_FAILURE,
932 kSimulatedRtt, fake_clock_);
933 ASSERT_NE(error_event_.error_text.find("."), std::string::npos);
934 ASSERT_NE(
935 error_event_.host_candidate.find(kLocalAddr2.HostAsSensitiveURIString()),
936 std::string::npos);
937 std::string server_url =
938 "turn:" + kTurnTcpIntAddr.ToString() + "?transport=tcp";
939 ASSERT_EQ(error_event_.url, server_url);
deadbeef5c3c1042017-08-04 15:01:57 -0700940}
941
942// A caveat for the above logic: if the socket ends up bound to one of the IPs
943// associated with the Network, just not the "best" one, this is ok.
944TEST_F(TurnPortTest, TurnTcpAllocationNotDiscardedIfNotBoundToBestIP) {
945 // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
946 ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
947
948 // Set up a network with kLocalAddr1 as the "best" IP, and kLocalAddr2 as an
949 // alternate.
950 rtc::Network* network = MakeNetwork(kLocalAddr1);
951 network->AddIP(kLocalAddr2.ipaddr());
952 ASSERT_EQ(kLocalAddr1.ipaddr(), network->GetBestIP());
953
954 // Set up TURN server to use TCP (this logic only exists for TCP).
955 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
956
957 // Create TURN port using our special Network, and tell it to start
958 // allocation.
959 CreateTurnPortWithNetwork(network, kTurnUsername, kTurnPassword,
960 kTurnTcpProtoAddr);
961 turn_port_->PrepareAddress();
962
963 // Candidate should be gathered as normally.
964 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
965 ASSERT_EQ(1U, turn_port_->Candidates().size());
966
967 // Verify that the socket actually used the alternate address, otherwise this
968 // test isn't doing what it meant to.
969 ASSERT_EQ(kLocalAddr2.ipaddr(),
970 turn_port_->Candidates()[0].related_address().ipaddr());
guoweis@webrtc.org4fba2932014-12-18 04:45:05 +0000971}
972
Taylor Brandstetter01cb5f22018-03-07 15:49:32 -0800973// Regression test for crbug.com/webrtc/8972, caused by buggy comparison
974// between rtc::IPAddress and rtc::InterfaceAddress.
975TEST_F(TurnPortTest, TCPPortNotDiscardedIfBoundToTemporaryIP) {
976 networks_.emplace_back("unittest", "unittest", kLocalIPv6Addr.ipaddr(), 32);
977 networks_.back().AddIP(rtc::InterfaceAddress(
978 kLocalIPv6Addr.ipaddr(), rtc::IPV6_ADDRESS_FLAG_TEMPORARY));
979
980 // Set up TURN server to use TCP (this logic only exists for TCP).
981 turn_server_.AddInternalSocket(kTurnIPv6IntAddr, PROTO_TCP);
982
983 // Create TURN port using our special Network, and tell it to start
984 // allocation.
985 CreateTurnPortWithNetwork(
986 &networks_.back(), kTurnUsername, kTurnPassword,
987 cricket::ProtocolAddress(kTurnIPv6IntAddr, PROTO_TCP));
988 turn_port_->PrepareAddress();
989
990 // Candidate should be gathered as normally.
991 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
992 ASSERT_EQ(1U, turn_port_->Candidates().size());
993}
994
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000995// Testing turn port will attempt to create TCP socket on address resolution
996// failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700997TEST_F(TurnPortTest, TestTurnTcpOnAddressResolveFailure) {
998 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
999 CreateTurnPort(kTurnUsername, kTurnPassword,
Eldar Relloda13ea22019-06-01 12:23:43 +03001000 ProtocolAddress(kTurnInvalidAddr, PROTO_TCP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001001 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001002 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001003 // As VSS doesn't provide a DNS resolution, name resolve will fail. TurnPort
1004 // will proceed in creating a TCP socket which will fail as there is no
1005 // server on the above domain and error will be set to SOCKET_ERROR.
1006 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
Eldar Relloda13ea22019-06-01 12:23:43 +03001007 EXPECT_EQ_SIMULATED_WAIT(error_event_.error_code, SERVER_NOT_REACHABLE_ERROR,
1008 kSimulatedRtt, fake_clock_);
1009 std::string server_url =
1010 "turn:" + kTurnInvalidAddr.ToString() + "?transport=tcp";
1011 ASSERT_EQ(error_event_.url, server_url);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001012}
1013
Steve Anton786de702017-08-17 15:15:46 -07001014// Testing turn port will attempt to create TLS socket on address resolution
1015// failure.
1016TEST_F(TurnPortTest, TestTurnTlsOnAddressResolveFailure) {
1017 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1018 CreateTurnPort(kTurnUsername, kTurnPassword,
Eldar Relloda13ea22019-06-01 12:23:43 +03001019 ProtocolAddress(kTurnInvalidAddr, PROTO_TLS));
Steve Anton786de702017-08-17 15:15:46 -07001020 turn_port_->PrepareAddress();
1021 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
1022 EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
1023}
1024
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001025// In case of UDP on address resolve failure, TurnPort will not create socket
1026// and return allocate failure.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001027TEST_F(TurnPortTest, TestTurnUdpOnAddressResolveFailure) {
1028 CreateTurnPort(kTurnUsername, kTurnPassword,
Eldar Relloda13ea22019-06-01 12:23:43 +03001029 ProtocolAddress(kTurnInvalidAddr, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001030 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001031 EXPECT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001032 // Error from turn port will not be socket error.
1033 EXPECT_NE(SOCKET_ERROR, turn_port_->error());
1034}
1035
1036// Try to do a TURN allocation with an invalid password.
1037TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
1038 CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
1039 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001040 EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001041 ASSERT_EQ(0U, turn_port_->Candidates().size());
1042}
1043
honghaizc463e202016-02-01 15:19:08 -08001044// Tests that TURN port nonce will be reset when receiving an ALLOCATE MISMATCH
1045// error.
1046TEST_F(TurnPortTest, TestTurnAllocateNonceResetAfterAllocateMismatch) {
1047 // Do a normal allocation first.
1048 CreateTurnPort(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_);
honghaizc463e202016-02-01 15:19:08 -08001051 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1052 // Destroy the turnport while keeping the drop probability to 1 to
1053 // suppress the release of the allocation at the server.
1054 ss_->set_drop_probability(1.0);
1055 turn_port_.reset();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001056 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -08001057 ss_->set_drop_probability(0.0);
1058
1059 // Force the socket server to assign the same port.
1060 ss_->SetNextPortForTesting(first_addr.port());
1061 turn_ready_ = false;
1062 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1063
1064 // It is expected that the turn port will first get a nonce from the server
1065 // using timestamp |ts_before| but then get an allocate mismatch error and
1066 // receive an even newer nonce based on the system clock. |ts_before| is
1067 // chosen so that the two NONCEs generated by the server will be different.
nisse1bffc1d2016-05-02 08:18:55 -07001068 int64_t ts_before = rtc::TimeMillis() - 1;
honghaizc463e202016-02-01 15:19:08 -08001069 std::string first_nonce =
1070 turn_server_.server()->SetTimestampForNextNonce(ts_before);
1071 turn_port_->PrepareAddress();
1072
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001073 // Four round trips; first we'll get "stale nonce", then
1074 // "allocate mismatch", then "stale nonce" again, then finally it will
1075 // succeed.
1076 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
honghaizc463e202016-02-01 15:19:08 -08001077 EXPECT_NE(first_nonce, turn_port_->nonce());
1078}
1079
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001080// Tests that a new local address is created after
1081// STUN_ERROR_ALLOCATION_MISMATCH.
1082TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
1083 // Do a normal allocation first.
1084 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1085 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001086 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001087 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1088
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001089 // Clear connected_ flag on turnport to suppress the release of
1090 // the allocation.
1091 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1092
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001093 // Forces the socket server to assign the same port.
1094 ss_->SetNextPortForTesting(first_addr.port());
1095
1096 turn_ready_ = false;
1097 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1098 turn_port_->PrepareAddress();
1099
1100 // Verifies that the new port has the same address.
1101 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1102
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001103 // Four round trips; first we'll get "stale nonce", then
1104 // "allocate mismatch", then "stale nonce" again, then finally it will
1105 // succeed.
1106 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001107
1108 // Verifies that the new port has a different address now.
1109 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
Sergey Ulanov17fa6722016-05-10 10:20:47 -07001110
1111 // Verify that all packets received from the shared socket are ignored.
1112 std::string test_packet = "Test packet";
1113 EXPECT_FALSE(turn_port_->HandleIncomingPacket(
1114 socket_.get(), test_packet.data(), test_packet.size(),
Niels Möller15ca5a92018-11-01 14:32:47 +01001115 rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0), rtc::TimeMicros()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001116}
1117
1118// Tests that a shared-socket-TurnPort creates its own socket after
1119// STUN_ERROR_ALLOCATION_MISMATCH.
1120TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
1121 // Do a normal allocation first.
1122 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1123 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001124 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001125 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1126
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001127 // Clear connected_ flag on turnport to suppress the release of
1128 // the allocation.
1129 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1130
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001131 turn_ready_ = false;
1132 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1133
1134 // Verifies that the new port has the same address.
1135 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1136 EXPECT_TRUE(turn_port_->SharedSocket());
1137
1138 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001139 // Extra 2 round trips due to allocate mismatch.
1140 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 4, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001141
1142 // Verifies that the new port has a different address now.
1143 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1144 EXPECT_FALSE(turn_port_->SharedSocket());
1145}
1146
1147TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001148 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001149 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1150
1151 // Do a normal allocation first.
1152 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001153 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001154 rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
1155
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001156 // Clear connected_ flag on turnport to suppress the release of
1157 // the allocation.
1158 turn_port_->OnSocketClose(turn_port_->socket(), 0);
1159
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001160 // Forces the socket server to assign the same port.
1161 ss_->SetNextPortForTesting(first_addr.port());
1162
1163 turn_ready_ = false;
1164 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1165 turn_port_->PrepareAddress();
1166
1167 // Verifies that the new port has the same address.
1168 EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
1169
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001170 // Extra 2 round trips due to allocate mismatch.
1171 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 5, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001172
1173 // Verifies that the new port has a different address now.
1174 EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
1175}
1176
Honghai Zhangf67c5482015-12-11 15:16:54 -08001177TEST_F(TurnPortTest, TestRefreshRequestGetsErrorResponse) {
1178 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001179 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz6b9ab922016-01-05 09:06:12 -08001180 turn_port_->CreateConnection(udp_port_->Candidates()[0],
1181 Port::ORIGIN_MESSAGE);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001182 // Set bad credentials.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001183 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001184 turn_port_->set_credentials(bad_credentials);
1185 turn_refresh_success_ = false;
1186 // This sends out the first RefreshRequest with correct credentials.
1187 // When this succeeds, it will schedule a new RefreshRequest with the bad
1188 // credential.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001189 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1190 EXPECT_TRUE_SIMULATED_WAIT(turn_refresh_success_, kSimulatedRtt, fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001191 // Flush it again, it will receive a bad response.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001192 turn_port_->FlushRequests(TURN_REFRESH_REQUEST);
1193 EXPECT_TRUE_SIMULATED_WAIT(!turn_refresh_success_, kSimulatedRtt,
1194 fake_clock_);
1195 EXPECT_FALSE(turn_port_->connected());
1196 EXPECT_TRUE(CheckAllConnectionsFailedAndPruned());
1197 EXPECT_FALSE(turn_port_->HasRequests());
Honghai Zhangf67c5482015-12-11 15:16:54 -08001198}
1199
honghaiz9dfed792016-01-29 13:22:31 -08001200// Test that TurnPort will not handle any incoming packets once it has been
1201// closed.
1202TEST_F(TurnPortTest, TestStopProcessingPacketsAfterClosed) {
1203 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001204 PrepareTurnAndUdpPorts(PROTO_UDP);
honghaiz9dfed792016-01-29 13:22:31 -08001205 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1206 Port::ORIGIN_MESSAGE);
1207 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1208 Port::ORIGIN_MESSAGE);
1209 ASSERT_TRUE(conn1 != NULL);
1210 ASSERT_TRUE(conn2 != NULL);
1211 // Make sure conn2 is writable.
1212 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001213 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE, conn2->write_state(),
1214 kSimulatedRtt * 2, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001215
1216 turn_port_->Close();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001217 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001218 turn_unknown_address_ = false;
1219 conn2->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001220 SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
honghaiz9dfed792016-01-29 13:22:31 -08001221 // Since the turn port does not handle packets any more, it should not
1222 // SignalUnknownAddress.
1223 EXPECT_FALSE(turn_unknown_address_);
1224}
1225
honghaizb19eba32015-08-03 10:23:31 -07001226// Test that CreateConnection will return null if port becomes disconnected.
1227TEST_F(TurnPortTest, TestCreateConnectionWhenSocketClosed) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001228 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001229 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001230 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaizb19eba32015-08-03 10:23:31 -07001231 // Create a connection.
1232 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1233 Port::ORIGIN_MESSAGE);
1234 ASSERT_TRUE(conn1 != NULL);
1235
1236 // Close the socket and create a connection again.
1237 turn_port_->OnSocketClose(turn_port_->socket(), 1);
1238 conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1239 Port::ORIGIN_MESSAGE);
1240 ASSERT_TRUE(conn1 == NULL);
1241}
1242
honghaiz079a7a12016-06-22 16:26:29 -07001243// Tests that when a TCP socket is closed, the respective TURN connection will
1244// be destroyed.
1245TEST_F(TurnPortTest, TestSocketCloseWillDestroyConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001246 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001247 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001248 PrepareTurnAndUdpPorts(PROTO_TCP);
honghaiz079a7a12016-06-22 16:26:29 -07001249 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1250 Port::ORIGIN_MESSAGE);
1251 EXPECT_NE(nullptr, conn);
1252 EXPECT_TRUE(!turn_port_->connections().empty());
1253 turn_port_->socket()->SignalClose(turn_port_->socket(), 1);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001254 EXPECT_TRUE_SIMULATED_WAIT(turn_port_->connections().empty(),
1255 kConnectionDestructionDelay, fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001256}
1257
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001258// Test try-alternate-server feature.
1259TEST_F(TurnPortTest, TestTurnAlternateServerUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001260 TestTurnAlternateServer(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001261}
1262
1263TEST_F(TurnPortTest, TestTurnAlternateServerTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001264 TestTurnAlternateServer(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001265}
1266
Steve Anton786de702017-08-17 15:15:46 -07001267TEST_F(TurnPortTest, TestTurnAlternateServerTLS) {
1268 TestTurnAlternateServer(PROTO_TLS);
1269}
1270
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001271// Test that we fail when we redirect to an address different from
1272// current IP family.
1273TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6UDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001274 TestTurnAlternateServerV4toV6(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001275}
1276
1277TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001278 TestTurnAlternateServerV4toV6(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001279}
1280
Steve Anton786de702017-08-17 15:15:46 -07001281TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TLS) {
1282 TestTurnAlternateServerV4toV6(PROTO_TLS);
1283}
1284
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001285// Test try-alternate-server catches the case of pingpong.
1286TEST_F(TurnPortTest, TestTurnAlternateServerPingPongUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001287 TestTurnAlternateServerPingPong(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001288}
1289
1290TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001291 TestTurnAlternateServerPingPong(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001292}
1293
Steve Anton786de702017-08-17 15:15:46 -07001294TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTLS) {
1295 TestTurnAlternateServerPingPong(PROTO_TLS);
1296}
1297
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001298// Test try-alternate-server catch the case of repeated server.
1299TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionUDP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001300 TestTurnAlternateServerDetectRepetition(PROTO_UDP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001301}
1302
1303TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTCP) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001304 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +00001305}
1306
Steve Anton786de702017-08-17 15:15:46 -07001307TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTLS) {
1308 TestTurnAlternateServerDetectRepetition(PROTO_TCP);
1309}
1310
deadbeeffb70b452016-10-24 13:15:59 -07001311// Test catching the case of a redirect to loopback.
1312TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv4) {
1313 TestTurnAlternateServerLoopback(PROTO_UDP, false);
1314}
1315
1316TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv6) {
1317 TestTurnAlternateServerLoopback(PROTO_UDP, true);
1318}
1319
1320TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv4) {
1321 TestTurnAlternateServerLoopback(PROTO_TCP, false);
1322}
1323
1324TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv6) {
1325 TestTurnAlternateServerLoopback(PROTO_TCP, true);
1326}
1327
Steve Anton786de702017-08-17 15:15:46 -07001328TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv4) {
1329 TestTurnAlternateServerLoopback(PROTO_TLS, false);
1330}
1331
1332TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv6) {
1333 TestTurnAlternateServerLoopback(PROTO_TLS, true);
1334}
1335
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001336// Do a TURN allocation and try to send a packet to it from the outside.
1337// The packet should be dropped. Then, try to send a packet from TURN to the
1338// outside. It should reach its destination. Finally, try again from the
1339// outside. It should now work as well.
1340TEST_F(TurnPortTest, TestTurnConnection) {
1341 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001342 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001343}
1344
1345// Similar to above, except that this test will use the shared socket.
1346TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
1347 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001348 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001349}
1350
1351// Test that we can establish a TCP connection with TURN server.
1352TEST_F(TurnPortTest, TestTurnTcpConnection) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001353 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001354 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001355 TestTurnConnection(PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001356}
1357
Steve Anton786de702017-08-17 15:15:46 -07001358// Test that we can establish a TLS connection with TURN server.
1359TEST_F(TurnPortTest, TestTurnTlsConnection) {
1360 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1361 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1362 TestTurnConnection(PROTO_TLS);
1363}
1364
honghaiz32f39962015-11-17 11:36:31 -08001365// Test that if a connection on a TURN port is destroyed, the TURN port can
1366// still receive ping on that connection as if it is from an unknown address.
1367// If the connection is created again, it will be used to receive ping.
1368TEST_F(TurnPortTest, TestDestroyTurnConnection) {
1369 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1370 TestDestroyTurnConnection();
1371}
1372
1373// Similar to above, except that this test will use the shared socket.
1374TEST_F(TurnPortTest, TestDestroyTurnConnectionUsingSharedSocket) {
1375 CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1376 TestDestroyTurnConnection();
1377}
1378
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001379// Run TurnConnectionTest with one-time-use nonce feature.
1380// Here server will send a 438 STALE_NONCE error message for
1381// every TURN transaction.
1382TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
1383 turn_server_.set_enable_otu_nonce(true);
1384 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001385 TestTurnConnection(PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001386}
1387
Honghai Zhang85975432015-11-12 11:07:12 -08001388// Test that CreatePermissionRequest will be scheduled after the success
Honghai Zhangf67c5482015-12-11 15:16:54 -08001389// of the first create permission request and the request will get an
1390// ErrorResponse if the ufrag and pwd are incorrect.
Honghai Zhang85975432015-11-12 11:07:12 -08001391TEST_F(TurnPortTest, TestRefreshCreatePermissionRequest) {
1392 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001393 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhang85975432015-11-12 11:07:12 -08001394
1395 Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1396 Port::ORIGIN_MESSAGE);
1397 ASSERT_TRUE(conn != NULL);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001398 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1399 fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001400 turn_create_permission_success_ = false;
1401 // A create-permission-request should be pending.
Honghai Zhangf67c5482015-12-11 15:16:54 -08001402 // After the next create-permission-response is received, it will schedule
1403 // another request with bad_ufrag and bad_pwd.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001404 RelayCredentials bad_credentials("bad_user", "bad_pwd");
Honghai Zhangf67c5482015-12-11 15:16:54 -08001405 turn_port_->set_credentials(bad_credentials);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001406 turn_port_->FlushRequests(kAllRequests);
1407 EXPECT_TRUE_SIMULATED_WAIT(turn_create_permission_success_, kSimulatedRtt,
1408 fake_clock_);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001409 // Flush the requests again; the create-permission-request will fail.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001410 turn_port_->FlushRequests(kAllRequests);
1411 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1412 fake_clock_);
1413 EXPECT_TRUE(CheckConnectionFailedAndPruned(conn));
Honghai Zhangf67c5482015-12-11 15:16:54 -08001414}
1415
1416TEST_F(TurnPortTest, TestChannelBindGetErrorResponse) {
1417 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001418 PrepareTurnAndUdpPorts(PROTO_UDP);
Honghai Zhangf67c5482015-12-11 15:16:54 -08001419 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1420 Port::ORIGIN_MESSAGE);
1421 ASSERT_TRUE(conn1 != nullptr);
1422 Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
1423 Port::ORIGIN_MESSAGE);
Honghai Zhang3d77deb2016-06-22 15:22:22 -07001424
honghaiz079a7a12016-06-22 16:26:29 -07001425 ASSERT_TRUE(conn2 != nullptr);
1426 conn1->Ping(0);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001427 EXPECT_TRUE_SIMULATED_WAIT(conn1->writable(), kSimulatedRtt * 2, fake_clock_);
1428 // TODO(deadbeef): SetEntryChannelId should not be a public method.
1429 // Instead we should set an option on the fake TURN server to force it to
1430 // send a channel bind errors.
1431 ASSERT_TRUE(
1432 turn_port_->SetEntryChannelId(udp_port_->Candidates()[0].address(), -1));
honghaiz079a7a12016-06-22 16:26:29 -07001433
1434 std::string data = "ABC";
1435 conn1->Send(data.data(), data.length(), options);
1436
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001437 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn1),
1438 kSimulatedRtt, fake_clock_);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001439 // Verify that packets are allowed to be sent after a bind request error.
1440 // They'll just use a send indication instead.
honghaiz079a7a12016-06-22 16:26:29 -07001441 conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
1442 &TurnPortTest::OnUdpReadPacket);
1443 conn1->Send(data.data(), data.length(), options);
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07001444 EXPECT_TRUE_SIMULATED_WAIT(!udp_packets_.empty(), kSimulatedRtt, fake_clock_);
Honghai Zhang85975432015-11-12 11:07:12 -08001445}
1446
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001447// Do a TURN allocation, establish a UDP connection, and send some data.
1448TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
1449 // Create ports and prepare addresses.
1450 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001451 TestTurnSendData(PROTO_UDP);
1452 EXPECT_EQ(UDP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001453}
1454
1455// Do a TURN allocation, establish a TCP connection, and send some data.
1456TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001457 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001458 // Create ports and prepare addresses.
1459 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001460 TestTurnSendData(PROTO_TCP);
1461 EXPECT_EQ(TCP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001462}
1463
Steve Anton786de702017-08-17 15:15:46 -07001464// Do a TURN allocation, establish a TLS connection, and send some data.
1465TEST_F(TurnPortTest, TestTurnSendDataTurnTlsToUdp) {
1466 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1467 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1468 TestTurnSendData(PROTO_TLS);
1469 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1470}
1471
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001472// Test TURN fails to make a connection from IPv6 address to a server which has
1473// IPv4 address.
1474TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001475 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001476 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1477 kTurnUdpProtoAddr);
1478 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001479 ASSERT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001480 EXPECT_TRUE(turn_port_->Candidates().empty());
1481}
1482
1483// Test TURN make a connection from IPv6 address to a server which has
1484// IPv6 intenal address. But in this test external address is a IPv4 address,
1485// hence allocated address will be a IPv4 address.
1486TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001487 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001488 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1489 kTurnUdpIPv6ProtoAddr);
1490 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001491 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001492 ASSERT_EQ(1U, turn_port_->Candidates().size());
1493 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
1494 turn_port_->Candidates()[0].address().ipaddr());
1495 EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
1496}
1497
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001498// Tests that the local and remote candidate address families should match when
1499// a connection is created. Specifically, if a TURN port has an IPv6 address,
1500// its local candidate will still be an IPv4 address and it can only create
1501// connections with IPv4 remote candidates.
1502TEST_F(TurnPortTest, TestCandidateAddressFamilyMatch) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001503 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001504
1505 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
1506 kTurnUdpIPv6ProtoAddr);
1507 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001508 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001509 ASSERT_EQ(1U, turn_port_->Candidates().size());
1510
1511 // Create an IPv4 candidate. It will match the TURN candidate.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001512 Candidate remote_candidate(ICE_CANDIDATE_COMPONENT_RTP, "udp", kLocalAddr2, 0,
1513 "", "", "local", 0, kCandidateFoundation);
Honghai Zhangf4ae6dc2016-06-22 22:34:58 -07001514 remote_candidate.set_address(kLocalAddr2);
1515 Connection* conn =
1516 turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1517 EXPECT_NE(nullptr, conn);
1518
1519 // Set the candidate address family to IPv6. It won't match the TURN
1520 // candidate.
1521 remote_candidate.set_address(kLocalIPv6Addr2);
1522 conn = turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
1523 EXPECT_EQ(nullptr, conn);
1524}
1525
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001526TEST_F(TurnPortTest, TestOriginHeader) {
1527 CreateTurnPortWithOrigin(kLocalAddr1, kTurnUsername, kTurnPassword,
1528 kTurnUdpProtoAddr, kTestOrigin);
1529 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001530 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +00001531 ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
1532 SocketAddress local_address = turn_port_->GetLocalAddress();
1533 ASSERT_TRUE(turn_server_.FindAllocation(local_address) != NULL);
1534 EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
1535}
1536
deadbeef376e1232015-11-25 09:00:08 -08001537// Test that a CreatePermission failure will result in the connection being
honghaiz079a7a12016-06-22 16:26:29 -07001538// pruned and failed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001539TEST_F(TurnPortTest, TestConnectionFailedAndPrunedOnCreatePermissionFailure) {
1540 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
deadbeef376e1232015-11-25 09:00:08 -08001541 turn_server_.server()->set_reject_private_addresses(true);
1542 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1543 turn_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001544 EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001545
1546 CreateUdpPort(SocketAddress("10.0.0.10", 0));
1547 udp_port_->PrepareAddress();
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001548 EXPECT_TRUE_SIMULATED_WAIT(udp_ready_, kSimulatedRtt, fake_clock_);
deadbeef376e1232015-11-25 09:00:08 -08001549 // Create a connection.
1550 TestConnectionWrapper conn(turn_port_->CreateConnection(
1551 udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE));
honghaiz079a7a12016-06-22 16:26:29 -07001552 EXPECT_TRUE(conn.connection() != nullptr);
deadbeef376e1232015-11-25 09:00:08 -08001553
honghaiz079a7a12016-06-22 16:26:29 -07001554 // Asynchronously, CreatePermission request should be sent and fail, which
1555 // will make the connection pruned and failed.
1556 EXPECT_TRUE_SIMULATED_WAIT(CheckConnectionFailedAndPruned(conn.connection()),
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001557 kSimulatedRtt, fake_clock_);
1558 EXPECT_TRUE_SIMULATED_WAIT(!turn_create_permission_success_, kSimulatedRtt,
1559 fake_clock_);
honghaiz079a7a12016-06-22 16:26:29 -07001560 // Check that the connection is not deleted asynchronously.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001561 SIMULATED_WAIT(conn.connection() == nullptr, kConnectionDestructionDelay,
1562 fake_clock_);
1563 EXPECT_NE(nullptr, conn.connection());
deadbeef376e1232015-11-25 09:00:08 -08001564}
1565
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001566// Test that a TURN allocation is released when the port is closed.
1567TEST_F(TurnPortTest, TestTurnReleaseAllocation) {
1568 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001569 TestTurnReleaseAllocation(PROTO_UDP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001570}
1571
1572// Test that a TURN TCP allocation is released when the port is closed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001573TEST_F(TurnPortTest, TestTurnTCPReleaseAllocation) {
1574 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001575 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
Steve Antoned447ae2017-08-17 14:31:51 -07001576 TestTurnReleaseAllocation(PROTO_TCP);
pthatcher@webrtc.orgfe672e32015-01-17 00:58:15 +00001577}
1578
Steve Anton786de702017-08-17 15:15:46 -07001579TEST_F(TurnPortTest, TestTurnTLSReleaseAllocation) {
1580 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1581 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1582 TestTurnReleaseAllocation(PROTO_TLS);
1583}
1584
Jonas Orelandc99dc312018-03-28 08:00:50 +02001585TEST_F(TurnPortTest, TestTurnUDPGracefulReleaseAllocation) {
1586 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_UDP);
1587 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1588 TestTurnGracefulReleaseAllocation(PROTO_UDP);
1589}
1590
1591TEST_F(TurnPortTest, TestTurnTCPGracefulReleaseAllocation) {
1592 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
1593 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
1594 TestTurnGracefulReleaseAllocation(PROTO_TCP);
1595}
1596
1597TEST_F(TurnPortTest, TestTurnTLSGracefulReleaseAllocation) {
1598 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1599 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1600 TestTurnGracefulReleaseAllocation(PROTO_TLS);
1601}
1602
Taylor Brandstetterd65ae4a2017-10-08 11:46:15 -07001603// Test that nothing bad happens if we try to create a connection to the same
1604// remote address twice. Previously there was a bug that caused this to hit a
1605// DCHECK.
1606TEST_F(TurnPortTest, CanCreateTwoConnectionsToSameAddress) {
1607 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
1608 PrepareTurnAndUdpPorts(PROTO_UDP);
1609 Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1610 Port::ORIGIN_MESSAGE);
1611 Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
1612 Port::ORIGIN_MESSAGE);
1613 EXPECT_NE(conn1, conn2);
1614}
1615
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001616// This test verifies any FD's are not leaked after TurnPort is destroyed.
1617// https://code.google.com/p/webrtc/issues/detail?id=2651
1618#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001619
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001620TEST_F(TurnPortTest, TestResolverShutdown) {
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001621 turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001622 int last_fd_count = GetFDCount();
1623 // Need to supply unresolved address to kick off resolver.
1624 CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001625 ProtocolAddress(rtc::SocketAddress("www.google.invalid", 3478),
1626 PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001627 turn_port_->PrepareAddress();
Taylor Brandstettere86e15b2015-12-29 12:51:12 -08001628 ASSERT_TRUE_WAIT(turn_error_, kResolverTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001629 EXPECT_TRUE(turn_port_->Candidates().empty());
1630 turn_port_.reset();
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001631 rtc::Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TESTFINISH);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001632 // Waiting for above message to be processed.
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001633 ASSERT_TRUE_SIMULATED_WAIT(test_finish_, 1, fake_clock_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001634 EXPECT_EQ(last_fd_count, GetFDCount());
1635}
1636#endif
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001637
Yves Gerey665174f2018-06-19 15:03:05 +02001638class MessageObserver : public StunMessageObserver {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001639 public:
Yves Gerey665174f2018-06-19 15:03:05 +02001640 MessageObserver(unsigned int* message_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001641 unsigned int* channel_data_counter,
Yves Gerey665174f2018-06-19 15:03:05 +02001642 unsigned int* attr_counter)
Jonas Orelandbdcee282017-10-10 14:01:40 +02001643 : message_counter_(message_counter),
1644 channel_data_counter_(channel_data_counter),
1645 attr_counter_(attr_counter) {}
1646 virtual ~MessageObserver() {}
Steve Anton6c38cc72017-11-29 10:25:58 -08001647 void ReceivedMessage(const TurnMessage* msg) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001648 if (message_counter_ != nullptr) {
1649 (*message_counter_)++;
1650 }
1651 // Implementation defined attributes are returned as ByteString
Yves Gerey665174f2018-06-19 15:03:05 +02001652 const StunByteStringAttribute* attr =
1653 msg->GetByteString(TestTurnCustomizer::STUN_ATTR_COUNTER);
Jonas Orelandbdcee282017-10-10 14:01:40 +02001654 if (attr != nullptr && attr_counter_ != nullptr) {
1655 rtc::ByteBufferReader buf(attr->bytes(), attr->length());
1656 unsigned int val = ~0u;
1657 buf.ReadUInt32(&val);
1658 (*attr_counter_)++;
1659 }
1660 }
1661
Steve Anton6c38cc72017-11-29 10:25:58 -08001662 void ReceivedChannelData(const char* data, size_t size) override {
Jonas Orelandbdcee282017-10-10 14:01:40 +02001663 if (channel_data_counter_ != nullptr) {
1664 (*channel_data_counter_)++;
1665 }
1666 }
1667
1668 // Number of TurnMessages observed.
1669 unsigned int* message_counter_ = nullptr;
1670
1671 // Number of channel data observed.
1672 unsigned int* channel_data_counter_ = nullptr;
1673
1674 // Number of TurnMessages that had STUN_ATTR_COUNTER.
1675 unsigned int* attr_counter_ = nullptr;
1676};
1677
1678// Do a TURN allocation, establish a TLS connection, and send some data.
1679// Add customizer and check that it get called.
1680TEST_F(TurnPortTest, TestTurnCustomizerCount) {
1681 unsigned int observer_message_counter = 0;
1682 unsigned int observer_channel_data_counter = 0;
1683 unsigned int observer_attr_counter = 0;
1684 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1685 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001686 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001687 &observer_attr_counter));
1688
1689 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1690 turn_customizer_.reset(customizer);
1691 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1692
1693 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1694 TestTurnSendData(PROTO_TLS);
1695 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1696
1697 // There should have been at least turn_packets_.size() calls to |customizer|.
1698 EXPECT_GE(customizer->modify_cnt_ + customizer->allow_channel_data_cnt_,
1699 turn_packets_.size());
1700
1701 // Some channel data should be received.
1702 EXPECT_GE(observer_channel_data_counter, 0u);
1703
1704 // Need to release TURN port before the customizer.
1705 turn_port_.reset(nullptr);
1706}
1707
1708// Do a TURN allocation, establish a TLS connection, and send some data.
1709// Add customizer and check that it can can prevent usage of channel data.
1710TEST_F(TurnPortTest, TestTurnCustomizerDisallowChannelData) {
1711 unsigned int observer_message_counter = 0;
1712 unsigned int observer_channel_data_counter = 0;
1713 unsigned int observer_attr_counter = 0;
1714 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1715 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001716 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001717 &observer_attr_counter));
1718 customizer->allow_channel_data_ = false;
1719 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1720 turn_customizer_.reset(customizer);
1721 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1722
1723 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1724 TestTurnSendData(PROTO_TLS);
1725 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1726
1727 // There should have been at least turn_packets_.size() calls to |customizer|.
1728 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1729
1730 // No channel data should be received.
1731 EXPECT_EQ(observer_channel_data_counter, 0u);
1732
1733 // Need to release TURN port before the customizer.
1734 turn_port_.reset(nullptr);
1735}
1736
1737// Do a TURN allocation, establish a TLS connection, and send some data.
1738// Add customizer and check that it can add attribute to messages.
1739TEST_F(TurnPortTest, TestTurnCustomizerAddAttribute) {
1740 unsigned int observer_message_counter = 0;
1741 unsigned int observer_channel_data_counter = 0;
1742 unsigned int observer_attr_counter = 0;
1743 TestTurnCustomizer* customizer = new TestTurnCustomizer();
1744 std::unique_ptr<MessageObserver> validator(new MessageObserver(
Yves Gerey665174f2018-06-19 15:03:05 +02001745 &observer_message_counter, &observer_channel_data_counter,
Jonas Orelandbdcee282017-10-10 14:01:40 +02001746 &observer_attr_counter));
1747 customizer->allow_channel_data_ = false;
1748 customizer->add_counter_ = true;
1749 turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
1750 turn_customizer_.reset(customizer);
1751 turn_server_.server()->SetStunMessageObserver(std::move(validator));
1752
1753 CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
1754 TestTurnSendData(PROTO_TLS);
1755 EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
1756
1757 // There should have been at least turn_packets_.size() calls to |customizer|.
1758 EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());
1759
1760 // Everything will be sent as messages since channel data is disallowed.
1761 EXPECT_GE(customizer->modify_cnt_, observer_message_counter);
1762
1763 // All messages should have attribute.
1764 EXPECT_EQ(observer_message_counter, observer_attr_counter);
1765
1766 // At least allow_channel_data_cnt_ messages should have been sent.
1767 EXPECT_GE(customizer->modify_cnt_, customizer->allow_channel_data_cnt_);
1768 EXPECT_GE(customizer->allow_channel_data_cnt_, 0u);
1769
1770 // No channel data should be received.
1771 EXPECT_EQ(observer_channel_data_counter, 0u);
1772
1773 // Need to release TURN port before the customizer.
1774 turn_port_.reset(nullptr);
1775}
1776
Taylor Brandstetter716d07a2016-06-27 14:07:41 -07001777} // namespace cricket