blob: d8499b44c5cebf3945bb8f4a87660af828eccabd [file] [log] [blame]
[email protected]7054e78f2012-05-07 21:44:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]03ec25382011-05-27 21:50:282// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file contains some tests for TCPClientSocket.
6// transport_client_socket_unittest.cc contans some other tests that
7// are common for TCP and other types of sockets.
8
9#include "net/socket/tcp_client_socket.h"
10
tbansal7b403bcc2016-04-13 22:33:2111#include <stddef.h>
12
martijna2e83bd2016-03-18 13:10:4513#include "net/base/ip_address.h"
[email protected]03ec25382011-05-27 21:50:2814#include "net/base/ip_endpoint.h"
15#include "net/base/net_errors.h"
[email protected]03ec25382011-05-27 21:50:2816#include "net/base/test_completion_callback.h"
tbansalca83c002016-04-28 20:56:2817#include "net/socket/socket_performance_watcher.h"
[email protected]03ec25382011-05-27 21:50:2818#include "net/socket/tcp_server_socket.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
tbansal7b403bcc2016-04-13 22:33:2121namespace base {
22class TimeDelta;
23}
24
[email protected]03ec25382011-05-27 21:50:2825namespace net {
26
27namespace {
28
29// Try binding a socket to loopback interface and verify that we can
30// still connect to a server on the same interface.
31TEST(TCPClientSocketTest, BindLoopbackToLoopback) {
martijna2e83bd2016-03-18 13:10:4532 IPAddress lo_address = IPAddress::IPv4Localhost();
[email protected]03ec25382011-05-27 21:50:2833
34 TCPServerSocket server(NULL, NetLog::Source());
35 ASSERT_EQ(OK, server.Listen(IPEndPoint(lo_address, 0), 1));
36 IPEndPoint server_address;
37 ASSERT_EQ(OK, server.GetLocalAddress(&server_address));
38
tbansal7b403bcc2016-04-13 22:33:2139 TCPClientSocket socket(AddressList(server_address), NULL, NULL,
40 NetLog::Source());
[email protected]03ec25382011-05-27 21:50:2841
42 EXPECT_EQ(OK, socket.Bind(IPEndPoint(lo_address, 0)));
43
[email protected]aa486102012-07-20 01:11:5344 IPEndPoint local_address_result;
45 EXPECT_EQ(OK, socket.GetLocalAddress(&local_address_result));
martijna2e83bd2016-03-18 13:10:4546 EXPECT_EQ(lo_address, local_address_result.address());
[email protected]aa486102012-07-20 01:11:5347
[email protected]83039bb2011-12-09 18:43:5548 TestCompletionCallback connect_callback;
49 EXPECT_EQ(ERR_IO_PENDING, socket.Connect(connect_callback.callback()));
[email protected]03ec25382011-05-27 21:50:2850
[email protected]df7a30d2011-12-03 04:16:5051 TestCompletionCallback accept_callback;
danakj655b66c2016-04-16 00:51:3852 std::unique_ptr<StreamSocket> accepted_socket;
[email protected]df7a30d2011-12-03 04:16:5053 int result = server.Accept(&accepted_socket, accept_callback.callback());
[email protected]03ec25382011-05-27 21:50:2854 if (result == ERR_IO_PENDING)
55 result = accept_callback.WaitForResult();
56 ASSERT_EQ(OK, result);
57
58 EXPECT_EQ(OK, connect_callback.WaitForResult());
[email protected]aa486102012-07-20 01:11:5359
60 EXPECT_TRUE(socket.IsConnected());
61 socket.Disconnect();
62 EXPECT_FALSE(socket.IsConnected());
63 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
64 socket.GetLocalAddress(&local_address_result));
[email protected]03ec25382011-05-27 21:50:2865}
66
67// Try to bind socket to the loopback interface and connect to an
68// external address, verify that connection fails.
69TEST(TCPClientSocketTest, BindLoopbackToExternal) {
martijna2e83bd2016-03-18 13:10:4570 IPAddress external_ip(72, 14, 213, 105);
[email protected]03ec25382011-05-27 21:50:2871 TCPClientSocket socket(AddressList::CreateFromIPAddress(external_ip, 80),
tbansal7b403bcc2016-04-13 22:33:2172 NULL, NULL, NetLog::Source());
[email protected]03ec25382011-05-27 21:50:2873
martijna2e83bd2016-03-18 13:10:4574 EXPECT_EQ(OK, socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)));
[email protected]03ec25382011-05-27 21:50:2875
[email protected]83039bb2011-12-09 18:43:5576 TestCompletionCallback connect_callback;
77 int result = socket.Connect(connect_callback.callback());
[email protected]03ec25382011-05-27 21:50:2878 if (result == ERR_IO_PENDING)
79 result = connect_callback.WaitForResult();
80
81 // We may get different errors here on different system, but
82 // connect() is not expected to succeed.
83 EXPECT_NE(OK, result);
84}
85
86// Bind a socket to the IPv4 loopback interface and try to connect to
87// the IPv6 loopback interface, verify that connection fails.
88TEST(TCPClientSocketTest, BindLoopbackToIPv6) {
[email protected]03ec25382011-05-27 21:50:2889 TCPServerSocket server(NULL, NetLog::Source());
martijna2e83bd2016-03-18 13:10:4590 int listen_result =
91 server.Listen(IPEndPoint(IPAddress::IPv6Localhost(), 0), 1);
[email protected]03ec25382011-05-27 21:50:2892 if (listen_result != OK) {
93 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled."
94 " Skipping the test";
95 return;
96 }
97
98 IPEndPoint server_address;
99 ASSERT_EQ(OK, server.GetLocalAddress(&server_address));
tbansal7b403bcc2016-04-13 22:33:21100 TCPClientSocket socket(AddressList(server_address), NULL, NULL,
101 NetLog::Source());
[email protected]03ec25382011-05-27 21:50:28102
martijna2e83bd2016-03-18 13:10:45103 EXPECT_EQ(OK, socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)));
[email protected]03ec25382011-05-27 21:50:28104
[email protected]83039bb2011-12-09 18:43:55105 TestCompletionCallback connect_callback;
106 int result = socket.Connect(connect_callback.callback());
[email protected]03ec25382011-05-27 21:50:28107 if (result == ERR_IO_PENDING)
108 result = connect_callback.WaitForResult();
109
110 EXPECT_NE(OK, result);
111}
112
tbansal7b403bcc2016-04-13 22:33:21113class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
114 public:
115 TestSocketPerformanceWatcher() : connection_changed_count_(0u) {}
116 ~TestSocketPerformanceWatcher() override {}
117
118 bool ShouldNotifyUpdatedRTT() const override { return true; }
119
120 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {}
121
122 void OnConnectionChanged() override { connection_changed_count_++; }
123
124 size_t connection_changed_count() const { return connection_changed_count_; }
125
126 private:
127 size_t connection_changed_count_;
128
129 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
130};
131
132// TestSocketPerformanceWatcher requires kernel support for tcp_info struct, and
133// so it is enabled only on certain platforms.
134#if defined(TCP_INFO) || defined(OS_LINUX)
135#define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
136#else
137#define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
138#endif
139// Tests if the socket performance watcher is notified if the same socket is
140// used for a different connection.
141TEST(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) {
142 const size_t kNumIPs = 2;
143 IPAddressList ip_list;
144 for (size_t i = 0; i < kNumIPs; ++i)
145 ip_list.push_back(IPAddress(72, 14, 213, i));
146
danakj655b66c2016-04-16 00:51:38147 std::unique_ptr<TestSocketPerformanceWatcher> watcher(
tbansal7b403bcc2016-04-13 22:33:21148 new TestSocketPerformanceWatcher());
149 TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
150
151 TCPClientSocket socket(
152 AddressList::CreateFromIPAddressList(ip_list, "example.com"),
153 std::move(watcher), NULL, NetLog::Source());
154
155 EXPECT_EQ(OK, socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)));
156
157 TestCompletionCallback connect_callback;
158
159 ASSERT_NE(OK, connect_callback.GetResult(
160 socket.Connect(connect_callback.callback())));
161
162 EXPECT_EQ(kNumIPs - 1, watcher_ptr->connection_changed_count());
163}
164
[email protected]03ec25382011-05-27 21:50:28165} // namespace
166
167} // namespace net