blob: 7af6c1296fbee155b44006bbf71501e5bf2e45d2 [file] [log] [blame]
[email protected]21160f02013-09-01 23:04:271// Copyright 2013 The Chromium Authors. All rights reserved.
2// 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_socket.h"
6
tbansal7b403bcc2016-04-13 22:33:217#include <stddef.h>
[email protected]c9080d82013-09-15 15:14:168#include <string.h>
[email protected]21160f02013-09-01 23:04:279
danakj655b66c2016-04-16 00:51:3810#include <memory>
[email protected]c9080d82013-09-15 15:14:1611#include <string>
12#include <vector>
13
[email protected]c9080d82013-09-15 15:14:1614#include "base/memory/ref_counted.h"
tbansal7b403bcc2016-04-13 22:33:2115#include "base/time/time.h"
Paul Jensen0f49dec2017-12-12 23:39:5816#include "build/build_config.h"
[email protected]21160f02013-09-01 23:04:2717#include "net/base/address_list.h"
[email protected]c9080d82013-09-15 15:14:1618#include "net/base/io_buffer.h"
[email protected]21160f02013-09-01 23:04:2719#include "net/base/ip_endpoint.h"
20#include "net/base/net_errors.h"
tfarina3d87d7cd2016-01-13 02:26:5921#include "net/base/sockaddr_storage.h"
[email protected]21160f02013-09-01 23:04:2722#include "net/base/test_completion_callback.h"
mikecironef22f9812016-10-04 03:40:1923#include "net/log/net_log_source.h"
tbansalca83c002016-04-28 20:56:2824#include "net/socket/socket_performance_watcher.h"
Paul Jensen0f49dec2017-12-12 23:39:5825#include "net/socket/socket_test_util.h"
[email protected]21160f02013-09-01 23:04:2726#include "net/socket/tcp_client_socket.h"
Paul Jensen0f49dec2017-12-12 23:39:5827#include "net/test/embedded_test_server/embedded_test_server.h"
robpercival214763f2016-07-01 23:27:0128#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0129#include "net/test/test_with_scoped_task_environment.h"
[email protected]690bbea2017-12-08 09:05:4630#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0131#include "testing/gmock/include/gmock/gmock.h"
[email protected]21160f02013-09-01 23:04:2732#include "testing/gtest/include/gtest/gtest.h"
33#include "testing/platform_test.h"
34
Sergey Ulanov7cbcbc52017-07-26 18:29:1335using net::test::IsError;
robpercival214763f2016-07-01 23:27:0136using net::test::IsOk;
37
[email protected]21160f02013-09-01 23:04:2738namespace net {
39
40namespace {
tbansal7b403bcc2016-04-13 22:33:2141
Matt Menkee06732012018-04-06 21:41:2442// IOBuffer with the ability to invoke a callback when destroyed. Useful for
43// checking for leaks.
44class IOBufferWithDestructionCallback : public IOBufferWithSize {
45 public:
46 explicit IOBufferWithDestructionCallback(base::OnceClosure on_destroy_closure)
47 : IOBufferWithSize(1024),
48 on_destroy_closure_(std::move(on_destroy_closure)) {
49 DCHECK(on_destroy_closure_);
50 }
51
52 protected:
53 ~IOBufferWithDestructionCallback() override {
54 std::move(on_destroy_closure_).Run();
55 }
56
57 base::OnceClosure on_destroy_closure_;
58};
59
tbansal7b403bcc2016-04-13 22:33:2160class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
61 public:
62 explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt)
63 : should_notify_updated_rtt_(should_notify_updated_rtt),
64 connection_changed_count_(0u),
65 rtt_notification_count_(0u) {}
Chris Watkins7a41d3552017-12-01 02:13:2766 ~TestSocketPerformanceWatcher() override = default;
tbansal7b403bcc2016-04-13 22:33:2167
68 bool ShouldNotifyUpdatedRTT() const override {
69 return should_notify_updated_rtt_;
70 }
71
72 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
73 rtt_notification_count_++;
74 }
75
76 void OnConnectionChanged() override { connection_changed_count_++; }
77
78 size_t rtt_notification_count() const { return rtt_notification_count_; }
79
80 size_t connection_changed_count() const { return connection_changed_count_; }
81
82 private:
83 const bool should_notify_updated_rtt_;
84 size_t connection_changed_count_;
85 size_t rtt_notification_count_;
86
87 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
88};
89
[email protected]21160f02013-09-01 23:04:2790const int kListenBacklog = 5;
91
Bence Béky98447b12018-05-08 03:14:0192class TCPSocketTest : public PlatformTest, public WithScopedTaskEnvironment {
[email protected]21160f02013-09-01 23:04:2793 protected:
Sergey Ulanov7cbcbc52017-07-26 18:29:1394 TCPSocketTest() : socket_(nullptr, nullptr, NetLogSource()) {}
[email protected]21160f02013-09-01 23:04:2795
96 void SetUpListenIPv4() {
robpercival214763f2016-07-01 23:27:0197 ASSERT_THAT(socket_.Open(ADDRESS_FAMILY_IPV4), IsOk());
98 ASSERT_THAT(socket_.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)),
99 IsOk());
100 ASSERT_THAT(socket_.Listen(kListenBacklog), IsOk());
101 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]21160f02013-09-01 23:04:27102 }
103
104 void SetUpListenIPv6(bool* success) {
105 *success = false;
[email protected]21160f02013-09-01 23:04:27106
[email protected]c9080d82013-09-15 15:14:16107 if (socket_.Open(ADDRESS_FAMILY_IPV6) != OK ||
martijna2e83bd2016-03-18 13:10:45108 socket_.Bind(IPEndPoint(IPAddress::IPv6Localhost(), 0)) != OK ||
[email protected]21160f02013-09-01 23:04:27109 socket_.Listen(kListenBacklog) != OK) {
110 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
111 "disabled. Skipping the test";
112 return;
113 }
robpercival214763f2016-07-01 23:27:01114 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]21160f02013-09-01 23:04:27115 *success = true;
116 }
117
[email protected]ef2f0022014-04-29 10:24:35118 void TestAcceptAsync() {
119 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38120 std::unique_ptr<TCPSocket> accepted_socket;
[email protected]ef2f0022014-04-29 10:24:35121 IPEndPoint accepted_address;
Sergey Ulanov7cbcbc52017-07-26 18:29:13122 ASSERT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
123 accept_callback.callback()),
124 IsError(ERR_IO_PENDING));
[email protected]ef2f0022014-04-29 10:24:35125
126 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13127 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19128 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13129 int connect_result = connecting_socket.Connect(connect_callback.callback());
130 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]ef2f0022014-04-29 10:24:35131
robpercival214763f2016-07-01 23:27:01132 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]ef2f0022014-04-29 10:24:35133
134 EXPECT_TRUE(accepted_socket.get());
135
136 // Both sockets should be on the loopback network interface.
137 EXPECT_EQ(accepted_address.address(), local_address_.address());
138 }
139
tbansal7b403bcc2016-04-13 22:33:21140#if defined(TCP_INFO) || defined(OS_LINUX)
141 // Tests that notifications to Socket Performance Watcher (SPW) are delivered
tbansal180587c2017-02-16 15:13:23142 // correctly. |should_notify_updated_rtt| is true if the SPW is interested in
143 // receiving RTT notifications. |num_messages| is the number of messages that
144 // are written/read by the sockets. |expect_connection_changed_count| is the
145 // expected number of connection change notifications received by the SPW.
146 // |expect_rtt_notification_count| is the expected number of RTT
147 // notifications received by the SPW. This test works by writing
148 // |num_messages| to the socket. A different socket (with a SPW attached to
149 // it) reads the messages.
150 void TestSPWNotifications(bool should_notify_updated_rtt,
tbansal7b403bcc2016-04-13 22:33:21151 size_t num_messages,
152 size_t expect_connection_changed_count,
153 size_t expect_rtt_notification_count) {
154 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
155
tbansal7b403bcc2016-04-13 22:33:21156 TestCompletionCallback connect_callback;
157
danakj655b66c2016-04-16 00:51:38158 std::unique_ptr<TestSocketPerformanceWatcher> watcher(
tbansal7b403bcc2016-04-13 22:33:21159 new TestSocketPerformanceWatcher(should_notify_updated_rtt));
160 TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
161
Sergey Ulanov7cbcbc52017-07-26 18:29:13162 TCPSocket connecting_socket(std::move(watcher), nullptr, NetLogSource());
tbansal7b403bcc2016-04-13 22:33:21163
164 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
robpercival214763f2016-07-01 23:27:01165 ASSERT_THAT(result, IsOk());
Sergey Ulanov7cbcbc52017-07-26 18:29:13166 int connect_result =
167 connecting_socket.Connect(local_address_, connect_callback.callback());
tbansal7b403bcc2016-04-13 22:33:21168
169 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38170 std::unique_ptr<TCPSocket> accepted_socket;
tbansal7b403bcc2016-04-13 22:33:21171 IPEndPoint accepted_address;
172 result = socket_.Accept(&accepted_socket, &accepted_address,
173 accept_callback.callback());
robpercival214763f2016-07-01 23:27:01174 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
tbansal7b403bcc2016-04-13 22:33:21175
176 ASSERT_TRUE(accepted_socket.get());
177
178 // Both sockets should be on the loopback network interface.
179 EXPECT_EQ(accepted_address.address(), local_address_.address());
180
Sergey Ulanov7cbcbc52017-07-26 18:29:13181 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
tbansal7b403bcc2016-04-13 22:33:21182
183 for (size_t i = 0; i < num_messages; ++i) {
tbansal7b403bcc2016-04-13 22:33:21184 // Use a 1 byte message so that the watcher is notified at most once per
185 // message.
186 const std::string message("t");
187
Victor Costan9c7302b2018-08-27 16:39:44188 scoped_refptr<IOBufferWithSize> write_buffer =
189 base::MakeRefCounted<IOBufferWithSize>(message.size());
tbansal7b403bcc2016-04-13 22:33:21190 memmove(write_buffer->data(), message.data(), message.size());
191
192 TestCompletionCallback write_callback;
193 int write_result = accepted_socket->Write(
[email protected]690bbea2017-12-08 09:05:46194 write_buffer.get(), write_buffer->size(), write_callback.callback(),
195 TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal7b403bcc2016-04-13 22:33:21196
Victor Costan9c7302b2018-08-27 16:39:44197 scoped_refptr<IOBufferWithSize> read_buffer =
198 base::MakeRefCounted<IOBufferWithSize>(message.size());
tbansal7b403bcc2016-04-13 22:33:21199 TestCompletionCallback read_callback;
200 int read_result = connecting_socket.Read(
201 read_buffer.get(), read_buffer->size(), read_callback.callback());
202
203 ASSERT_EQ(1, write_callback.GetResult(write_result));
204 ASSERT_EQ(1, read_callback.GetResult(read_result));
205 }
206 EXPECT_EQ(expect_connection_changed_count,
207 watcher_ptr->connection_changed_count());
208 EXPECT_EQ(expect_rtt_notification_count,
209 watcher_ptr->rtt_notification_count());
210 }
211#endif // defined(TCP_INFO) || defined(OS_LINUX)
212
[email protected]21160f02013-09-01 23:04:27213 AddressList local_address_list() const {
214 return AddressList(local_address_);
215 }
216
217 TCPSocket socket_;
218 IPEndPoint local_address_;
219};
220
221// Test listening and accepting with a socket bound to an IPv4 address.
222TEST_F(TCPSocketTest, Accept) {
223 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
224
225 TestCompletionCallback connect_callback;
226 // TODO(yzshen): Switch to use TCPSocket when it supports client socket
227 // operations.
Sergey Ulanov7cbcbc52017-07-26 18:29:13228 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19229 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13230 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]21160f02013-09-01 23:04:27231
232 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38233 std::unique_ptr<TCPSocket> accepted_socket;
[email protected]21160f02013-09-01 23:04:27234 IPEndPoint accepted_address;
235 int result = socket_.Accept(&accepted_socket, &accepted_address,
236 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13237 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
[email protected]21160f02013-09-01 23:04:27238
239 EXPECT_TRUE(accepted_socket.get());
240
241 // Both sockets should be on the loopback network interface.
242 EXPECT_EQ(accepted_address.address(), local_address_.address());
243
Sergey Ulanov7cbcbc52017-07-26 18:29:13244 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]21160f02013-09-01 23:04:27245}
246
247// Test Accept() callback.
248TEST_F(TCPSocketTest, AcceptAsync) {
249 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
[email protected]ef2f0022014-04-29 10:24:35250 TestAcceptAsync();
[email protected]21160f02013-09-01 23:04:27251}
252
rvera26f0a1392017-05-02 22:25:44253// Test AdoptConnectedSocket()
254TEST_F(TCPSocketTest, AdoptConnectedSocket) {
Sergey Ulanov7cbcbc52017-07-26 18:29:13255 TCPSocket accepting_socket(nullptr, nullptr, NetLogSource());
rvera26f0a1392017-05-02 22:25:44256 ASSERT_THAT(accepting_socket.Open(ADDRESS_FAMILY_IPV4), IsOk());
257 ASSERT_THAT(accepting_socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)),
258 IsOk());
259 ASSERT_THAT(accepting_socket.GetLocalAddress(&local_address_), IsOk());
260 ASSERT_THAT(accepting_socket.Listen(kListenBacklog), IsOk());
261
262 TestCompletionCallback connect_callback;
263 // TODO(yzshen): Switch to use TCPSocket when it supports client socket
264 // operations.
Sergey Ulanov7cbcbc52017-07-26 18:29:13265 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
rvera26f0a1392017-05-02 22:25:44266 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13267 int connect_result = connecting_socket.Connect(connect_callback.callback());
rvera26f0a1392017-05-02 22:25:44268
269 TestCompletionCallback accept_callback;
270 std::unique_ptr<TCPSocket> accepted_socket;
271 IPEndPoint accepted_address;
272 int result = accepting_socket.Accept(&accepted_socket, &accepted_address,
273 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13274 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
rvera26f0a1392017-05-02 22:25:44275
276 SocketDescriptor accepted_descriptor =
277 accepted_socket->ReleaseSocketDescriptorForTesting();
278
279 ASSERT_THAT(
280 socket_.AdoptConnectedSocket(accepted_descriptor, accepted_address),
281 IsOk());
282
283 // socket_ should now have the local address.
284 IPEndPoint adopted_address;
285 ASSERT_THAT(socket_.GetLocalAddress(&adopted_address), IsOk());
286 EXPECT_EQ(local_address_.address(), adopted_address.address());
287
Sergey Ulanov7cbcbc52017-07-26 18:29:13288 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
rvera26f0a1392017-05-02 22:25:44289}
290
291// Test Accept() for AdoptUnconnectedSocket.
292TEST_F(TCPSocketTest, AcceptForAdoptedUnconnectedSocket) {
293 SocketDescriptor existing_socket =
294 CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
295 ASSERT_THAT(socket_.AdoptUnconnectedSocket(existing_socket), IsOk());
[email protected]ef2f0022014-04-29 10:24:35296
martijna2e83bd2016-03-18 13:10:45297 IPEndPoint address(IPAddress::IPv4Localhost(), 0);
[email protected]ef2f0022014-04-29 10:24:35298 SockaddrStorage storage;
299 ASSERT_TRUE(address.ToSockAddr(storage.addr, &storage.addr_len));
300 ASSERT_EQ(0, bind(existing_socket, storage.addr, storage.addr_len));
301
robpercival214763f2016-07-01 23:27:01302 ASSERT_THAT(socket_.Listen(kListenBacklog), IsOk());
303 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
[email protected]ef2f0022014-04-29 10:24:35304
305 TestAcceptAsync();
306}
[email protected]ef2f0022014-04-29 10:24:35307
[email protected]21160f02013-09-01 23:04:27308// Accept two connections simultaneously.
309TEST_F(TCPSocketTest, Accept2Connections) {
310 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
311
312 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38313 std::unique_ptr<TCPSocket> accepted_socket;
[email protected]21160f02013-09-01 23:04:27314 IPEndPoint accepted_address;
315
Sergey Ulanov7cbcbc52017-07-26 18:29:13316 ASSERT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
317 accept_callback.callback()),
318 IsError(ERR_IO_PENDING));
[email protected]21160f02013-09-01 23:04:27319
320 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13321 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19322 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13323 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]21160f02013-09-01 23:04:27324
325 TestCompletionCallback connect_callback2;
Sergey Ulanov7cbcbc52017-07-26 18:29:13326 TCPClientSocket connecting_socket2(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19327 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13328 int connect_result2 =
329 connecting_socket2.Connect(connect_callback2.callback());
[email protected]21160f02013-09-01 23:04:27330
robpercival214763f2016-07-01 23:27:01331 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
[email protected]21160f02013-09-01 23:04:27332
333 TestCompletionCallback accept_callback2;
danakj655b66c2016-04-16 00:51:38334 std::unique_ptr<TCPSocket> accepted_socket2;
[email protected]21160f02013-09-01 23:04:27335 IPEndPoint accepted_address2;
336
337 int result = socket_.Accept(&accepted_socket2, &accepted_address2,
338 accept_callback2.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13339 ASSERT_THAT(accept_callback2.GetResult(result), IsOk());
[email protected]21160f02013-09-01 23:04:27340
Sergey Ulanov7cbcbc52017-07-26 18:29:13341 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
342 EXPECT_THAT(connect_callback2.GetResult(connect_result2), IsOk());
[email protected]21160f02013-09-01 23:04:27343
344 EXPECT_TRUE(accepted_socket.get());
345 EXPECT_TRUE(accepted_socket2.get());
346 EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
347
348 EXPECT_EQ(accepted_address.address(), local_address_.address());
349 EXPECT_EQ(accepted_address2.address(), local_address_.address());
350}
351
352// Test listening and accepting with a socket bound to an IPv6 address.
353TEST_F(TCPSocketTest, AcceptIPv6) {
354 bool initialized = false;
355 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized));
356 if (!initialized)
357 return;
358
359 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13360 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19361 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13362 int connect_result = connecting_socket.Connect(connect_callback.callback());
[email protected]21160f02013-09-01 23:04:27363
364 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38365 std::unique_ptr<TCPSocket> accepted_socket;
[email protected]21160f02013-09-01 23:04:27366 IPEndPoint accepted_address;
367 int result = socket_.Accept(&accepted_socket, &accepted_address,
368 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13369 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
[email protected]21160f02013-09-01 23:04:27370
371 EXPECT_TRUE(accepted_socket.get());
372
373 // Both sockets should be on the loopback network interface.
374 EXPECT_EQ(accepted_address.address(), local_address_.address());
375
Sergey Ulanov7cbcbc52017-07-26 18:29:13376 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]21160f02013-09-01 23:04:27377}
378
[email protected]c9080d82013-09-15 15:14:16379TEST_F(TCPSocketTest, ReadWrite) {
380 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
381
382 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13383 TCPSocket connecting_socket(nullptr, nullptr, NetLogSource());
[email protected]c9080d82013-09-15 15:14:16384 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
robpercival214763f2016-07-01 23:27:01385 ASSERT_THAT(result, IsOk());
Sergey Ulanov7cbcbc52017-07-26 18:29:13386 int connect_result =
387 connecting_socket.Connect(local_address_, connect_callback.callback());
[email protected]c9080d82013-09-15 15:14:16388
389 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38390 std::unique_ptr<TCPSocket> accepted_socket;
[email protected]c9080d82013-09-15 15:14:16391 IPEndPoint accepted_address;
392 result = socket_.Accept(&accepted_socket, &accepted_address,
393 accept_callback.callback());
robpercival214763f2016-07-01 23:27:01394 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
[email protected]c9080d82013-09-15 15:14:16395
396 ASSERT_TRUE(accepted_socket.get());
397
398 // Both sockets should be on the loopback network interface.
399 EXPECT_EQ(accepted_address.address(), local_address_.address());
400
Sergey Ulanov7cbcbc52017-07-26 18:29:13401 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
[email protected]c9080d82013-09-15 15:14:16402
403 const std::string message("test message");
404 std::vector<char> buffer(message.size());
405
406 size_t bytes_written = 0;
407 while (bytes_written < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44408 scoped_refptr<IOBufferWithSize> write_buffer =
409 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_written);
[email protected]c9080d82013-09-15 15:14:16410 memmove(write_buffer->data(), message.data() + bytes_written,
411 message.size() - bytes_written);
412
413 TestCompletionCallback write_callback;
414 int write_result = accepted_socket->Write(
[email protected]690bbea2017-12-08 09:05:46415 write_buffer.get(), write_buffer->size(), write_callback.callback(),
416 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c9080d82013-09-15 15:14:16417 write_result = write_callback.GetResult(write_result);
418 ASSERT_TRUE(write_result >= 0);
419 bytes_written += write_result;
420 ASSERT_TRUE(bytes_written <= message.size());
421 }
422
423 size_t bytes_read = 0;
424 while (bytes_read < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44425 scoped_refptr<IOBufferWithSize> read_buffer =
426 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_read);
[email protected]c9080d82013-09-15 15:14:16427 TestCompletionCallback read_callback;
428 int read_result = connecting_socket.Read(
429 read_buffer.get(), read_buffer->size(), read_callback.callback());
430 read_result = read_callback.GetResult(read_result);
431 ASSERT_TRUE(read_result >= 0);
432 ASSERT_TRUE(bytes_read + read_result <= message.size());
433 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
434 bytes_read += read_result;
435 }
436
437 std::string received_message(buffer.begin(), buffer.end());
438 ASSERT_EQ(message, received_message);
439}
440
Matt Menkee06732012018-04-06 21:41:24441// Destroy a TCPSocket while there's a pending read, and make sure the read
442// IOBuffer that the socket was holding on to is destroyed.
443// See https://crbug.com/804868.
444TEST_F(TCPSocketTest, DestroyWithPendingRead) {
445 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
446
447 // Create a connected socket.
448
449 TestCompletionCallback connect_callback;
450 std::unique_ptr<TCPSocket> connecting_socket =
451 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
452 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
453 ASSERT_THAT(result, IsOk());
454 int connect_result =
455 connecting_socket->Connect(local_address_, connect_callback.callback());
456
457 TestCompletionCallback accept_callback;
458 std::unique_ptr<TCPSocket> accepted_socket;
459 IPEndPoint accepted_address;
460 result = socket_.Accept(&accepted_socket, &accepted_address,
461 accept_callback.callback());
462 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
463 ASSERT_TRUE(accepted_socket.get());
464 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
465
466 // Try to read from the socket, but never write anything to the other end.
467 base::RunLoop run_loop;
468 scoped_refptr<IOBufferWithDestructionCallback> read_buffer(
469 base::MakeRefCounted<IOBufferWithDestructionCallback>(
470 run_loop.QuitClosure()));
471 TestCompletionCallback read_callback;
472 EXPECT_EQ(ERR_IO_PENDING,
473 connecting_socket->Read(read_buffer.get(), read_buffer->size(),
474 read_callback.callback()));
475
476 // Release the handle to the read buffer and destroy the socket. Make sure the
477 // read buffer is destroyed.
478 read_buffer = nullptr;
479 connecting_socket.reset();
480 run_loop.Run();
481}
482
483// Destroy a TCPSocket while there's a pending write, and make sure the write
484// IOBuffer that the socket was holding on to is destroyed.
485TEST_F(TCPSocketTest, DestroyWithPendingWrite) {
486 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
487
488 // Create a connected socket.
489
490 TestCompletionCallback connect_callback;
491 std::unique_ptr<TCPSocket> connecting_socket =
492 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
493 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
494 ASSERT_THAT(result, IsOk());
495 int connect_result =
496 connecting_socket->Connect(local_address_, connect_callback.callback());
497
498 TestCompletionCallback accept_callback;
499 std::unique_ptr<TCPSocket> accepted_socket;
500 IPEndPoint accepted_address;
501 result = socket_.Accept(&accepted_socket, &accepted_address,
502 accept_callback.callback());
503 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
504 ASSERT_TRUE(accepted_socket.get());
505 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
506
507 // Repeatedly write to the socket until an operation does not complete
508 // synchronously.
509 base::RunLoop run_loop;
510 scoped_refptr<IOBufferWithDestructionCallback> write_buffer(
511 base::MakeRefCounted<IOBufferWithDestructionCallback>(
512 run_loop.QuitClosure()));
513 memset(write_buffer->data(), '1', write_buffer->size());
514 TestCompletionCallback write_callback;
515 while (true) {
516 int result = connecting_socket->Write(
517 write_buffer.get(), write_buffer->size(), write_callback.callback(),
518 TRAFFIC_ANNOTATION_FOR_TESTS);
519 if (result == ERR_IO_PENDING)
520 break;
521 ASSERT_LT(0, result);
522 }
523
524 // Release the handle to the read buffer and destroy the socket. Make sure the
525 // write buffer is destroyed.
526 write_buffer = nullptr;
527 connecting_socket.reset();
528 run_loop.Run();
529}
530
Helen Lia6d3b2c2018-05-08 16:09:07531// If a ReadIfReady is pending, it's legal to cancel it and start reading later.
532TEST_F(TCPSocketTest, CancelPendingReadIfReady) {
533 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
534
535 // Create a connected socket.
536 TestCompletionCallback connect_callback;
537 std::unique_ptr<TCPSocket> connecting_socket =
538 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
539 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
540 ASSERT_THAT(result, IsOk());
541 int connect_result =
542 connecting_socket->Connect(local_address_, connect_callback.callback());
543
544 TestCompletionCallback accept_callback;
545 std::unique_ptr<TCPSocket> accepted_socket;
546 IPEndPoint accepted_address;
547 result = socket_.Accept(&accepted_socket, &accepted_address,
548 accept_callback.callback());
549 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
550 ASSERT_TRUE(accepted_socket.get());
551 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
552
553 // Try to read from the socket, but never write anything to the other end.
554 base::RunLoop run_loop;
555 scoped_refptr<IOBufferWithDestructionCallback> read_buffer(
556 base::MakeRefCounted<IOBufferWithDestructionCallback>(
557 run_loop.QuitClosure()));
558 TestCompletionCallback read_callback;
559 EXPECT_EQ(ERR_IO_PENDING, connecting_socket->ReadIfReady(
560 read_buffer.get(), read_buffer->size(),
561 read_callback.callback()));
562
563 // Now cancel the pending ReadIfReady().
564 connecting_socket->CancelReadIfReady();
565
566 // Send data to |connecting_socket|.
567 const char kMsg[] = "hello!";
568 scoped_refptr<StringIOBuffer> write_buffer =
569 base::MakeRefCounted<StringIOBuffer>(kMsg);
570
571 TestCompletionCallback write_callback;
572 int write_result = accepted_socket->Write(write_buffer.get(), strlen(kMsg),
573 write_callback.callback(),
574 TRAFFIC_ANNOTATION_FOR_TESTS);
575 const int msg_size = strlen(kMsg);
576 ASSERT_EQ(msg_size, write_result);
577
Helen Lia6d3b2c2018-05-08 16:09:07578 TestCompletionCallback read_callback2;
579 int read_result = connecting_socket->ReadIfReady(
580 read_buffer.get(), read_buffer->size(), read_callback2.callback());
Wez1c67dcbe2018-05-09 10:48:34581 if (read_result == ERR_IO_PENDING) {
582 ASSERT_EQ(OK, read_callback2.GetResult(read_result));
583 read_result = connecting_socket->ReadIfReady(
584 read_buffer.get(), read_buffer->size(), read_callback2.callback());
585 }
Helen Lia6d3b2c2018-05-08 16:09:07586
Wez1c67dcbe2018-05-09 10:48:34587 ASSERT_EQ(msg_size, read_result);
Helen Lia6d3b2c2018-05-08 16:09:07588 ASSERT_EQ(0, memcmp(&kMsg, read_buffer->data(), msg_size));
589}
590
tbansal7b403bcc2016-04-13 22:33:21591// These tests require kernel support for tcp_info struct, and so they are
592// enabled only on certain platforms.
593#if defined(TCP_INFO) || defined(OS_LINUX)
594// If SocketPerformanceWatcher::ShouldNotifyUpdatedRTT always returns false,
595// then the wtatcher should not receive any notifications.
596TEST_F(TCPSocketTest, SPWNotInterested) {
tbansal180587c2017-02-16 15:13:23597 TestSPWNotifications(false, 2u, 0u, 0u);
tbansal7b403bcc2016-04-13 22:33:21598}
599
Achuith Bhandarkar7f920f82018-08-14 18:56:21600#if defined(OS_CHROMEOS)
601// https://crbug.com/873851.
602#define MAYBE_SPWNoAdvance DISABLED_SPWNoAdvance
603#else
604#define MAYBE_SPWNoAdvance SPWNoAdvance
605#endif
tbansal7b403bcc2016-04-13 22:33:21606// One notification should be received when the socket connects. One
tbansal180587c2017-02-16 15:13:23607// additional notification should be received for each message read.
Achuith Bhandarkar7f920f82018-08-14 18:56:21608TEST_F(TCPSocketTest, MAYBE_SPWNoAdvance) {
tbansal180587c2017-02-16 15:13:23609 TestSPWNotifications(true, 2u, 0u, 3u);
tbansal7b403bcc2016-04-13 22:33:21610}
611#endif // defined(TCP_INFO) || defined(OS_LINUX)
612
Paul Jensen0f49dec2017-12-12 23:39:58613// On Android, where socket tagging is supported, verify that TCPSocket::Tag
614// works as expected.
615#if defined(OS_ANDROID)
616TEST_F(TCPSocketTest, Tag) {
617 // Start test server.
618 EmbeddedTestServer test_server;
619 test_server.AddDefaultHandlers(base::FilePath());
620 ASSERT_TRUE(test_server.Start());
621
622 AddressList addr_list;
623 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
624 EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
625
626 // Verify TCP connect packets are tagged and counted properly.
627 int32_t tag_val1 = 0x12345678;
628 uint64_t old_traffic = GetTaggedBytes(tag_val1);
629 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
630 socket_.ApplySocketTag(tag1);
631 TestCompletionCallback connect_callback;
632 int connect_result =
633 socket_.Connect(addr_list[0], connect_callback.callback());
634 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
635 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
636
637 // Verify socket can be retagged with a new value and the current process's
638 // UID.
639 int32_t tag_val2 = 0x87654321;
640 old_traffic = GetTaggedBytes(tag_val2);
641 SocketTag tag2(getuid(), tag_val2);
642 socket_.ApplySocketTag(tag2);
Paul Jensen8d6f87ec2018-01-13 00:46:54643 const char kRequest1[] = "GET / HTTP/1.0";
Victor Costan9c7302b2018-08-27 16:39:44644 scoped_refptr<IOBuffer> write_buffer1 =
645 base::MakeRefCounted<StringIOBuffer>(kRequest1);
Paul Jensen0f49dec2017-12-12 23:39:58646 TestCompletionCallback write_callback1;
647 EXPECT_EQ(
648 socket_.Write(write_buffer1.get(), strlen(kRequest1),
649 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54650 static_cast<int>(strlen(kRequest1)));
Paul Jensen0f49dec2017-12-12 23:39:58651 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
652
653 // Verify socket can be retagged with a new value and the current process's
654 // UID.
655 old_traffic = GetTaggedBytes(tag_val1);
656 socket_.ApplySocketTag(tag1);
657 const char kRequest2[] = "\n\n";
Victor Costan9c7302b2018-08-27 16:39:44658 scoped_refptr<IOBuffer> write_buffer2 =
659 base::MakeRefCounted<StringIOBuffer>(kRequest2);
Paul Jensen0f49dec2017-12-12 23:39:58660 TestCompletionCallback write_callback2;
661 EXPECT_EQ(
662 socket_.Write(write_buffer2.get(), strlen(kRequest2),
663 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54664 static_cast<int>(strlen(kRequest2)));
Paul Jensen0f49dec2017-12-12 23:39:58665 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
666
667 socket_.Close();
668}
669
670TEST_F(TCPSocketTest, TagAfterConnect) {
671 // Start test server.
672 EmbeddedTestServer test_server;
673 test_server.AddDefaultHandlers(base::FilePath());
674 ASSERT_TRUE(test_server.Start());
675
676 AddressList addr_list;
677 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
678 EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
679
680 // Connect socket.
681 TestCompletionCallback connect_callback;
682 int connect_result =
683 socket_.Connect(addr_list[0], connect_callback.callback());
684 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
685
686 // Verify socket can be tagged with a new value and the current process's
687 // UID.
688 int32_t tag_val2 = 0x87654321;
689 uint64_t old_traffic = GetTaggedBytes(tag_val2);
690 SocketTag tag2(getuid(), tag_val2);
691 socket_.ApplySocketTag(tag2);
Paul Jensen8d6f87ec2018-01-13 00:46:54692 const char kRequest1[] = "GET / HTTP/1.0";
Victor Costan9c7302b2018-08-27 16:39:44693 scoped_refptr<IOBuffer> write_buffer1 =
694 base::MakeRefCounted<StringIOBuffer>(kRequest1);
Paul Jensen0f49dec2017-12-12 23:39:58695 TestCompletionCallback write_callback1;
696 EXPECT_EQ(
697 socket_.Write(write_buffer1.get(), strlen(kRequest1),
698 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54699 static_cast<int>(strlen(kRequest1)));
Paul Jensen0f49dec2017-12-12 23:39:58700 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
701
702 // Verify socket can be retagged with a new value and the current process's
703 // UID.
704 int32_t tag_val1 = 0x12345678;
705 old_traffic = GetTaggedBytes(tag_val1);
706 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
707 socket_.ApplySocketTag(tag1);
708 const char kRequest2[] = "\n\n";
Victor Costan9c7302b2018-08-27 16:39:44709 scoped_refptr<IOBuffer> write_buffer2 =
710 base::MakeRefCounted<StringIOBuffer>(kRequest2);
Paul Jensen0f49dec2017-12-12 23:39:58711 TestCompletionCallback write_callback2;
712 EXPECT_EQ(
713 socket_.Write(write_buffer2.get(), strlen(kRequest2),
714 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54715 static_cast<int>(strlen(kRequest2)));
Paul Jensen0f49dec2017-12-12 23:39:58716 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
717
718 socket_.Close();
719}
720#endif
721
[email protected]21160f02013-09-01 23:04:27722} // namespace
723} // namespace net