blob: 651cd6964ad1f0c251fbe41d779a26737ea9d7a5 [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
[email protected]e57a7162011-06-15 04:14:237#include <string>
[email protected]7370de6e2012-02-22 08:04:188#include <vector>
[email protected]e57a7162011-06-15 04:14:239
[email protected]38712522011-04-18 23:03:3210#include "base/compiler_specific.h"
[email protected]7370de6e2012-02-22 08:04:1811#include "base/memory/ref_counted.h"
[email protected]e57a7162011-06-15 04:14:2312#include "base/memory/scoped_ptr.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"
19#include "net/socket/tcp_client_socket.h"
20#include "testing/gtest/include/gtest/gtest.h"
21#include "testing/platform_test.h"
22
23namespace net {
24
25namespace {
26const int kListenBacklog = 5;
27
28class TCPServerSocketTest : public PlatformTest {
29 protected:
30 TCPServerSocketTest()
31 : socket_(NULL, NetLog::Source()) {
32 }
33
[email protected]03ec25382011-05-27 21:50:2834 void SetUpIPv4() {
martijna2e83bd2016-03-18 13:10:4535 IPEndPoint address(IPAddress::IPv4Localhost(), 0);
[email protected]38712522011-04-18 23:03:3236 ASSERT_EQ(OK, socket_.Listen(address, kListenBacklog));
37 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_));
38 }
39
[email protected]03ec25382011-05-27 21:50:2840 void SetUpIPv6(bool* success) {
41 *success = false;
martijna2e83bd2016-03-18 13:10:4542 IPEndPoint address(IPAddress::IPv6Localhost(), 0);
[email protected]03ec25382011-05-27 21:50:2843 if (socket_.Listen(address, kListenBacklog) != 0) {
44 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
45 "disabled. Skipping the test";
46 return;
47 }
48 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_));
49 *success = true;
50 }
51
[email protected]3268023f2011-05-05 00:08:1052 static IPEndPoint GetPeerAddress(StreamSocket* socket) {
[email protected]a3528692012-06-08 00:11:4253 IPEndPoint address;
[email protected]38712522011-04-18 23:03:3254 EXPECT_EQ(OK, socket->GetPeerAddress(&address));
[email protected]a3528692012-06-08 00:11:4255 return address;
[email protected]38712522011-04-18 23:03:3256 }
57
[email protected]fe89ea72011-05-12 02:02:4058 AddressList local_address_list() const {
[email protected]7054e78f2012-05-07 21:44:5659 return AddressList(local_address_);
[email protected]fe89ea72011-05-12 02:02:4060 }
61
[email protected]38712522011-04-18 23:03:3262 TCPServerSocket socket_;
63 IPEndPoint local_address_;
64};
65
66TEST_F(TCPServerSocketTest, Accept) {
[email protected]03ec25382011-05-27 21:50:2867 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
68
[email protected]83039bb2011-12-09 18:43:5569 TestCompletionCallback connect_callback;
[email protected]fe89ea72011-05-12 02:02:4070 TCPClientSocket connecting_socket(local_address_list(),
[email protected]38712522011-04-18 23:03:3271 NULL, NetLog::Source());
[email protected]83039bb2011-12-09 18:43:5572 connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:3273
[email protected]df7a30d2011-12-03 04:16:5074 TestCompletionCallback accept_callback;
[email protected]3268023f2011-05-05 00:08:1075 scoped_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:5076 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
[email protected]38712522011-04-18 23:03:3277 if (result == ERR_IO_PENDING)
78 result = accept_callback.WaitForResult();
79 ASSERT_EQ(OK, result);
80
81 ASSERT_TRUE(accepted_socket.get() != NULL);
82
83 // Both sockets should be on the loopback network interface.
84 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
85 local_address_.address());
86
87 EXPECT_EQ(OK, connect_callback.WaitForResult());
88}
89
90// Test Accept() callback.
91TEST_F(TCPServerSocketTest, AcceptAsync) {
[email protected]03ec25382011-05-27 21:50:2892 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
93
[email protected]df7a30d2011-12-03 04:16:5094 TestCompletionCallback accept_callback;
[email protected]3268023f2011-05-05 00:08:1095 scoped_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:3296
[email protected]df7a30d2011-12-03 04:16:5097 ASSERT_EQ(ERR_IO_PENDING,
98 socket_.Accept(&accepted_socket, accept_callback.callback()));
[email protected]38712522011-04-18 23:03:3299
[email protected]83039bb2011-12-09 18:43:55100 TestCompletionCallback connect_callback;
[email protected]fe89ea72011-05-12 02:02:40101 TCPClientSocket connecting_socket(local_address_list(),
[email protected]38712522011-04-18 23:03:32102 NULL, NetLog::Source());
[email protected]83039bb2011-12-09 18:43:55103 connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:32104
105 EXPECT_EQ(OK, connect_callback.WaitForResult());
106 EXPECT_EQ(OK, accept_callback.WaitForResult());
107
108 EXPECT_TRUE(accepted_socket != NULL);
109
110 // Both sockets should be on the loopback network interface.
111 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
112 local_address_.address());
113}
114
115// Accept two connections simultaneously.
116TEST_F(TCPServerSocketTest, Accept2Connections) {
[email protected]03ec25382011-05-27 21:50:28117 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
118
[email protected]df7a30d2011-12-03 04:16:50119 TestCompletionCallback accept_callback;
[email protected]3268023f2011-05-05 00:08:10120 scoped_ptr<StreamSocket> accepted_socket;
[email protected]38712522011-04-18 23:03:32121
122 ASSERT_EQ(ERR_IO_PENDING,
[email protected]df7a30d2011-12-03 04:16:50123 socket_.Accept(&accepted_socket, accept_callback.callback()));
[email protected]38712522011-04-18 23:03:32124
[email protected]83039bb2011-12-09 18:43:55125 TestCompletionCallback connect_callback;
[email protected]fe89ea72011-05-12 02:02:40126 TCPClientSocket connecting_socket(local_address_list(),
[email protected]38712522011-04-18 23:03:32127 NULL, NetLog::Source());
[email protected]83039bb2011-12-09 18:43:55128 connecting_socket.Connect(connect_callback.callback());
[email protected]38712522011-04-18 23:03:32129
[email protected]83039bb2011-12-09 18:43:55130 TestCompletionCallback connect_callback2;
[email protected]fe89ea72011-05-12 02:02:40131 TCPClientSocket connecting_socket2(local_address_list(),
[email protected]38712522011-04-18 23:03:32132 NULL, NetLog::Source());
[email protected]83039bb2011-12-09 18:43:55133 connecting_socket2.Connect(connect_callback2.callback());
[email protected]38712522011-04-18 23:03:32134
135 EXPECT_EQ(OK, accept_callback.WaitForResult());
136
[email protected]df7a30d2011-12-03 04:16:50137 TestCompletionCallback accept_callback2;
[email protected]3268023f2011-05-05 00:08:10138 scoped_ptr<StreamSocket> accepted_socket2;
[email protected]df7a30d2011-12-03 04:16:50139 int result = socket_.Accept(&accepted_socket2, accept_callback2.callback());
[email protected]38712522011-04-18 23:03:32140 if (result == ERR_IO_PENDING)
141 result = accept_callback2.WaitForResult();
142 ASSERT_EQ(OK, result);
143
144 EXPECT_EQ(OK, connect_callback.WaitForResult());
145
146 EXPECT_TRUE(accepted_socket != NULL);
147 EXPECT_TRUE(accepted_socket2 != NULL);
148 EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
149
150 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
151 local_address_.address());
152 EXPECT_EQ(GetPeerAddress(accepted_socket2.get()).address(),
153 local_address_.address());
154}
155
[email protected]03ec25382011-05-27 21:50:28156TEST_F(TCPServerSocketTest, AcceptIPv6) {
157 bool initialized = false;
158 ASSERT_NO_FATAL_FAILURE(SetUpIPv6(&initialized));
159 if (!initialized)
160 return;
161
[email protected]83039bb2011-12-09 18:43:55162 TestCompletionCallback connect_callback;
[email protected]03ec25382011-05-27 21:50:28163 TCPClientSocket connecting_socket(local_address_list(),
164 NULL, NetLog::Source());
[email protected]83039bb2011-12-09 18:43:55165 connecting_socket.Connect(connect_callback.callback());
[email protected]03ec25382011-05-27 21:50:28166
[email protected]df7a30d2011-12-03 04:16:50167 TestCompletionCallback accept_callback;
[email protected]03ec25382011-05-27 21:50:28168 scoped_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:50169 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
[email protected]03ec25382011-05-27 21:50:28170 if (result == ERR_IO_PENDING)
171 result = accept_callback.WaitForResult();
172 ASSERT_EQ(OK, result);
173
174 ASSERT_TRUE(accepted_socket.get() != NULL);
175
176 // Both sockets should be on the loopback network interface.
177 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
178 local_address_.address());
179
180 EXPECT_EQ(OK, connect_callback.WaitForResult());
181}
182
[email protected]7370de6e2012-02-22 08:04:18183TEST_F(TCPServerSocketTest, AcceptIO) {
184 ASSERT_NO_FATAL_FAILURE(SetUpIPv4());
185
186 TestCompletionCallback connect_callback;
187 TCPClientSocket connecting_socket(local_address_list(),
188 NULL, NetLog::Source());
189 connecting_socket.Connect(connect_callback.callback());
190
191 TestCompletionCallback accept_callback;
192 scoped_ptr<StreamSocket> accepted_socket;
193 int result = socket_.Accept(&accepted_socket, accept_callback.callback());
194 ASSERT_EQ(OK, accept_callback.GetResult(result));
195
196 ASSERT_TRUE(accepted_socket.get() != NULL);
197
198 // Both sockets should be on the loopback network interface.
199 EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
200 local_address_.address());
201
202 EXPECT_EQ(OK, connect_callback.WaitForResult());
203
204 const std::string message("test message");
205 std::vector<char> buffer(message.size());
206
207 size_t bytes_written = 0;
208 while (bytes_written < message.size()) {
[email protected]fa6ce922014-07-17 04:27:04209 scoped_refptr<IOBufferWithSize> write_buffer(
210 new IOBufferWithSize(message.size() - bytes_written));
[email protected]7370de6e2012-02-22 08:04:18211 memmove(write_buffer->data(), message.data(), message.size());
212
213 TestCompletionCallback write_callback;
[email protected]90499482013-06-01 00:39:50214 int write_result = accepted_socket->Write(
215 write_buffer.get(), write_buffer->size(), write_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18216 write_result = write_callback.GetResult(write_result);
217 ASSERT_TRUE(write_result >= 0);
218 ASSERT_TRUE(bytes_written + write_result <= message.size());
219 bytes_written += write_result;
220 }
221
222 size_t bytes_read = 0;
223 while (bytes_read < message.size()) {
[email protected]fa6ce922014-07-17 04:27:04224 scoped_refptr<IOBufferWithSize> read_buffer(
225 new IOBufferWithSize(message.size() - bytes_read));
[email protected]7370de6e2012-02-22 08:04:18226 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50227 int read_result = connecting_socket.Read(
228 read_buffer.get(), read_buffer->size(), read_callback.callback());
[email protected]7370de6e2012-02-22 08:04:18229 read_result = read_callback.GetResult(read_result);
230 ASSERT_TRUE(read_result >= 0);
231 ASSERT_TRUE(bytes_read + read_result <= message.size());
232 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
233 bytes_read += read_result;
234 }
235
236 std::string received_message(buffer.begin(), buffer.end());
237 ASSERT_EQ(message, received_message);
238}
239
[email protected]38712522011-04-18 23:03:32240} // namespace
241
242} // namespace net