blob: f0a2117ef4b9d84a36301624f14a21f07cd52f0f [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2009 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "p2p/base/stun_port.h"
12
kwiberg3ec46792016-04-27 07:22:53 -070013#include <memory>
14
Steve Anton10542f22019-01-11 09:11:00 -080015#include "p2p/base/basic_packet_socket_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "p2p/base/test_stun_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/gunit.h"
18#include "rtc_base/helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/socket_address.h"
20#include "rtc_base/ssl_adapter.h"
21#include "rtc_base/virtual_socket_server.h"
Tim Haloun6ca98362018-09-17 17:06:08 -070022#include "test/gmock.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023
24using cricket::ServerAddresses;
25using rtc::SocketAddress;
Tim Haloun6ca98362018-09-17 17:06:08 -070026using ::testing::_;
27using ::testing::Return;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000028
29static const SocketAddress kLocalAddr("127.0.0.1", 0);
30static const SocketAddress kStunAddr1("127.0.0.1", 5000);
31static const SocketAddress kStunAddr2("127.0.0.1", 4000);
Honghai Zhang351d77b2016-05-20 15:08:29 -070032static const SocketAddress kStunAddr3("127.0.0.1", 3000);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000033static const SocketAddress kBadAddr("0.0.0.1", 5000);
34static const SocketAddress kStunHostnameAddr("localhost", 5000);
35static const SocketAddress kBadHostnameAddr("not-a-real-hostname", 5000);
pthatcher94a2f212017-02-08 14:42:22 -080036// STUN timeout (with all retries) is cricket::STUN_TOTAL_TIMEOUT.
Taylor Brandstetter8fcf4142016-05-23 12:49:30 -070037// Add some margin of error for slow bots.
pthatcher94a2f212017-02-08 14:42:22 -080038static const int kTimeoutMs = cricket::STUN_TOTAL_TIMEOUT;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039// stun prio = 100 << 24 | 30 (IPV4) << 8 | 256 - 0
Peter Boström0c4e06b2015-10-07 12:23:21 +020040static const uint32_t kStunCandidatePriority = 1677729535;
honghaize2af9ef2016-03-03 08:27:47 -080041static const int kInfiniteLifetime = -1;
42static const int kHighCostPortKeepaliveLifetimeMs = 2 * 60 * 1000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000043
44// Tests connecting a StunPort to a fake STUN server (cricket::StunServer)
Mirko Bonadei6a489f22019-04-09 15:11:12 +020045class StunPortTestBase : public ::testing::Test, public sigslot::has_slots<> {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000046 public:
pthatcher1749bc32017-02-08 13:18:00 -080047 StunPortTestBase()
deadbeef98e186c2017-05-16 18:00:06 -070048 : ss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -070049 thread_(ss_.get()),
deadbeef5c3c1042017-08-04 15:01:57 -070050 network_("unittest", "unittest", kLocalAddr.ipaddr(), 32),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051 socket_factory_(rtc::Thread::Current()),
honghaize2af9ef2016-03-03 08:27:47 -080052 stun_server_1_(cricket::TestStunServer::Create(rtc::Thread::Current(),
53 kStunAddr1)),
54 stun_server_2_(cricket::TestStunServer::Create(rtc::Thread::Current(),
55 kStunAddr2)),
56 done_(false),
57 error_(false),
pthatcher1749bc32017-02-08 13:18:00 -080058 stun_keepalive_delay_(1),
deadbeef5c3c1042017-08-04 15:01:57 -070059 stun_keepalive_lifetime_(-1) {
60 network_.AddIP(kLocalAddr.ipaddr());
61 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000062
honghaize2af9ef2016-03-03 08:27:47 -080063 cricket::UDPPort* port() const { return stun_port_.get(); }
Tim Haloun6ca98362018-09-17 17:06:08 -070064 rtc::AsyncPacketSocket* socket() const { return socket_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065 bool done() const { return done_; }
66 bool error() const { return error_; }
67
honghaize2af9ef2016-03-03 08:27:47 -080068 void SetNetworkType(rtc::AdapterType adapter_type) {
69 network_.set_type(adapter_type);
70 }
71
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072 void CreateStunPort(const rtc::SocketAddress& server_addr) {
73 ServerAddresses stun_servers;
74 stun_servers.insert(server_addr);
75 CreateStunPort(stun_servers);
76 }
77
78 void CreateStunPort(const ServerAddresses& stun_servers) {
Steve Antona8f1e562018-10-10 11:29:44 -070079 stun_port_ = cricket::StunPort::Create(
deadbeef5c3c1042017-08-04 15:01:57 -070080 rtc::Thread::Current(), &socket_factory_, &network_, 0, 0,
81 rtc::CreateRandomString(16), rtc::CreateRandomString(22), stun_servers,
Steve Antona8f1e562018-10-10 11:29:44 -070082 std::string(), absl::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083 stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
honghaize2af9ef2016-03-03 08:27:47 -080084 // If |stun_keepalive_lifetime_| is negative, let the stun port
85 // choose its lifetime from the network type.
86 if (stun_keepalive_lifetime_ >= 0) {
87 stun_port_->set_stun_keepalive_lifetime(stun_keepalive_lifetime_);
88 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000089 stun_port_->SignalPortComplete.connect(this,
pthatcher1749bc32017-02-08 13:18:00 -080090 &StunPortTestBase::OnPortComplete);
91 stun_port_->SignalPortError.connect(this, &StunPortTestBase::OnPortError);
Eldar Relloda13ea22019-06-01 12:23:43 +030092 stun_port_->SignalCandidateError.connect(
93 this, &StunPortTestBase::OnCandidateError);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000094 }
95
Tim Haloun6ca98362018-09-17 17:06:08 -070096 void CreateSharedUdpPort(const rtc::SocketAddress& server_addr,
97 rtc::AsyncPacketSocket* socket) {
98 if (socket) {
99 socket_.reset(socket);
100 } else {
101 socket_.reset(socket_factory_.CreateUdpSocket(
102 rtc::SocketAddress(kLocalAddr.ipaddr(), 0), 0, 0));
103 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104 ASSERT_TRUE(socket_ != NULL);
pthatcher1749bc32017-02-08 13:18:00 -0800105 socket_->SignalReadPacket.connect(this, &StunPortTestBase::OnReadPacket);
Steve Antona8f1e562018-10-10 11:29:44 -0700106 stun_port_ = cricket::UDPPort::Create(
Qingsi Wang4ff54432018-03-01 18:25:20 -0800107 rtc::Thread::Current(), &socket_factory_, &network_, socket_.get(),
108 rtc::CreateRandomString(16), rtc::CreateRandomString(22), std::string(),
Steve Antona8f1e562018-10-10 11:29:44 -0700109 false, absl::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000110 ASSERT_TRUE(stun_port_ != NULL);
111 ServerAddresses stun_servers;
112 stun_servers.insert(server_addr);
113 stun_port_->set_server_addresses(stun_servers);
114 stun_port_->SignalPortComplete.connect(this,
pthatcher1749bc32017-02-08 13:18:00 -0800115 &StunPortTestBase::OnPortComplete);
116 stun_port_->SignalPortError.connect(this, &StunPortTestBase::OnPortError);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117 }
118
Yves Gerey665174f2018-06-19 15:03:05 +0200119 void PrepareAddress() { stun_port_->PrepareAddress(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000120
Yves Gerey665174f2018-06-19 15:03:05 +0200121 void OnReadPacket(rtc::AsyncPacketSocket* socket,
122 const char* data,
123 size_t size,
124 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100125 const int64_t& /* packet_time_us */) {
Yves Gerey665174f2018-06-19 15:03:05 +0200126 stun_port_->HandleIncomingPacket(socket, data, size, remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100127 /* packet_time_us */ -1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 }
129
130 void SendData(const char* data, size_t len) {
Yves Gerey665174f2018-06-19 15:03:05 +0200131 stun_port_->HandleIncomingPacket(socket_.get(), data, len,
132 rtc::SocketAddress("22.22.22.22", 0),
Niels Möllere6933812018-11-05 13:01:41 +0100133 /* packet_time_us */ -1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134 }
135
136 protected:
Mirko Bonadei71061bc2019-06-04 09:01:51 +0200137 static void SetUpTestSuite() {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 // Ensure the RNG is inited.
139 rtc::InitRandom(NULL, 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000140 }
141
142 void OnPortComplete(cricket::Port* port) {
143 ASSERT_FALSE(done_);
144 done_ = true;
145 error_ = false;
146 }
147 void OnPortError(cricket::Port* port) {
148 done_ = true;
149 error_ = true;
150 }
Eldar Relloda13ea22019-06-01 12:23:43 +0300151 void OnCandidateError(cricket::Port* port,
152 const cricket::IceCandidateErrorEvent& event) {
153 error_event_ = event;
154 }
Yves Gerey665174f2018-06-19 15:03:05 +0200155 void SetKeepaliveDelay(int delay) { stun_keepalive_delay_ = delay; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156
honghaize2af9ef2016-03-03 08:27:47 -0800157 void SetKeepaliveLifetime(int lifetime) {
158 stun_keepalive_lifetime_ = lifetime;
159 }
160
Yves Gerey665174f2018-06-19 15:03:05 +0200161 cricket::TestStunServer* stun_server_1() { return stun_server_1_.get(); }
162 cricket::TestStunServer* stun_server_2() { return stun_server_2_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163
164 private:
kwiberg3ec46792016-04-27 07:22:53 -0700165 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700166 rtc::AutoSocketServerThread thread_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000167 rtc::Network network_;
168 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700169 std::unique_ptr<cricket::UDPPort> stun_port_;
170 std::unique_ptr<cricket::TestStunServer> stun_server_1_;
171 std::unique_ptr<cricket::TestStunServer> stun_server_2_;
172 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000173 bool done_;
174 bool error_;
175 int stun_keepalive_delay_;
honghaize2af9ef2016-03-03 08:27:47 -0800176 int stun_keepalive_lifetime_;
Eldar Relloda13ea22019-06-01 12:23:43 +0300177
178 protected:
179 cricket::IceCandidateErrorEvent error_event_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180};
181
pthatcher1749bc32017-02-08 13:18:00 -0800182class StunPortTestWithRealClock : public StunPortTestBase {};
183
184class FakeClockBase {
185 public:
186 rtc::ScopedFakeClock fake_clock;
187};
188
189class StunPortTest : public FakeClockBase, public StunPortTestBase {};
190
Honghai Zhangd00c0572016-06-28 09:44:47 -0700191// Test that we can create a STUN port.
192TEST_F(StunPortTest, TestCreateStunPort) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 CreateStunPort(kStunAddr1);
194 EXPECT_EQ("stun", port()->Type());
195 EXPECT_EQ(0U, port()->Candidates().size());
196}
197
Honghai Zhangd00c0572016-06-28 09:44:47 -0700198// Test that we can create a UDP port.
199TEST_F(StunPortTest, TestCreateUdpPort) {
Tim Haloun6ca98362018-09-17 17:06:08 -0700200 CreateSharedUdpPort(kStunAddr1, nullptr);
Honghai Zhangd00c0572016-06-28 09:44:47 -0700201 EXPECT_EQ("local", port()->Type());
202 EXPECT_EQ(0U, port()->Candidates().size());
203}
204
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000205// Test that we can get an address from a STUN server.
206TEST_F(StunPortTest, TestPrepareAddress) {
207 CreateStunPort(kStunAddr1);
208 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800209 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000210 ASSERT_EQ(1U, port()->Candidates().size());
211 EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
zhihuang26d99c22017-02-13 12:47:27 -0800212 std::string expected_server_url = "stun:127.0.0.1:5000";
213 EXPECT_EQ(port()->Candidates()[0].url(), expected_server_url);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000214
deadbeef98e186c2017-05-16 18:00:06 -0700215 // TODO(deadbeef): Add IPv6 tests here.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000216}
217
218// Test that we fail properly if we can't get an address.
219TEST_F(StunPortTest, TestPrepareAddressFail) {
220 CreateStunPort(kBadAddr);
221 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800222 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000223 EXPECT_TRUE(error());
224 EXPECT_EQ(0U, port()->Candidates().size());
Eldar Relloda13ea22019-06-01 12:23:43 +0300225 EXPECT_EQ_SIMULATED_WAIT(error_event_.error_code,
226 cricket::SERVER_NOT_REACHABLE_ERROR, kTimeoutMs,
227 fake_clock);
228 ASSERT_NE(error_event_.error_text.find("."), std::string::npos);
229 ASSERT_NE(
230 error_event_.host_candidate.find(kLocalAddr.HostAsSensitiveURIString()),
231 std::string::npos);
232 std::string server_url = "stun:" + kBadAddr.ToString();
233 ASSERT_EQ(error_event_.url, server_url);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000234}
235
236// Test that we can get an address from a STUN server specified by a hostname.
aleloid49d3872017-03-28 03:00:07 -0700237// Crashes on Linux, see webrtc:7416
Alex Loiko2058d522018-11-19 14:51:06 +0100238#if defined(WEBRTC_LINUX) || defined(WEBRTC_WIN)
aleloid49d3872017-03-28 03:00:07 -0700239#define MAYBE_TestPrepareAddressHostname DISABLED_TestPrepareAddressHostname
240#else
241#define MAYBE_TestPrepareAddressHostname TestPrepareAddressHostname
242#endif
243TEST_F(StunPortTest, MAYBE_TestPrepareAddressHostname) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000244 CreateStunPort(kStunHostnameAddr);
245 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800246 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000247 ASSERT_EQ(1U, port()->Candidates().size());
248 EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
249 EXPECT_EQ(kStunCandidatePriority, port()->Candidates()[0].priority());
250}
251
252// Test that we handle hostname lookup failures properly.
pthatcher1749bc32017-02-08 13:18:00 -0800253TEST_F(StunPortTestWithRealClock, TestPrepareAddressHostnameFail) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000254 CreateStunPort(kBadHostnameAddr);
255 PrepareAddress();
256 EXPECT_TRUE_WAIT(done(), kTimeoutMs);
257 EXPECT_TRUE(error());
258 EXPECT_EQ(0U, port()->Candidates().size());
Eldar Relloda13ea22019-06-01 12:23:43 +0300259 EXPECT_EQ_WAIT(error_event_.error_code, cricket::SERVER_NOT_REACHABLE_ERROR,
260 kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261}
262
263// This test verifies keepalive response messages don't result in
264// additional candidate generation.
265TEST_F(StunPortTest, TestKeepAliveResponse) {
266 SetKeepaliveDelay(500); // 500ms of keepalive delay.
deadbeef9a6f4d42017-05-15 19:43:33 -0700267 CreateStunPort(kStunAddr1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000268 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800269 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000270 ASSERT_EQ(1U, port()->Candidates().size());
271 EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
pthatcher1749bc32017-02-08 13:18:00 -0800272 SIMULATED_WAIT(false, 1000, fake_clock);
273 EXPECT_EQ(1U, port()->Candidates().size());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000274}
275
276// Test that a local candidate can be generated using a shared socket.
277TEST_F(StunPortTest, TestSharedSocketPrepareAddress) {
Tim Haloun6ca98362018-09-17 17:06:08 -0700278 CreateSharedUdpPort(kStunAddr1, nullptr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800280 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000281 ASSERT_EQ(1U, port()->Candidates().size());
282 EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
283}
284
285// Test that we still a get a local candidate with invalid stun server hostname.
286// Also verifing that UDPPort can receive packets when stun address can't be
287// resolved.
pthatcher1749bc32017-02-08 13:18:00 -0800288TEST_F(StunPortTestWithRealClock,
289 TestSharedSocketPrepareAddressInvalidHostname) {
Tim Haloun6ca98362018-09-17 17:06:08 -0700290 CreateSharedUdpPort(kBadHostnameAddr, nullptr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000291 PrepareAddress();
292 EXPECT_TRUE_WAIT(done(), kTimeoutMs);
293 ASSERT_EQ(1U, port()->Candidates().size());
294 EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
295
296 // Send data to port after it's ready. This is to make sure, UDP port can
297 // handle data with unresolved stun server address.
298 std::string data = "some random data, sending to cricket::Port.";
299 SendData(data.c_str(), data.length());
300 // No crash is success.
301}
302
303// Test that the same address is added only once if two STUN servers are in use.
304TEST_F(StunPortTest, TestNoDuplicatedAddressWithTwoStunServers) {
305 ServerAddresses stun_servers;
306 stun_servers.insert(kStunAddr1);
307 stun_servers.insert(kStunAddr2);
308 CreateStunPort(stun_servers);
309 EXPECT_EQ("stun", port()->Type());
310 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800311 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000312 EXPECT_EQ(1U, port()->Candidates().size());
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700313 EXPECT_EQ(port()->Candidates()[0].relay_protocol(), "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000314}
315
316// Test that candidates can be allocated for multiple STUN servers, one of which
317// is not reachable.
318TEST_F(StunPortTest, TestMultipleStunServersWithBadServer) {
319 ServerAddresses stun_servers;
320 stun_servers.insert(kStunAddr1);
321 stun_servers.insert(kBadAddr);
322 CreateStunPort(stun_servers);
323 EXPECT_EQ("stun", port()->Type());
324 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800325 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000326 EXPECT_EQ(1U, port()->Candidates().size());
Eldar Relloda13ea22019-06-01 12:23:43 +0300327 std::string server_url = "stun:" + kBadAddr.ToString();
328 ASSERT_EQ_SIMULATED_WAIT(error_event_.url, server_url, kTimeoutMs,
329 fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330}
331
332// Test that two candidates are allocated if the two STUN servers return
333// different mapped addresses.
334TEST_F(StunPortTest, TestTwoCandidatesWithTwoStunServersAcrossNat) {
335 const SocketAddress kStunMappedAddr1("77.77.77.77", 0);
336 const SocketAddress kStunMappedAddr2("88.77.77.77", 0);
337 stun_server_1()->set_fake_stun_addr(kStunMappedAddr1);
338 stun_server_2()->set_fake_stun_addr(kStunMappedAddr2);
339
340 ServerAddresses stun_servers;
341 stun_servers.insert(kStunAddr1);
342 stun_servers.insert(kStunAddr2);
343 CreateStunPort(stun_servers);
344 EXPECT_EQ("stun", port()->Type());
345 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800346 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000347 EXPECT_EQ(2U, port()->Candidates().size());
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700348 EXPECT_EQ(port()->Candidates()[0].relay_protocol(), "");
349 EXPECT_EQ(port()->Candidates()[1].relay_protocol(), "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000350}
honghaize2af9ef2016-03-03 08:27:47 -0800351
352// Test that the stun_keepalive_lifetime is set correctly based on the network
Honghai Zhang351d77b2016-05-20 15:08:29 -0700353// type on a STUN port. Also test that it will be updated if the network type
354// changes.
honghaize2af9ef2016-03-03 08:27:47 -0800355TEST_F(StunPortTest, TestStunPortGetStunKeepaliveLifetime) {
Honghai Zhang351d77b2016-05-20 15:08:29 -0700356 // Lifetime for the default (unknown) network type is |kInfiniteLifetime|.
honghaize2af9ef2016-03-03 08:27:47 -0800357 CreateStunPort(kStunAddr1);
358 EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
honghaize2af9ef2016-03-03 08:27:47 -0800359 // Lifetime for the cellular network is |kHighCostPortKeepaliveLifetimeMs|
360 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
honghaize2af9ef2016-03-03 08:27:47 -0800361 EXPECT_EQ(kHighCostPortKeepaliveLifetimeMs,
362 port()->stun_keepalive_lifetime());
Honghai Zhang351d77b2016-05-20 15:08:29 -0700363
364 // Lifetime for the wifi network is |kInfiniteLifetime|.
365 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
366 CreateStunPort(kStunAddr2);
367 EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
honghaize2af9ef2016-03-03 08:27:47 -0800368}
369
370// Test that the stun_keepalive_lifetime is set correctly based on the network
Honghai Zhang351d77b2016-05-20 15:08:29 -0700371// type on a shared STUN port (UDPPort). Also test that it will be updated
372// if the network type changes.
honghaize2af9ef2016-03-03 08:27:47 -0800373TEST_F(StunPortTest, TestUdpPortGetStunKeepaliveLifetime) {
Honghai Zhang351d77b2016-05-20 15:08:29 -0700374 // Lifetime for the default (unknown) network type is |kInfiniteLifetime|.
Tim Haloun6ca98362018-09-17 17:06:08 -0700375 CreateSharedUdpPort(kStunAddr1, nullptr);
honghaize2af9ef2016-03-03 08:27:47 -0800376 EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
Honghai Zhang351d77b2016-05-20 15:08:29 -0700377 // Lifetime for the cellular network is |kHighCostPortKeepaliveLifetimeMs|.
honghaize2af9ef2016-03-03 08:27:47 -0800378 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
honghaize2af9ef2016-03-03 08:27:47 -0800379 EXPECT_EQ(kHighCostPortKeepaliveLifetimeMs,
380 port()->stun_keepalive_lifetime());
Honghai Zhang351d77b2016-05-20 15:08:29 -0700381
382 // Lifetime for the wifi network type is |kInfiniteLifetime|.
383 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
Tim Haloun6ca98362018-09-17 17:06:08 -0700384 CreateSharedUdpPort(kStunAddr2, nullptr);
Honghai Zhang351d77b2016-05-20 15:08:29 -0700385 EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
honghaize2af9ef2016-03-03 08:27:47 -0800386}
387
388// Test that STUN binding requests will be stopped shortly if the keep-alive
389// lifetime is short.
390TEST_F(StunPortTest, TestStunBindingRequestShortLifetime) {
391 SetKeepaliveDelay(101);
392 SetKeepaliveLifetime(100);
393 CreateStunPort(kStunAddr1);
394 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800395 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
396 EXPECT_TRUE_SIMULATED_WAIT(
397 !port()->HasPendingRequest(cricket::STUN_BINDING_REQUEST), 2000,
398 fake_clock);
honghaize2af9ef2016-03-03 08:27:47 -0800399}
400
401// Test that by default, the STUN binding requests will last for a long time.
402TEST_F(StunPortTest, TestStunBindingRequestLongLifetime) {
403 SetKeepaliveDelay(101);
404 CreateStunPort(kStunAddr1);
405 PrepareAddress();
pthatcher1749bc32017-02-08 13:18:00 -0800406 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
407 EXPECT_TRUE_SIMULATED_WAIT(
408 port()->HasPendingRequest(cricket::STUN_BINDING_REQUEST), 1000,
409 fake_clock);
honghaize2af9ef2016-03-03 08:27:47 -0800410}
Tim Haloun6ca98362018-09-17 17:06:08 -0700411
412class MockAsyncPacketSocket : public rtc::AsyncPacketSocket {
413 public:
414 ~MockAsyncPacketSocket() = default;
415
416 MOCK_CONST_METHOD0(GetLocalAddress, SocketAddress());
417 MOCK_CONST_METHOD0(GetRemoteAddress, SocketAddress());
418 MOCK_METHOD3(Send,
419 int(const void* pv,
420 size_t cb,
421 const rtc::PacketOptions& options));
422
423 MOCK_METHOD4(SendTo,
424 int(const void* pv,
425 size_t cb,
426 const SocketAddress& addr,
427 const rtc::PacketOptions& options));
428 MOCK_METHOD0(Close, int());
429 MOCK_CONST_METHOD0(GetState, State());
430 MOCK_METHOD2(GetOption, int(rtc::Socket::Option opt, int* value));
431 MOCK_METHOD2(SetOption, int(rtc::Socket::Option opt, int value));
432 MOCK_CONST_METHOD0(GetError, int());
433 MOCK_METHOD1(SetError, void(int error));
434};
435
436// Test that outbound packets inherit the dscp value assigned to the socket.
437TEST_F(StunPortTest, TestStunPacketsHaveDscpPacketOption) {
438 MockAsyncPacketSocket* socket = new MockAsyncPacketSocket();
439 CreateSharedUdpPort(kStunAddr1, socket);
440 EXPECT_CALL(*socket, GetLocalAddress()).WillRepeatedly(Return(kLocalAddr));
441 EXPECT_CALL(*socket, GetState())
442 .WillRepeatedly(Return(rtc::AsyncPacketSocket::STATE_BOUND));
443 EXPECT_CALL(*socket, SetOption(_, _)).WillRepeatedly(Return(0));
444
445 // If DSCP is not set on the socket, stun packets should have no value.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200446 EXPECT_CALL(*socket,
447 SendTo(_, _, _,
448 ::testing::Field(&rtc::PacketOptions::dscp,
449 ::testing::Eq(rtc::DSCP_NO_CHANGE))))
Tim Haloun6ca98362018-09-17 17:06:08 -0700450 .WillOnce(Return(100));
451 PrepareAddress();
452
453 // Once it is set transport wide, they should inherit that value.
454 port()->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
455 EXPECT_CALL(*socket, SendTo(_, _, _,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200456 ::testing::Field(&rtc::PacketOptions::dscp,
457 ::testing::Eq(rtc::DSCP_AF41))))
Tim Haloun6ca98362018-09-17 17:06:08 -0700458 .WillRepeatedly(Return(100));
459 EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
460}