blob: 86f7ac4a7239f730a7e68d48b5f880bfb6db7bb1 [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"
22#include "testing/gmock/include/gmock/gmock.h"
[email protected]38712522011-04-18 23:03:3223#include "testing/gtest/include/gtest/gtest.h"
24#include "testing/platform_test.h"
25
Sergey Ulanov7cbcbc52017-07-26 18:29:1326using net::test::IsError;
robpercival214763f2016-07-01 23:27:0127using net::test::IsOk;
28
[email protected]38712522011-04-18 23:03:3229namespace net {
30
31namespace {
32const int kListenBacklog = 5;
33
34class TCPServerSocketTest : public PlatformTest {
35 protected:
Sergey Ulanov7cbcbc52017-07-26 18:29:1336 TCPServerSocketTest() : socket_(nullptr, NetLogSource()) {}
[email protected]38712522011-04-18 23:03:3237
[email protected]03ec25382011-05-27 21:50:2838 void SetUpIPv4() {
martijna2e83bd2016-03-18 13:10:4539 IPEndPoint address(IPAddress::IPv4Localhost(), 0);
robpercival214763f2016-07-01 23:27:0140 ASSERT_THAT(socket_.Listen(address, kListenBacklog), IsOk());
41 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]38712522011-04-18 23:03:3242 }
43
[email protected]03ec25382011-05-27 21:50:2844 void SetUpIPv6(bool* success) {
45 *success = false;
martijna2e83bd2016-03-18 13:10:4546 IPEndPoint address(IPAddress::IPv6Localhost(), 0);
[email protected]03ec25382011-05-27 21:50:2847 if (socket_.Listen(address, kListenBacklog) != 0) {
48 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
49 "disabled. Skipping the test";
50 return;
51 }
robpercival214763f2016-07-01 23:27:0152 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]03ec25382011-05-27 21:50:2853 *success = true;
54 }
55
[email protected]3268023f2011-05-05 00:08:1056 static IPEndPoint GetPeerAddress(StreamSocket* socket) {
[email protected]a3528692012-06-08 00:11:4257 IPEndPoint address;
robpercival214763f2016-07-01 23:27:0158 EXPECT_THAT(socket->GetPeerAddress(&address), IsOk());
[email protected]a3528692012-06-08 00:11:4259 return address;
[email protected]38712522011-04-18 23:03:3260 }
61
[email protected]fe89ea72011-05-12 02:02:4062 AddressList local_address_list() const {
[email protected]7054e78f2012-05-07 21:44:5663 return AddressList(local_address_);
[email protected]fe89ea72011-05-12 02:02:4064 }
65
[email protected]38712522011-04-18 23:03:3266 TCPServerSocket socket_;
67 IPEndPoint local_address_;
68};
69
70TEST_F(TCPServerSocketTest, Accept) {
[email protected]03ec25382011-05-27 21:50:2871 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
72
[email protected]83039bb2011-12-09 18:43:5573 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:1374 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:1975 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:1376 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:3277
[email protected]df7a30d2011-12-03 04:16:5078 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:3879 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:5080 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:1381 result = accept_callback.GetResult(result);
robpercival214763f2016-07-01 23:27:0182 ASSERT_THAT(result, IsOk());
[email protected]38712522011-04-18 23:03:3283
Sergey Ulanov7cbcbc52017-07-26 18:29:1384 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]38712522011-04-18 23:03:3285
86 // Both sockets should be on the loopback network interface.
87 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
88 local_address_.address());
89
Sergey Ulanov7cbcbc52017-07-26 18:29:1390 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]38712522011-04-18 23:03:3291}
92
93// Test Accept() callback.
94TEST_F(TCPServerSocketTest, AcceptAsync) {
[email protected]03ec25382011-05-27 21:50:2895 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
96
[email protected]df7a30d2011-12-03 04:16:5097 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:3898 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:3299
Sergey Ulanov7cbcbc52017-07-26 18:29:13100 ASSERT_THAT(socket_.Accept(&accepted_socket, accept_callback.callback()),
101 IsError(ERR_IO_PENDING));
[email protected]38712522011-04-18 23:03:32102
[email protected]83039bb2011-12-09 18:43:55103 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13104 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19105 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13106 int connect_result = connecting_socket.Connect(connect_callback.callback());
107 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]38712522011-04-18 23:03:32108
robpercival214763f2016-07-01 23:27:01109 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]38712522011-04-18 23:03:32110
Sergey Ulanov7cbcbc52017-07-26 18:29:13111 EXPECT_TRUE(accepted_socket != nullptr);
[email protected]38712522011-04-18 23:03:32112
113 // Both sockets should be on the loopback network interface.
114 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
115 local_address_.address());
116}
117
118// Accept two connections simultaneously.
119TEST_F(TCPServerSocketTest, Accept2Connections) {
[email protected]03ec25382011-05-27 21:50:28120 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
121
[email protected]df7a30d2011-12-03 04:16:50122 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38123 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:32124
125 ASSERT_EQ(ERR_IO_PENDING,
[email protected]df7a30d2011-12-03 04:16:50126 socket_.Accept(&accepted_socket, accept_callback.callback()));
[email protected]38712522011-04-18 23:03:32127
[email protected]83039bb2011-12-09 18:43:55128 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13129 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19130 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13131 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:32132
[email protected]83039bb2011-12-09 18:43:55133 TestCompletionCallback connect_callback2;
Sergey Ulanov7cbcbc52017-07-26 18:29:13134 TCPClientSocket connecting_socket2(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19135 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13136 int connect_result2 =
137 connecting_socket2.Connect(connect_callback2.callback());
[email protected]38712522011-04-18 23:03:32138
robpercival214763f2016-07-01 23:27:01139 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]38712522011-04-18 23:03:32140
[email protected]df7a30d2011-12-03 04:16:50141 TestCompletionCallback accept_callback2;
danakj655b66c2016-04-16 00:51:38142 std::unique_ptr<StreamSocket> accepted_socket2;
[email protected]df7a30d2011-12-03 04:16:50143 int result = socket_.Accept(&accepted_socket2, accept_callback2.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13144 result = accept_callback2.GetResult(result);
robpercival214763f2016-07-01 23:27:01145 ASSERT_THAT(result, IsOk());
[email protected]38712522011-04-18 23:03:32146
Sergey Ulanov7cbcbc52017-07-26 18:29:13147 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
148 EXPECT_THAT(connect_callback2.GetResult(connect_result2), IsOk());
[email protected]38712522011-04-18 23:03:32149
Sergey Ulanov7cbcbc52017-07-26 18:29:13150 EXPECT_TRUE(accepted_socket != nullptr);
151 EXPECT_TRUE(accepted_socket2 != nullptr);
[email protected]38712522011-04-18 23:03:32152 EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
153
154 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
155 local_address_.address());
156 EXPECT_EQ(GetPeerAddress(accepted_socket2.get()).address(),
157 local_address_.address());
158}
159
[email protected]03ec25382011-05-27 21:50:28160TEST_F(TCPServerSocketTest, AcceptIPv6) {
161 bool initialized = false;
162 ASSERT_NO_FATAL_FAILURE(SetUpIPv6(&initialized));
163 if (!initialized)
164 return;
165
[email protected]83039bb2011-12-09 18:43:55166 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13167 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19168 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13169 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]03ec25382011-05-27 21:50:28170
[email protected]df7a30d2011-12-03 04:16:50171 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38172 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:50173 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13174 result = accept_callback.GetResult(result);
robpercival214763f2016-07-01 23:27:01175 ASSERT_THAT(result, IsOk());
[email protected]03ec25382011-05-27 21:50:28176
Sergey Ulanov7cbcbc52017-07-26 18:29:13177 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]03ec25382011-05-27 21:50:28178
179 // Both sockets should be on the loopback network interface.
180 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
181 local_address_.address());
182
Sergey Ulanov7cbcbc52017-07-26 18:29:13183 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]03ec25382011-05-27 21:50:28184}
185
[email protected]7370de6e2012-02-22 08:04:18186TEST_F(TCPServerSocketTest, AcceptIO) {
187 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
188
189 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13190 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19191 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13192 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18193
194 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38195 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]7370de6e2012-02-22 08:04:18196 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
robpercival214763f2016-07-01 23:27:01197 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
[email protected]7370de6e2012-02-22 08:04:18198
Sergey Ulanov7cbcbc52017-07-26 18:29:13199 ASSERT_TRUE(accepted_socket.get() != nullptr);
[email protected]7370de6e2012-02-22 08:04:18200
201 // Both sockets should be on the loopback network interface.
202 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
203 local_address_.address());
204
Sergey Ulanov7cbcbc52017-07-26 18:29:13205 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]7370de6e2012-02-22 08:04:18206
207 const std::string message("test message");
208 std::vector<char> buffer(message.size());
209
210 size_t bytes_written = 0;
211 while (bytes_written < message.size()) {
[email protected]fa6ce922014-07-17 04:27:04212 scoped_refptr<IOBufferWithSize> write_buffer(
213 new IOBufferWithSize(message.size() - bytes_written));
[email protected]7370de6e2012-02-22 08:04:18214 memmove(write_buffer->data(), message.data(), message.size());
215
216 TestCompletionCallback write_callback;
[email protected]90499482013-06-01 00:39:50217 int write_result = accepted_socket->Write(
218 write_buffer.get(), write_buffer->size(), write_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18219 write_result = write_callback.GetResult(write_result);
220 ASSERT_TRUE(write_result >= 0);
221 ASSERT_TRUE(bytes_written + write_result <= message.size());
222 bytes_written += write_result;
223 }
224
225 size_t bytes_read = 0;
226 while (bytes_read < message.size()) {
[email protected]fa6ce922014-07-17 04:27:04227 scoped_refptr<IOBufferWithSize> read_buffer(
228 new IOBufferWithSize(message.size() - bytes_read));
[email protected]7370de6e2012-02-22 08:04:18229 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50230 int read_result = connecting_socket.Read(
231 read_buffer.get(), read_buffer->size(), read_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18232 read_result = read_callback.GetResult(read_result);
233 ASSERT_TRUE(read_result >= 0);
234 ASSERT_TRUE(bytes_read + read_result <= message.size());
235 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
236 bytes_read += read_result;
237 }
238
239 std::string received_message(buffer.begin(), buffer.end());
240 ASSERT_EQ(message, received_message);
241}
242
[email protected]38712522011-04-18 23:03:32243} // namespace
244
245} // namespace net