blob: 17cb9554f7dd0aa8d53b4c76650d76e1d2bf51f4 [file] [log] [blame]
[email protected]7370de6e2012-02-22 08:04:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]38712522011-04-18 23:03:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/tcp_server_socket.h"
6
danakj655b66c2016-04-16 00:51:387#include <memory>
[email protected]e57a7162011-06-15 04:14:238#include <string>
[email protected]7370de6e2012-02-22 08:04:189#include <vector>
[email protected]e57a7162011-06-15 04:14:2310
[email protected]38712522011-04-18 23:03:3211#include "base/compiler_specific.h"
[email protected]7370de6e2012-02-22 08:04:1812#include "base/memory/ref_counted.h"
[email protected]38712522011-04-18 23:03:3213#include "net/base/address_list.h"
[email protected]7370de6e2012-02-22 08:04:1814#include "net/base/io_buffer.h"
martijna2e83bd2016-03-18 13:10:4515#include "net/base/ip_address.h"
[email protected]38712522011-04-18 23:03:3216#include "net/base/ip_endpoint.h"
17#include "net/base/net_errors.h"
[email protected]38712522011-04-18 23:03:3218#include "net/base/test_completion_callback.h"
mikecironef22f9812016-10-04 03:40:1919#include "net/log/net_log_source.h"
[email protected]38712522011-04-18 23:03:3220#include "net/socket/tcp_client_socket.h"
robpercival214763f2016-07-01 23:27:0121#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0122#include "net/test/test_with_scoped_task_environment.h"
Ramin Halavati0a08cc82018-02-06 07:46:3823#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0124#include "testing/gmock/include/gmock/gmock.h"
[email protected]38712522011-04-18 23:03:3225#include "testing/gtest/include/gtest/gtest.h"
26#include "testing/platform_test.h"
27
Sergey Ulanov7cbcbc52017-07-26 18:29:1328using net::test::IsError;
robpercival214763f2016-07-01 23:27:0129using net::test::IsOk;
30
[email protected]38712522011-04-18 23:03:3231namespace net {
32
33namespace {
34const int kListenBacklog = 5;
35
Bence Béky98447b12018-05-08 03:14:0136class TCPServerSocketTest : public PlatformTest,
37 public WithScopedTaskEnvironment {
[email protected]38712522011-04-18 23:03:3238 protected:
Sergey Ulanov7cbcbc52017-07-26 18:29:1339 TCPServerSocketTest() : socket_(nullptr, NetLogSource()) {}
[email protected]38712522011-04-18 23:03:3240
[email protected]03ec25382011-05-27 21:50:2841 void SetUpIPv4() {
martijna2e83bd2016-03-18 13:10:4542 IPEndPoint address(IPAddress::IPv4Localhost(), 0);
robpercival214763f2016-07-01 23:27:0143 ASSERT_THAT(socket_.Listen(address, kListenBacklog), IsOk());
44 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]38712522011-04-18 23:03:3245 }
46
[email protected]03ec25382011-05-27 21:50:2847 void SetUpIPv6(bool* success) {
48 *success = false;
martijna2e83bd2016-03-18 13:10:4549 IPEndPoint address(IPAddress::IPv6Localhost(), 0);
[email protected]03ec25382011-05-27 21:50:2850 if (socket_.Listen(address, kListenBacklog) != 0) {
51 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
52 "disabled. Skipping the test";
53 return;
54 }
robpercival214763f2016-07-01 23:27:0155 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]03ec25382011-05-27 21:50:2856 *success = true;
57 }
58
[email protected]3268023f2011-05-05 00:08:1059 static IPEndPoint GetPeerAddress(StreamSocket* socket) {
[email protected]a3528692012-06-08 00:11:4260 IPEndPoint address;
robpercival214763f2016-07-01 23:27:0161 EXPECT_THAT(socket->GetPeerAddress(&address), IsOk());
[email protected]a3528692012-06-08 00:11:4262 return address;
[email protected]38712522011-04-18 23:03:3263 }
64
[email protected]fe89ea72011-05-12 02:02:4065 AddressList local_address_list() const {
[email protected]7054e78f2012-05-07 21:44:5666 return AddressList(local_address_);
[email protected]fe89ea72011-05-12 02:02:4067 }
68
[email protected]38712522011-04-18 23:03:3269 TCPServerSocket socket_;
70 IPEndPoint local_address_;
71};
72
73TEST_F(TCPServerSocketTest, Accept) {
[email protected]03ec25382011-05-27 21:50:2874 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
75
[email protected]83039bb2011-12-09 18:43:5576 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:1377 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:1978 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:1379 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:3280
[email protected]df7a30d2011-12-03 04:16:5081 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:3882 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:5083 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:1384 result = accept_callback.GetResult(result);
robpercival214763f2016-07-01 23:27:0185 ASSERT_THAT(result, IsOk());
[email protected]38712522011-04-18 23:03:3286
Sergey Ulanov7cbcbc52017-07-26 18:29:1387 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]38712522011-04-18 23:03:3288
89 // Both sockets should be on the loopback network interface.
90 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
91 local_address_.address());
92
Sergey Ulanov7cbcbc52017-07-26 18:29:1393 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]38712522011-04-18 23:03:3294}
95
96// Test Accept() callback.
97TEST_F(TCPServerSocketTest, AcceptAsync) {
[email protected]03ec25382011-05-27 21:50:2898 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
99
[email protected]df7a30d2011-12-03 04:16:50100 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38101 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:32102
Sergey Ulanov7cbcbc52017-07-26 18:29:13103 ASSERT_THAT(socket_.Accept(&accepted_socket, accept_callback.callback()),
104 IsError(ERR_IO_PENDING));
[email protected]38712522011-04-18 23:03:32105
[email protected]83039bb2011-12-09 18:43:55106 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13107 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19108 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13109 int connect_result = connecting_socket.Connect(connect_callback.callback());
110 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]38712522011-04-18 23:03:32111
robpercival214763f2016-07-01 23:27:01112 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]38712522011-04-18 23:03:32113
Sergey Ulanov7cbcbc52017-07-26 18:29:13114 EXPECT_TRUE(accepted_socket != nullptr);
[email protected]38712522011-04-18 23:03:32115
116 // Both sockets should be on the loopback network interface.
117 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
118 local_address_.address());
119}
120
121// Accept two connections simultaneously.
122TEST_F(TCPServerSocketTest, Accept2Connections) {
[email protected]03ec25382011-05-27 21:50:28123 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
124
[email protected]df7a30d2011-12-03 04:16:50125 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38126 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:32127
128 ASSERT_EQ(ERR_IO_PENDING,
[email protected]df7a30d2011-12-03 04:16:50129 socket_.Accept(&accepted_socket, accept_callback.callback()));
[email protected]38712522011-04-18 23:03:32130
[email protected]83039bb2011-12-09 18:43:55131 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13132 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19133 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13134 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:32135
[email protected]83039bb2011-12-09 18:43:55136 TestCompletionCallback connect_callback2;
Sergey Ulanov7cbcbc52017-07-26 18:29:13137 TCPClientSocket connecting_socket2(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19138 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13139 int connect_result2 =
140 connecting_socket2.Connect(connect_callback2.callback());
[email protected]38712522011-04-18 23:03:32141
robpercival214763f2016-07-01 23:27:01142 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]38712522011-04-18 23:03:32143
[email protected]df7a30d2011-12-03 04:16:50144 TestCompletionCallback accept_callback2;
danakj655b66c2016-04-16 00:51:38145 std::unique_ptr<StreamSocket> accepted_socket2;
[email protected]df7a30d2011-12-03 04:16:50146 int result = socket_.Accept(&accepted_socket2, accept_callback2.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13147 result = accept_callback2.GetResult(result);
robpercival214763f2016-07-01 23:27:01148 ASSERT_THAT(result, IsOk());
[email protected]38712522011-04-18 23:03:32149
Sergey Ulanov7cbcbc52017-07-26 18:29:13150 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
151 EXPECT_THAT(connect_callback2.GetResult(connect_result2), IsOk());
[email protected]38712522011-04-18 23:03:32152
Sergey Ulanov7cbcbc52017-07-26 18:29:13153 EXPECT_TRUE(accepted_socket != nullptr);
154 EXPECT_TRUE(accepted_socket2 != nullptr);
[email protected]38712522011-04-18 23:03:32155 EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
156
157 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
158 local_address_.address());
159 EXPECT_EQ(GetPeerAddress(accepted_socket2.get()).address(),
160 local_address_.address());
161}
162
[email protected]03ec25382011-05-27 21:50:28163TEST_F(TCPServerSocketTest, AcceptIPv6) {
164 bool initialized = false;
165 ASSERT_NO_FATAL_FAILURE(SetUpIPv6(&initialized));
166 if (!initialized)
167 return;
168
[email protected]83039bb2011-12-09 18:43:55169 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13170 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19171 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13172 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]03ec25382011-05-27 21:50:28173
[email protected]df7a30d2011-12-03 04:16:50174 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38175 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:50176 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13177 result = accept_callback.GetResult(result);
robpercival214763f2016-07-01 23:27:01178 ASSERT_THAT(result, IsOk());
[email protected]03ec25382011-05-27 21:50:28179
Sergey Ulanov7cbcbc52017-07-26 18:29:13180 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]03ec25382011-05-27 21:50:28181
182 // Both sockets should be on the loopback network interface.
183 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
184 local_address_.address());
185
Sergey Ulanov7cbcbc52017-07-26 18:29:13186 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]03ec25382011-05-27 21:50:28187}
188
[email protected]7370de6e2012-02-22 08:04:18189TEST_F(TCPServerSocketTest, AcceptIO) {
190 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
191
192 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13193 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19194 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13195 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18196
197 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38198 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]7370de6e2012-02-22 08:04:18199 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
robpercival214763f2016-07-01 23:27:01200 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
[email protected]7370de6e2012-02-22 08:04:18201
Sergey Ulanov7cbcbc52017-07-26 18:29:13202 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]7370de6e2012-02-22 08:04:18203
204 // Both sockets should be on the loopback network interface.
205 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
206 local_address_.address());
207
Sergey Ulanov7cbcbc52017-07-26 18:29:13208 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]7370de6e2012-02-22 08:04:18209
210 const std::string message("test message");
211 std::vector<char> buffer(message.size());
212
213 size_t bytes_written = 0;
214 while (bytes_written < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44215 scoped_refptr<IOBufferWithSize> write_buffer =
216 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_written);
[email protected]7370de6e2012-02-22 08:04:18217 memmove(write_buffer->data(), message.data(), message.size());
218
219 TestCompletionCallback write_callback;
[email protected]90499482013-06-01 00:39:50220 int write_result = accepted_socket->Write(
Ramin Halavati0a08cc82018-02-06 07:46:38221 write_buffer.get(), write_buffer->size(), write_callback.callback(),
222 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7370de6e2012-02-22 08:04:18223 write_result = write_callback.GetResult(write_result);
224 ASSERT_TRUE(write_result >= 0);
225 ASSERT_TRUE(bytes_written + write_result <= message.size());
226 bytes_written += write_result;
227 }
228
229 size_t bytes_read = 0;
230 while (bytes_read < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44231 scoped_refptr<IOBufferWithSize> read_buffer =
232 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_read);
[email protected]7370de6e2012-02-22 08:04:18233 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50234 int read_result = connecting_socket.Read(
235 read_buffer.get(), read_buffer->size(), read_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18236 read_result = read_callback.GetResult(read_result);
237 ASSERT_TRUE(read_result >= 0);
238 ASSERT_TRUE(bytes_read + read_result <= message.size());
239 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
240 bytes_read += read_result;
241 }
242
243 std::string received_message(buffer.begin(), buffer.end());
244 ASSERT_EQ(message, received_message);
245}
246
[email protected]38712522011-04-18 23:03:32247} // namespace
248
249} // namespace net