[go: nahoru, domu]

blob: 359426d86db5e59de72cecc8c0ed8dbfbe3bb596 [file] [log] [blame]
yzshen@chromium.org21160f02013-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
tbansal7b403bc2016-04-13 22:33:217#include <stddef.h>
yzshen@chromium.orgc9080d82013-09-15 15:14:168#include <string.h>
yzshen@chromium.org21160f02013-09-01 23:04:279
danakj655b66c2016-04-16 00:51:3810#include <memory>
yzshen@chromium.orgc9080d82013-09-15 15:14:1611#include <string>
12#include <vector>
13
14#include "base/memory/ref_counted.h"
Matt Menkeb92dda2dd2018-09-18 17:04:4215#include "base/test/bind_test_util.h"
tbansal7b403bc2016-04-13 22:33:2116#include "base/time/time.h"
Paul Jensen0f49dec2017-12-12 23:39:5817#include "build/build_config.h"
yzshen@chromium.org21160f02013-09-01 23:04:2718#include "net/base/address_list.h"
yzshen@chromium.orgc9080d82013-09-15 15:14:1619#include "net/base/io_buffer.h"
yzshen@chromium.org21160f02013-09-01 23:04:2720#include "net/base/ip_endpoint.h"
21#include "net/base/net_errors.h"
tfarina3d87d7cd2016-01-13 02:26:5922#include "net/base/sockaddr_storage.h"
yzshen@chromium.org21160f02013-09-01 23:04:2723#include "net/base/test_completion_callback.h"
mikecironef22f9812016-10-04 03:40:1924#include "net/log/net_log_source.h"
Wezd1742132019-01-18 02:50:4625#include "net/socket/socket_descriptor.h"
tbansalca83c002016-04-28 20:56:2826#include "net/socket/socket_performance_watcher.h"
Paul Jensen0f49dec2017-12-12 23:39:5827#include "net/socket/socket_test_util.h"
yzshen@chromium.org21160f02013-09-01 23:04:2728#include "net/socket/tcp_client_socket.h"
Paul Jensen0f49dec2017-12-12 23:39:5829#include "net/test/embedded_test_server/embedded_test_server.h"
robpercival214763f2016-07-01 23:27:0130#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0131#include "net/test/test_with_scoped_task_environment.h"
rhalavati@google.com690bbea2017-12-08 09:05:4632#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0133#include "testing/gmock/include/gmock/gmock.h"
yzshen@chromium.org21160f02013-09-01 23:04:2734#include "testing/gtest/include/gtest/gtest.h"
35#include "testing/platform_test.h"
36
Matt Menkeb92dda2dd2018-09-18 17:04:4237// For getsockopt() call.
38#if defined(OS_WIN)
39#include <winsock2.h>
40#else // !defined(OS_WIN)
41#include <sys/socket.h>
42#endif // !defined(OS_WIN)
43
Sergey Ulanov7cbcbc52017-07-26 18:29:1344using net::test::IsError;
robpercival214763f2016-07-01 23:27:0145using net::test::IsOk;
46
yzshen@chromium.org21160f02013-09-01 23:04:2747namespace net {
48
49namespace {
tbansal7b403bc2016-04-13 22:33:2150
Matt Menkee06732012018-04-06 21:41:2451// IOBuffer with the ability to invoke a callback when destroyed. Useful for
52// checking for leaks.
53class IOBufferWithDestructionCallback : public IOBufferWithSize {
54 public:
55 explicit IOBufferWithDestructionCallback(base::OnceClosure on_destroy_closure)
56 : IOBufferWithSize(1024),
57 on_destroy_closure_(std::move(on_destroy_closure)) {
58 DCHECK(on_destroy_closure_);
59 }
60
61 protected:
62 ~IOBufferWithDestructionCallback() override {
63 std::move(on_destroy_closure_).Run();
64 }
65
66 base::OnceClosure on_destroy_closure_;
67};
68
tbansal7b403bc2016-04-13 22:33:2169class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
70 public:
71 explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt)
72 : should_notify_updated_rtt_(should_notify_updated_rtt),
73 connection_changed_count_(0u),
74 rtt_notification_count_(0u) {}
Chris Watkins7a41d3552017-12-01 02:13:2775 ~TestSocketPerformanceWatcher() override = default;
tbansal7b403bc2016-04-13 22:33:2176
77 bool ShouldNotifyUpdatedRTT() const override {
78 return should_notify_updated_rtt_;
79 }
80
81 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
82 rtt_notification_count_++;
83 }
84
85 void OnConnectionChanged() override { connection_changed_count_++; }
86
87 size_t rtt_notification_count() const { return rtt_notification_count_; }
88
89 size_t connection_changed_count() const { return connection_changed_count_; }
90
91 private:
92 const bool should_notify_updated_rtt_;
93 size_t connection_changed_count_;
94 size_t rtt_notification_count_;
95
96 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
97};
98
yzshen@chromium.org21160f02013-09-01 23:04:2799const int kListenBacklog = 5;
100
Bence Béky98447b12018-05-08 03:14:01101class TCPSocketTest : public PlatformTest, public WithScopedTaskEnvironment {
yzshen@chromium.org21160f02013-09-01 23:04:27102 protected:
Sergey Ulanov7cbcbc52017-07-26 18:29:13103 TCPSocketTest() : socket_(nullptr, nullptr, NetLogSource()) {}
yzshen@chromium.org21160f02013-09-01 23:04:27104
105 void SetUpListenIPv4() {
robpercival214763f2016-07-01 23:27:01106 ASSERT_THAT(socket_.Open(ADDRESS_FAMILY_IPV4), IsOk());
107 ASSERT_THAT(socket_.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)),
108 IsOk());
109 ASSERT_THAT(socket_.Listen(kListenBacklog), IsOk());
110 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27111 }
112
113 void SetUpListenIPv6(bool* success) {
114 *success = false;
yzshen@chromium.org21160f02013-09-01 23:04:27115
yzshen@chromium.orgc9080d82013-09-15 15:14:16116 if (socket_.Open(ADDRESS_FAMILY_IPV6) != OK ||
martijna2e83bd2016-03-18 13:10:45117 socket_.Bind(IPEndPoint(IPAddress::IPv6Localhost(), 0)) != OK ||
yzshen@chromium.org21160f02013-09-01 23:04:27118 socket_.Listen(kListenBacklog) != OK) {
119 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
120 "disabled. Skipping the test";
121 return;
122 }
robpercival214763f2016-07-01 23:27:01123 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27124 *success = true;
125 }
126
xiyuan@chromium.orgef2f0022014-04-29 10:24:35127 void TestAcceptAsync() {
128 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38129 std::unique_ptr<TCPSocket> accepted_socket;
xiyuan@chromium.orgef2f0022014-04-29 10:24:35130 IPEndPoint accepted_address;
Sergey Ulanov7cbcbc52017-07-26 18:29:13131 ASSERT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
132 accept_callback.callback()),
133 IsError(ERR_IO_PENDING));
xiyuan@chromium.orgef2f0022014-04-29 10:24:35134
135 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13136 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19137 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13138 int connect_result = connecting_socket.Connect(connect_callback.callback());
139 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
xiyuan@chromium.orgef2f0022014-04-29 10:24:35140
robpercival214763f2016-07-01 23:27:01141 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
xiyuan@chromium.orgef2f0022014-04-29 10:24:35142
143 EXPECT_TRUE(accepted_socket.get());
144
145 // Both sockets should be on the loopback network interface.
146 EXPECT_EQ(accepted_address.address(), local_address_.address());
147 }
148
tbansal7b403bc2016-04-13 22:33:21149#if defined(TCP_INFO) || defined(OS_LINUX)
150 // Tests that notifications to Socket Performance Watcher (SPW) are delivered
tbansal180587c2017-02-16 15:13:23151 // correctly. |should_notify_updated_rtt| is true if the SPW is interested in
152 // receiving RTT notifications. |num_messages| is the number of messages that
153 // are written/read by the sockets. |expect_connection_changed_count| is the
154 // expected number of connection change notifications received by the SPW.
155 // |expect_rtt_notification_count| is the expected number of RTT
156 // notifications received by the SPW. This test works by writing
157 // |num_messages| to the socket. A different socket (with a SPW attached to
158 // it) reads the messages.
159 void TestSPWNotifications(bool should_notify_updated_rtt,
tbansal7b403bc2016-04-13 22:33:21160 size_t num_messages,
161 size_t expect_connection_changed_count,
162 size_t expect_rtt_notification_count) {
163 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
164
tbansal7b403bc2016-04-13 22:33:21165 TestCompletionCallback connect_callback;
166
danakj655b66c2016-04-16 00:51:38167 std::unique_ptr<TestSocketPerformanceWatcher> watcher(
tbansal7b403bc2016-04-13 22:33:21168 new TestSocketPerformanceWatcher(should_notify_updated_rtt));
169 TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
170
Sergey Ulanov7cbcbc52017-07-26 18:29:13171 TCPSocket connecting_socket(std::move(watcher), nullptr, NetLogSource());
tbansal7b403bc2016-04-13 22:33:21172
173 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
robpercival214763f2016-07-01 23:27:01174 ASSERT_THAT(result, IsOk());
Sergey Ulanov7cbcbc52017-07-26 18:29:13175 int connect_result =
176 connecting_socket.Connect(local_address_, connect_callback.callback());
tbansal7b403bc2016-04-13 22:33:21177
178 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38179 std::unique_ptr<TCPSocket> accepted_socket;
tbansal7b403bc2016-04-13 22:33:21180 IPEndPoint accepted_address;
181 result = socket_.Accept(&accepted_socket, &accepted_address,
182 accept_callback.callback());
robpercival214763f2016-07-01 23:27:01183 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
tbansal7b403bc2016-04-13 22:33:21184
185 ASSERT_TRUE(accepted_socket.get());
186
187 // Both sockets should be on the loopback network interface.
188 EXPECT_EQ(accepted_address.address(), local_address_.address());
189
Sergey Ulanov7cbcbc52017-07-26 18:29:13190 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
tbansal7b403bc2016-04-13 22:33:21191
192 for (size_t i = 0; i < num_messages; ++i) {
tbansal7b403bc2016-04-13 22:33:21193 // Use a 1 byte message so that the watcher is notified at most once per
194 // message.
195 const std::string message("t");
196
Victor Costan9c7302b2018-08-27 16:39:44197 scoped_refptr<IOBufferWithSize> write_buffer =
198 base::MakeRefCounted<IOBufferWithSize>(message.size());
tbansal7b403bc2016-04-13 22:33:21199 memmove(write_buffer->data(), message.data(), message.size());
200
201 TestCompletionCallback write_callback;
202 int write_result = accepted_socket->Write(
rhalavati@google.com690bbea2017-12-08 09:05:46203 write_buffer.get(), write_buffer->size(), write_callback.callback(),
204 TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal7b403bc2016-04-13 22:33:21205
Victor Costan9c7302b2018-08-27 16:39:44206 scoped_refptr<IOBufferWithSize> read_buffer =
207 base::MakeRefCounted<IOBufferWithSize>(message.size());
tbansal7b403bc2016-04-13 22:33:21208 TestCompletionCallback read_callback;
209 int read_result = connecting_socket.Read(
210 read_buffer.get(), read_buffer->size(), read_callback.callback());
211
212 ASSERT_EQ(1, write_callback.GetResult(write_result));
213 ASSERT_EQ(1, read_callback.GetResult(read_result));
214 }
215 EXPECT_EQ(expect_connection_changed_count,
216 watcher_ptr->connection_changed_count());
217 EXPECT_EQ(expect_rtt_notification_count,
218 watcher_ptr->rtt_notification_count());
219 }
220#endif // defined(TCP_INFO) || defined(OS_LINUX)
221
yzshen@chromium.org21160f02013-09-01 23:04:27222 AddressList local_address_list() const {
223 return AddressList(local_address_);
224 }
225
226 TCPSocket socket_;
227 IPEndPoint local_address_;
228};
229
230// Test listening and accepting with a socket bound to an IPv4 address.
231TEST_F(TCPSocketTest, Accept) {
232 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
233
234 TestCompletionCallback connect_callback;
235 // TODO(yzshen): Switch to use TCPSocket when it supports client socket
236 // operations.
Sergey Ulanov7cbcbc52017-07-26 18:29:13237 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19238 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13239 int connect_result = connecting_socket.Connect(connect_callback.callback());
yzshen@chromium.org21160f02013-09-01 23:04:27240
241 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38242 std::unique_ptr<TCPSocket> accepted_socket;
yzshen@chromium.org21160f02013-09-01 23:04:27243 IPEndPoint accepted_address;
244 int result = socket_.Accept(&accepted_socket, &accepted_address,
245 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13246 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27247
248 EXPECT_TRUE(accepted_socket.get());
249
250 // Both sockets should be on the loopback network interface.
251 EXPECT_EQ(accepted_address.address(), local_address_.address());
252
Sergey Ulanov7cbcbc52017-07-26 18:29:13253 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27254}
255
256// Test Accept() callback.
257TEST_F(TCPSocketTest, AcceptAsync) {
258 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
xiyuan@chromium.orgef2f0022014-04-29 10:24:35259 TestAcceptAsync();
yzshen@chromium.org21160f02013-09-01 23:04:27260}
261
rvera26f0a1392017-05-02 22:25:44262// Test AdoptConnectedSocket()
263TEST_F(TCPSocketTest, AdoptConnectedSocket) {
Sergey Ulanov7cbcbc52017-07-26 18:29:13264 TCPSocket accepting_socket(nullptr, nullptr, NetLogSource());
rvera26f0a1392017-05-02 22:25:44265 ASSERT_THAT(accepting_socket.Open(ADDRESS_FAMILY_IPV4), IsOk());
266 ASSERT_THAT(accepting_socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)),
267 IsOk());
268 ASSERT_THAT(accepting_socket.GetLocalAddress(&local_address_), IsOk());
269 ASSERT_THAT(accepting_socket.Listen(kListenBacklog), IsOk());
270
271 TestCompletionCallback connect_callback;
272 // TODO(yzshen): Switch to use TCPSocket when it supports client socket
273 // operations.
Sergey Ulanov7cbcbc52017-07-26 18:29:13274 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
rvera26f0a1392017-05-02 22:25:44275 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13276 int connect_result = connecting_socket.Connect(connect_callback.callback());
rvera26f0a1392017-05-02 22:25:44277
278 TestCompletionCallback accept_callback;
279 std::unique_ptr<TCPSocket> accepted_socket;
280 IPEndPoint accepted_address;
281 int result = accepting_socket.Accept(&accepted_socket, &accepted_address,
282 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13283 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
rvera26f0a1392017-05-02 22:25:44284
285 SocketDescriptor accepted_descriptor =
286 accepted_socket->ReleaseSocketDescriptorForTesting();
287
288 ASSERT_THAT(
289 socket_.AdoptConnectedSocket(accepted_descriptor, accepted_address),
290 IsOk());
291
292 // socket_ should now have the local address.
293 IPEndPoint adopted_address;
294 ASSERT_THAT(socket_.GetLocalAddress(&adopted_address), IsOk());
295 EXPECT_EQ(local_address_.address(), adopted_address.address());
296
Sergey Ulanov7cbcbc52017-07-26 18:29:13297 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
rvera26f0a1392017-05-02 22:25:44298}
299
300// Test Accept() for AdoptUnconnectedSocket.
301TEST_F(TCPSocketTest, AcceptForAdoptedUnconnectedSocket) {
302 SocketDescriptor existing_socket =
303 CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
304 ASSERT_THAT(socket_.AdoptUnconnectedSocket(existing_socket), IsOk());
xiyuan@chromium.orgef2f0022014-04-29 10:24:35305
martijna2e83bd2016-03-18 13:10:45306 IPEndPoint address(IPAddress::IPv4Localhost(), 0);
xiyuan@chromium.orgef2f0022014-04-29 10:24:35307 SockaddrStorage storage;
308 ASSERT_TRUE(address.ToSockAddr(storage.addr, &storage.addr_len));
309 ASSERT_EQ(0, bind(existing_socket, storage.addr, storage.addr_len));
310
robpercival214763f2016-07-01 23:27:01311 ASSERT_THAT(socket_.Listen(kListenBacklog), IsOk());
312 ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
xiyuan@chromium.orgef2f0022014-04-29 10:24:35313
314 TestAcceptAsync();
315}
xiyuan@chromium.orgef2f0022014-04-29 10:24:35316
yzshen@chromium.org21160f02013-09-01 23:04:27317// Accept two connections simultaneously.
318TEST_F(TCPSocketTest, Accept2Connections) {
319 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
320
321 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38322 std::unique_ptr<TCPSocket> accepted_socket;
yzshen@chromium.org21160f02013-09-01 23:04:27323 IPEndPoint accepted_address;
324
Sergey Ulanov7cbcbc52017-07-26 18:29:13325 ASSERT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
326 accept_callback.callback()),
327 IsError(ERR_IO_PENDING));
yzshen@chromium.org21160f02013-09-01 23:04:27328
329 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13330 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19331 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13332 int connect_result = connecting_socket.Connect(connect_callback.callback());
yzshen@chromium.org21160f02013-09-01 23:04:27333
334 TestCompletionCallback connect_callback2;
Sergey Ulanov7cbcbc52017-07-26 18:29:13335 TCPClientSocket connecting_socket2(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19336 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13337 int connect_result2 =
338 connecting_socket2.Connect(connect_callback2.callback());
yzshen@chromium.org21160f02013-09-01 23:04:27339
robpercival214763f2016-07-01 23:27:01340 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27341
342 TestCompletionCallback accept_callback2;
danakj655b66c2016-04-16 00:51:38343 std::unique_ptr<TCPSocket> accepted_socket2;
yzshen@chromium.org21160f02013-09-01 23:04:27344 IPEndPoint accepted_address2;
345
346 int result = socket_.Accept(&accepted_socket2, &accepted_address2,
347 accept_callback2.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13348 ASSERT_THAT(accept_callback2.GetResult(result), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27349
Sergey Ulanov7cbcbc52017-07-26 18:29:13350 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
351 EXPECT_THAT(connect_callback2.GetResult(connect_result2), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27352
353 EXPECT_TRUE(accepted_socket.get());
354 EXPECT_TRUE(accepted_socket2.get());
355 EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
356
357 EXPECT_EQ(accepted_address.address(), local_address_.address());
358 EXPECT_EQ(accepted_address2.address(), local_address_.address());
359}
360
361// Test listening and accepting with a socket bound to an IPv6 address.
362TEST_F(TCPSocketTest, AcceptIPv6) {
363 bool initialized = false;
364 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized));
365 if (!initialized)
366 return;
367
368 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13369 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
mikecironef22f9812016-10-04 03:40:19370 NetLogSource());
Sergey Ulanov7cbcbc52017-07-26 18:29:13371 int connect_result = connecting_socket.Connect(connect_callback.callback());
yzshen@chromium.org21160f02013-09-01 23:04:27372
373 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38374 std::unique_ptr<TCPSocket> accepted_socket;
yzshen@chromium.org21160f02013-09-01 23:04:27375 IPEndPoint accepted_address;
376 int result = socket_.Accept(&accepted_socket, &accepted_address,
377 accept_callback.callback());
Sergey Ulanov7cbcbc52017-07-26 18:29:13378 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27379
380 EXPECT_TRUE(accepted_socket.get());
381
382 // Both sockets should be on the loopback network interface.
383 EXPECT_EQ(accepted_address.address(), local_address_.address());
384
Sergey Ulanov7cbcbc52017-07-26 18:29:13385 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
yzshen@chromium.org21160f02013-09-01 23:04:27386}
387
yzshen@chromium.orgc9080d82013-09-15 15:14:16388TEST_F(TCPSocketTest, ReadWrite) {
389 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
390
391 TestCompletionCallback connect_callback;
Sergey Ulanov7cbcbc52017-07-26 18:29:13392 TCPSocket connecting_socket(nullptr, nullptr, NetLogSource());
yzshen@chromium.orgc9080d82013-09-15 15:14:16393 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
robpercival214763f2016-07-01 23:27:01394 ASSERT_THAT(result, IsOk());
Sergey Ulanov7cbcbc52017-07-26 18:29:13395 int connect_result =
396 connecting_socket.Connect(local_address_, connect_callback.callback());
yzshen@chromium.orgc9080d82013-09-15 15:14:16397
398 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:38399 std::unique_ptr<TCPSocket> accepted_socket;
yzshen@chromium.orgc9080d82013-09-15 15:14:16400 IPEndPoint accepted_address;
401 result = socket_.Accept(&accepted_socket, &accepted_address,
402 accept_callback.callback());
robpercival214763f2016-07-01 23:27:01403 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
yzshen@chromium.orgc9080d82013-09-15 15:14:16404
405 ASSERT_TRUE(accepted_socket.get());
406
407 // Both sockets should be on the loopback network interface.
408 EXPECT_EQ(accepted_address.address(), local_address_.address());
409
Sergey Ulanov7cbcbc52017-07-26 18:29:13410 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
yzshen@chromium.orgc9080d82013-09-15 15:14:16411
412 const std::string message("test message");
413 std::vector<char> buffer(message.size());
414
415 size_t bytes_written = 0;
416 while (bytes_written < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44417 scoped_refptr<IOBufferWithSize> write_buffer =
418 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_written);
yzshen@chromium.orgc9080d82013-09-15 15:14:16419 memmove(write_buffer->data(), message.data() + bytes_written,
420 message.size() - bytes_written);
421
422 TestCompletionCallback write_callback;
423 int write_result = accepted_socket->Write(
rhalavati@google.com690bbea2017-12-08 09:05:46424 write_buffer.get(), write_buffer->size(), write_callback.callback(),
425 TRAFFIC_ANNOTATION_FOR_TESTS);
yzshen@chromium.orgc9080d82013-09-15 15:14:16426 write_result = write_callback.GetResult(write_result);
427 ASSERT_TRUE(write_result >= 0);
428 bytes_written += write_result;
429 ASSERT_TRUE(bytes_written <= message.size());
430 }
431
432 size_t bytes_read = 0;
433 while (bytes_read < message.size()) {
Victor Costan9c7302b2018-08-27 16:39:44434 scoped_refptr<IOBufferWithSize> read_buffer =
435 base::MakeRefCounted<IOBufferWithSize>(message.size() - bytes_read);
yzshen@chromium.orgc9080d82013-09-15 15:14:16436 TestCompletionCallback read_callback;
437 int read_result = connecting_socket.Read(
438 read_buffer.get(), read_buffer->size(), read_callback.callback());
439 read_result = read_callback.GetResult(read_result);
440 ASSERT_TRUE(read_result >= 0);
441 ASSERT_TRUE(bytes_read + read_result <= message.size());
442 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
443 bytes_read += read_result;
444 }
445
446 std::string received_message(buffer.begin(), buffer.end());
447 ASSERT_EQ(message, received_message);
448}
449
Matt Menkee06732012018-04-06 21:41:24450// Destroy a TCPSocket while there's a pending read, and make sure the read
451// IOBuffer that the socket was holding on to is destroyed.
452// See https://crbug.com/804868.
453TEST_F(TCPSocketTest, DestroyWithPendingRead) {
454 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
455
456 // Create a connected socket.
457
458 TestCompletionCallback connect_callback;
459 std::unique_ptr<TCPSocket> connecting_socket =
460 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
461 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
462 ASSERT_THAT(result, IsOk());
463 int connect_result =
464 connecting_socket->Connect(local_address_, connect_callback.callback());
465
466 TestCompletionCallback accept_callback;
467 std::unique_ptr<TCPSocket> accepted_socket;
468 IPEndPoint accepted_address;
469 result = socket_.Accept(&accepted_socket, &accepted_address,
470 accept_callback.callback());
471 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
472 ASSERT_TRUE(accepted_socket.get());
473 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
474
475 // Try to read from the socket, but never write anything to the other end.
476 base::RunLoop run_loop;
477 scoped_refptr<IOBufferWithDestructionCallback> read_buffer(
478 base::MakeRefCounted<IOBufferWithDestructionCallback>(
479 run_loop.QuitClosure()));
480 TestCompletionCallback read_callback;
481 EXPECT_EQ(ERR_IO_PENDING,
482 connecting_socket->Read(read_buffer.get(), read_buffer->size(),
483 read_callback.callback()));
484
485 // Release the handle to the read buffer and destroy the socket. Make sure the
486 // read buffer is destroyed.
487 read_buffer = nullptr;
488 connecting_socket.reset();
489 run_loop.Run();
490}
491
492// Destroy a TCPSocket while there's a pending write, and make sure the write
493// IOBuffer that the socket was holding on to is destroyed.
494TEST_F(TCPSocketTest, DestroyWithPendingWrite) {
495 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
496
497 // Create a connected socket.
498
499 TestCompletionCallback connect_callback;
500 std::unique_ptr<TCPSocket> connecting_socket =
501 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
502 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
503 ASSERT_THAT(result, IsOk());
504 int connect_result =
505 connecting_socket->Connect(local_address_, connect_callback.callback());
506
507 TestCompletionCallback accept_callback;
508 std::unique_ptr<TCPSocket> accepted_socket;
509 IPEndPoint accepted_address;
510 result = socket_.Accept(&accepted_socket, &accepted_address,
511 accept_callback.callback());
512 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
513 ASSERT_TRUE(accepted_socket.get());
514 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
515
516 // Repeatedly write to the socket until an operation does not complete
517 // synchronously.
518 base::RunLoop run_loop;
519 scoped_refptr<IOBufferWithDestructionCallback> write_buffer(
520 base::MakeRefCounted<IOBufferWithDestructionCallback>(
521 run_loop.QuitClosure()));
522 memset(write_buffer->data(), '1', write_buffer->size());
523 TestCompletionCallback write_callback;
524 while (true) {
525 int result = connecting_socket->Write(
526 write_buffer.get(), write_buffer->size(), write_callback.callback(),
527 TRAFFIC_ANNOTATION_FOR_TESTS);
528 if (result == ERR_IO_PENDING)
529 break;
530 ASSERT_LT(0, result);
531 }
532
533 // Release the handle to the read buffer and destroy the socket. Make sure the
534 // write buffer is destroyed.
535 write_buffer = nullptr;
536 connecting_socket.reset();
537 run_loop.Run();
538}
539
Helen Lia6d3b2c2018-05-08 16:09:07540// If a ReadIfReady is pending, it's legal to cancel it and start reading later.
541TEST_F(TCPSocketTest, CancelPendingReadIfReady) {
542 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
543
544 // Create a connected socket.
545 TestCompletionCallback connect_callback;
546 std::unique_ptr<TCPSocket> connecting_socket =
547 std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
548 int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
549 ASSERT_THAT(result, IsOk());
550 int connect_result =
551 connecting_socket->Connect(local_address_, connect_callback.callback());
552
553 TestCompletionCallback accept_callback;
554 std::unique_ptr<TCPSocket> accepted_socket;
555 IPEndPoint accepted_address;
556 result = socket_.Accept(&accepted_socket, &accepted_address,
557 accept_callback.callback());
558 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
559 ASSERT_TRUE(accepted_socket.get());
560 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
561
562 // Try to read from the socket, but never write anything to the other end.
563 base::RunLoop run_loop;
564 scoped_refptr<IOBufferWithDestructionCallback> read_buffer(
565 base::MakeRefCounted<IOBufferWithDestructionCallback>(
566 run_loop.QuitClosure()));
567 TestCompletionCallback read_callback;
568 EXPECT_EQ(ERR_IO_PENDING, connecting_socket->ReadIfReady(
569 read_buffer.get(), read_buffer->size(),
570 read_callback.callback()));
571
572 // Now cancel the pending ReadIfReady().
573 connecting_socket->CancelReadIfReady();
574
575 // Send data to |connecting_socket|.
576 const char kMsg[] = "hello!";
577 scoped_refptr<StringIOBuffer> write_buffer =
578 base::MakeRefCounted<StringIOBuffer>(kMsg);
579
580 TestCompletionCallback write_callback;
581 int write_result = accepted_socket->Write(write_buffer.get(), strlen(kMsg),
582 write_callback.callback(),
583 TRAFFIC_ANNOTATION_FOR_TESTS);
584 const int msg_size = strlen(kMsg);
585 ASSERT_EQ(msg_size, write_result);
586
Helen Lia6d3b2c2018-05-08 16:09:07587 TestCompletionCallback read_callback2;
588 int read_result = connecting_socket->ReadIfReady(
589 read_buffer.get(), read_buffer->size(), read_callback2.callback());
Wez1c67dcbe2018-05-09 10:48:34590 if (read_result == ERR_IO_PENDING) {
591 ASSERT_EQ(OK, read_callback2.GetResult(read_result));
592 read_result = connecting_socket->ReadIfReady(
593 read_buffer.get(), read_buffer->size(), read_callback2.callback());
594 }
Helen Lia6d3b2c2018-05-08 16:09:07595
Wez1c67dcbe2018-05-09 10:48:34596 ASSERT_EQ(msg_size, read_result);
Helen Lia6d3b2c2018-05-08 16:09:07597 ASSERT_EQ(0, memcmp(&kMsg, read_buffer->data(), msg_size));
598}
599
Wezd1742132019-01-18 02:50:46600TEST_F(TCPSocketTest, IsConnected) {
Wez372b03422019-01-12 00:09:47601 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
602
603 TestCompletionCallback accept_callback;
604 std::unique_ptr<TCPSocket> accepted_socket;
605 IPEndPoint accepted_address;
606 EXPECT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
607 accept_callback.callback()),
608 IsError(ERR_IO_PENDING));
609
610 TestCompletionCallback connect_callback;
611 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
612 NetLogSource());
613
614 // Immediately after creation, the socket should not be connected.
615 EXPECT_FALSE(connecting_socket.IsConnected());
616 EXPECT_FALSE(connecting_socket.IsConnectedAndIdle());
617
618 int connect_result = connecting_socket.Connect(connect_callback.callback());
619 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
620 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
621
622 // |connecting_socket| and |accepted_socket| should now both be reported as
623 // connected, and idle
624 EXPECT_TRUE(accepted_socket->IsConnected());
625 EXPECT_TRUE(accepted_socket->IsConnectedAndIdle());
626 EXPECT_TRUE(connecting_socket.IsConnected());
627 EXPECT_TRUE(connecting_socket.IsConnectedAndIdle());
628
629 // Write one byte to the |accepted_socket|, then close it.
630 const char kSomeData[] = "!";
631 scoped_refptr<IOBuffer> some_data_buffer =
632 base::MakeRefCounted<StringIOBuffer>(kSomeData);
633 TestCompletionCallback write_callback;
634 EXPECT_THAT(write_callback.GetResult(accepted_socket->Write(
635 some_data_buffer.get(), 1, write_callback.callback(),
636 TRAFFIC_ANNOTATION_FOR_TESTS)),
637 1);
638 accepted_socket.reset();
639
Wezd1742132019-01-18 02:50:46640 // Wait until |connecting_socket| is signalled as having data to read.
641 fd_set read_fds;
642 FD_ZERO(&read_fds);
643 SocketDescriptor connecting_fd =
644 connecting_socket.SocketDescriptorForTesting();
645 FD_SET(connecting_fd, &read_fds);
646 ASSERT_EQ(select(FD_SETSIZE, &read_fds, nullptr, nullptr, nullptr), 1);
647 ASSERT_TRUE(FD_ISSET(connecting_fd, &read_fds));
648
649 // It should now be reported as connected, but not as idle.
Wez372b03422019-01-12 00:09:47650 EXPECT_TRUE(connecting_socket.IsConnected());
651 EXPECT_FALSE(connecting_socket.IsConnectedAndIdle());
652
653 // Read the message from |connecting_socket_|, then read the end-of-stream.
654 scoped_refptr<IOBufferWithSize> read_buffer =
655 base::MakeRefCounted<IOBufferWithSize>(2);
656 TestCompletionCallback read_callback;
657 EXPECT_THAT(
658 read_callback.GetResult(connecting_socket.Read(
659 read_buffer.get(), read_buffer->size(), read_callback.callback())),
660 1);
661 EXPECT_THAT(
662 read_callback.GetResult(connecting_socket.Read(
663 read_buffer.get(), read_buffer->size(), read_callback.callback())),
664 0);
665
666 // |connecting_socket| has no more data to read, so should noe be reported
667 // as disconnected.
668 EXPECT_FALSE(connecting_socket.IsConnected());
669 EXPECT_FALSE(connecting_socket.IsConnectedAndIdle());
670}
671
Matt Menkeb92dda2dd2018-09-18 17:04:42672// Tests that setting a socket option in the BeforeConnectCallback works. With
673// real sockets, socket options often have to be set before the connect() call,
674// and the BeforeConnectCallback is the only way to do that, with a
675// TCPClientSocket.
676TEST_F(TCPSocketTest, BeforeConnectCallback) {
677 // A receive buffer size that is between max and minimum buffer size limits,
678 // and weird enough to likely not be a default value.
679 const int kReceiveBufferSize = 32 * 1024 + 1117;
680 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
681
682 TestCompletionCallback accept_callback;
683 std::unique_ptr<TCPSocket> accepted_socket;
684 IPEndPoint accepted_address;
685 EXPECT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
686 accept_callback.callback()),
687 IsError(ERR_IO_PENDING));
688
689 TestCompletionCallback connect_callback;
690 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
691 NetLogSource());
692
693 connecting_socket.SetBeforeConnectCallback(base::BindLambdaForTesting([&] {
694 EXPECT_FALSE(connecting_socket.IsConnected());
695 int result = connecting_socket.SetReceiveBufferSize(kReceiveBufferSize);
696 EXPECT_THAT(result, IsOk());
697 return result;
698 }));
699 int connect_result = connecting_socket.Connect(connect_callback.callback());
700
701 EXPECT_THAT(accept_callback.WaitForResult(), IsOk());
702 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
703
704 int actual_size = 0;
705 socklen_t actual_size_len = sizeof(actual_size);
706 int os_result = getsockopt(
707 connecting_socket.SocketDescriptorForTesting(), SOL_SOCKET, SO_RCVBUF,
708 reinterpret_cast<char*>(&actual_size), &actual_size_len);
709 ASSERT_EQ(0, os_result);
710// Linux platforms generally allocate twice as much buffer size is requested to
711// account for internal kernel data structures.
712#if defined(OS_LINUX) || defined(OS_ANDROID)
713 EXPECT_EQ(2 * kReceiveBufferSize, actual_size);
714// Unfortunately, Apple platform behavior doesn't seem to be documented, and
715// doesn't match behavior on any other platforms.
Wez372b03422019-01-12 00:09:47716// Fuchsia doesn't currently implement SO_RCVBUF.
717#elif !defined(OS_IOS) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
Matt Menkeb92dda2dd2018-09-18 17:04:42718 EXPECT_EQ(kReceiveBufferSize, actual_size);
719#endif
720}
721
722TEST_F(TCPSocketTest, BeforeConnectCallbackFails) {
723 // Setting up a server isn't strictly necessary, but it does allow checking
724 // the server was never connected to.
725 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
726
727 TestCompletionCallback accept_callback;
728 std::unique_ptr<TCPSocket> accepted_socket;
729 IPEndPoint accepted_address;
730 EXPECT_THAT(socket_.Accept(&accepted_socket, &accepted_address,
731 accept_callback.callback()),
732 IsError(ERR_IO_PENDING));
733
734 TestCompletionCallback connect_callback;
735 TCPClientSocket connecting_socket(local_address_list(), nullptr, nullptr,
736 NetLogSource());
737
738 // Set a callback that returns a nonsensical error, and make sure it's
739 // returned.
740 connecting_socket.SetBeforeConnectCallback(base::BindRepeating(
741 [] { return static_cast<int>(net::ERR_NAME_NOT_RESOLVED); }));
742 int connect_result = connecting_socket.Connect(connect_callback.callback());
743 EXPECT_THAT(connect_callback.GetResult(connect_result),
744 IsError(net::ERR_NAME_NOT_RESOLVED));
745
746 // Best effort check that the socket wasn't accepted - may flakily pass on
747 // regression, unfortunately.
748 base::RunLoop().RunUntilIdle();
749 EXPECT_FALSE(accept_callback.have_result());
750}
751
tbansal7b403bc2016-04-13 22:33:21752// These tests require kernel support for tcp_info struct, and so they are
753// enabled only on certain platforms.
754#if defined(TCP_INFO) || defined(OS_LINUX)
755// If SocketPerformanceWatcher::ShouldNotifyUpdatedRTT always returns false,
756// then the wtatcher should not receive any notifications.
757TEST_F(TCPSocketTest, SPWNotInterested) {
tbansal180587c2017-02-16 15:13:23758 TestSPWNotifications(false, 2u, 0u, 0u);
tbansal7b403bc2016-04-13 22:33:21759}
760
761// One notification should be received when the socket connects. One
tbansal180587c2017-02-16 15:13:23762// additional notification should be received for each message read.
Asanka Herath3773b612018-10-25 19:46:22763TEST_F(TCPSocketTest, SPWNoAdvance) {
tbansal180587c2017-02-16 15:13:23764 TestSPWNotifications(true, 2u, 0u, 3u);
tbansal7b403bc2016-04-13 22:33:21765}
766#endif // defined(TCP_INFO) || defined(OS_LINUX)
767
Paul Jensen0f49dec2017-12-12 23:39:58768// On Android, where socket tagging is supported, verify that TCPSocket::Tag
769// works as expected.
770#if defined(OS_ANDROID)
771TEST_F(TCPSocketTest, Tag) {
772 // Start test server.
773 EmbeddedTestServer test_server;
774 test_server.AddDefaultHandlers(base::FilePath());
775 ASSERT_TRUE(test_server.Start());
776
777 AddressList addr_list;
778 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
779 EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
780
781 // Verify TCP connect packets are tagged and counted properly.
782 int32_t tag_val1 = 0x12345678;
783 uint64_t old_traffic = GetTaggedBytes(tag_val1);
784 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
785 socket_.ApplySocketTag(tag1);
786 TestCompletionCallback connect_callback;
787 int connect_result =
788 socket_.Connect(addr_list[0], connect_callback.callback());
789 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
790 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
791
792 // Verify socket can be retagged with a new value and the current process's
793 // UID.
794 int32_t tag_val2 = 0x87654321;
795 old_traffic = GetTaggedBytes(tag_val2);
796 SocketTag tag2(getuid(), tag_val2);
797 socket_.ApplySocketTag(tag2);
Paul Jensen8d6f87ec2018-01-13 00:46:54798 const char kRequest1[] = "GET / HTTP/1.0";
Victor Costan9c7302b2018-08-27 16:39:44799 scoped_refptr<IOBuffer> write_buffer1 =
800 base::MakeRefCounted<StringIOBuffer>(kRequest1);
Paul Jensen0f49dec2017-12-12 23:39:58801 TestCompletionCallback write_callback1;
802 EXPECT_EQ(
803 socket_.Write(write_buffer1.get(), strlen(kRequest1),
804 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54805 static_cast<int>(strlen(kRequest1)));
Paul Jensen0f49dec2017-12-12 23:39:58806 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
807
808 // Verify socket can be retagged with a new value and the current process's
809 // UID.
810 old_traffic = GetTaggedBytes(tag_val1);
811 socket_.ApplySocketTag(tag1);
812 const char kRequest2[] = "\n\n";
Victor Costan9c7302b2018-08-27 16:39:44813 scoped_refptr<IOBuffer> write_buffer2 =
814 base::MakeRefCounted<StringIOBuffer>(kRequest2);
Paul Jensen0f49dec2017-12-12 23:39:58815 TestCompletionCallback write_callback2;
816 EXPECT_EQ(
817 socket_.Write(write_buffer2.get(), strlen(kRequest2),
818 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54819 static_cast<int>(strlen(kRequest2)));
Paul Jensen0f49dec2017-12-12 23:39:58820 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
821
822 socket_.Close();
823}
824
825TEST_F(TCPSocketTest, TagAfterConnect) {
826 // Start test server.
827 EmbeddedTestServer test_server;
828 test_server.AddDefaultHandlers(base::FilePath());
829 ASSERT_TRUE(test_server.Start());
830
831 AddressList addr_list;
832 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
833 EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
834
835 // Connect socket.
836 TestCompletionCallback connect_callback;
837 int connect_result =
838 socket_.Connect(addr_list[0], connect_callback.callback());
839 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
840
841 // Verify socket can be tagged with a new value and the current process's
842 // UID.
843 int32_t tag_val2 = 0x87654321;
844 uint64_t old_traffic = GetTaggedBytes(tag_val2);
845 SocketTag tag2(getuid(), tag_val2);
846 socket_.ApplySocketTag(tag2);
Paul Jensen8d6f87ec2018-01-13 00:46:54847 const char kRequest1[] = "GET / HTTP/1.0";
Victor Costan9c7302b2018-08-27 16:39:44848 scoped_refptr<IOBuffer> write_buffer1 =
849 base::MakeRefCounted<StringIOBuffer>(kRequest1);
Paul Jensen0f49dec2017-12-12 23:39:58850 TestCompletionCallback write_callback1;
851 EXPECT_EQ(
852 socket_.Write(write_buffer1.get(), strlen(kRequest1),
853 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54854 static_cast<int>(strlen(kRequest1)));
Paul Jensen0f49dec2017-12-12 23:39:58855 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
856
857 // Verify socket can be retagged with a new value and the current process's
858 // UID.
859 int32_t tag_val1 = 0x12345678;
860 old_traffic = GetTaggedBytes(tag_val1);
861 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
862 socket_.ApplySocketTag(tag1);
863 const char kRequest2[] = "\n\n";
Victor Costan9c7302b2018-08-27 16:39:44864 scoped_refptr<IOBuffer> write_buffer2 =
865 base::MakeRefCounted<StringIOBuffer>(kRequest2);
Paul Jensen0f49dec2017-12-12 23:39:58866 TestCompletionCallback write_callback2;
867 EXPECT_EQ(
868 socket_.Write(write_buffer2.get(), strlen(kRequest2),
869 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
Paul Jensen8d6f87ec2018-01-13 00:46:54870 static_cast<int>(strlen(kRequest2)));
Paul Jensen0f49dec2017-12-12 23:39:58871 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
872
873 socket_.Close();
874}
875#endif
876
yzshen@chromium.org21160f02013-09-01 23:04:27877} // namespace
878} // namespace net