1// Copyright (c) 2012 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// 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
11#include "net/base/ip_endpoint.h"
12#include "net/base/net_errors.h"
13#include "net/base/net_util.h"
14#include "net/base/test_completion_callback.h"
15#include "net/socket/tcp_server_socket.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace net {
19
20namespace {
21
22// Try binding a socket to loopback interface and verify that we can
23// still connect to a server on the same interface.
24TEST(TCPClientSocketTest, BindLoopbackToLoopback) {
25  IPAddressNumber lo_address;
26  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &lo_address));
27
28  TCPServerSocket server(NULL, NetLog::Source());
29  ASSERT_EQ(OK, server.Listen(IPEndPoint(lo_address, 0), 1));
30  IPEndPoint server_address;
31  ASSERT_EQ(OK, server.GetLocalAddress(&server_address));
32
33  TCPClientSocket socket(AddressList(server_address), NULL, NetLog::Source());
34
35  EXPECT_EQ(OK, socket.Bind(IPEndPoint(lo_address, 0)));
36
37  IPEndPoint local_address_result;
38  EXPECT_EQ(OK, socket.GetLocalAddress(&local_address_result));
39  EXPECT_EQ(lo_address, local_address_result.address());
40
41  TestCompletionCallback connect_callback;
42  EXPECT_EQ(ERR_IO_PENDING, socket.Connect(connect_callback.callback()));
43
44  TestCompletionCallback accept_callback;
45  scoped_ptr<StreamSocket> accepted_socket;
46  int result = server.Accept(&accepted_socket, accept_callback.callback());
47  if (result == ERR_IO_PENDING)
48    result = accept_callback.WaitForResult();
49  ASSERT_EQ(OK, result);
50
51  EXPECT_EQ(OK, connect_callback.WaitForResult());
52
53  EXPECT_TRUE(socket.IsConnected());
54  socket.Disconnect();
55  EXPECT_FALSE(socket.IsConnected());
56  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
57            socket.GetLocalAddress(&local_address_result));
58}
59
60// Try to bind socket to the loopback interface and connect to an
61// external address, verify that connection fails.
62TEST(TCPClientSocketTest, BindLoopbackToExternal) {
63  IPAddressNumber external_ip;
64  ASSERT_TRUE(ParseIPLiteralToNumber("72.14.213.105", &external_ip));
65  TCPClientSocket socket(AddressList::CreateFromIPAddress(external_ip, 80),
66                         NULL, NetLog::Source());
67
68  IPAddressNumber lo_address;
69  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &lo_address));
70  EXPECT_EQ(OK, socket.Bind(IPEndPoint(lo_address, 0)));
71
72  TestCompletionCallback connect_callback;
73  int result = socket.Connect(connect_callback.callback());
74  if (result == ERR_IO_PENDING)
75    result = connect_callback.WaitForResult();
76
77  // We may get different errors here on different system, but
78  // connect() is not expected to succeed.
79  EXPECT_NE(OK, result);
80}
81
82// Bind a socket to the IPv4 loopback interface and try to connect to
83// the IPv6 loopback interface, verify that connection fails.
84TEST(TCPClientSocketTest, BindLoopbackToIPv6) {
85  IPAddressNumber ipv6_lo_ip;
86  ASSERT_TRUE(ParseIPLiteralToNumber("::1", &ipv6_lo_ip));
87  TCPServerSocket server(NULL, NetLog::Source());
88  int listen_result = server.Listen(IPEndPoint(ipv6_lo_ip, 0), 1);
89  if (listen_result != OK) {
90    LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled."
91        " Skipping the test";
92    return;
93  }
94
95  IPEndPoint server_address;
96  ASSERT_EQ(OK, server.GetLocalAddress(&server_address));
97  TCPClientSocket socket(AddressList(server_address), NULL, NetLog::Source());
98
99  IPAddressNumber ipv4_lo_ip;
100  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ipv4_lo_ip));
101  EXPECT_EQ(OK, socket.Bind(IPEndPoint(ipv4_lo_ip, 0)));
102
103  TestCompletionCallback connect_callback;
104  int result = socket.Connect(connect_callback.callback());
105  if (result == ERR_IO_PENDING)
106    result = connect_callback.WaitForResult();
107
108  EXPECT_NE(OK, result);
109}
110
111}  // namespace
112
113}  // namespace net
114