• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_server_socket.h"
6 
7 #include "base/compiler_specific.h"
8 #include "base/scoped_ptr.h"
9 #include "net/base/address_list.h"
10 #include "net/base/ip_endpoint.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/sys_addrinfo.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/socket/tcp_client_socket.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/platform_test.h"
17 
18 namespace net {
19 
20 namespace {
21 const int kListenBacklog = 5;
22 
23 class TCPServerSocketTest : public PlatformTest {
24  protected:
TCPServerSocketTest()25   TCPServerSocketTest()
26       : socket_(NULL, NetLog::Source()) {
27   }
28 
SetUp()29   void SetUp() OVERRIDE {
30     IPEndPoint address;
31     ParseAddress("127.0.0.1", 0, &address);
32     ASSERT_EQ(OK, socket_.Listen(address, kListenBacklog));
33     ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_));
34   }
35 
ParseAddress(std::string ip_str,int port,IPEndPoint * address)36   void ParseAddress(std::string ip_str, int port, IPEndPoint* address) {
37     IPAddressNumber ip_number;
38     bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
39     if (!rv)
40       return;
41     *address = IPEndPoint(ip_number, port);
42   }
43 
GetPeerAddress(ClientSocket * socket)44   static IPEndPoint GetPeerAddress(ClientSocket* socket) {
45     AddressList address;
46     EXPECT_EQ(OK, socket->GetPeerAddress(&address));
47     IPEndPoint endpoint;
48     EXPECT_TRUE(endpoint.FromSockAddr(
49         address.head()->ai_addr, address.head()->ai_addrlen));
50     return endpoint;
51   }
52 
53   TCPServerSocket socket_;
54   IPEndPoint local_address_;
55 };
56 
TEST_F(TCPServerSocketTest,Accept)57 TEST_F(TCPServerSocketTest, Accept) {
58   TestCompletionCallback connect_callback;
59   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
60                                                 local_address_.port(), false),
61                                     NULL, NetLog::Source());
62   connecting_socket.Connect(&connect_callback);
63 
64   TestCompletionCallback accept_callback;
65   scoped_ptr<ClientSocket> accepted_socket;
66   int result = socket_.Accept(&accepted_socket, &accept_callback);
67   if (result == ERR_IO_PENDING)
68     result = accept_callback.WaitForResult();
69   ASSERT_EQ(OK, result);
70 
71   ASSERT_TRUE(accepted_socket.get() != NULL);
72 
73   // Both sockets should be on the loopback network interface.
74   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
75             local_address_.address());
76 
77   EXPECT_EQ(OK, connect_callback.WaitForResult());
78 }
79 
80 // Test Accept() callback.
TEST_F(TCPServerSocketTest,AcceptAsync)81 TEST_F(TCPServerSocketTest, AcceptAsync) {
82   TestCompletionCallback accept_callback;
83   scoped_ptr<ClientSocket> accepted_socket;
84 
85   ASSERT_EQ(ERR_IO_PENDING, socket_.Accept(&accepted_socket, &accept_callback));
86 
87   TestCompletionCallback connect_callback;
88   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
89                                                 local_address_.port(), false),
90                                     NULL, NetLog::Source());
91   connecting_socket.Connect(&connect_callback);
92 
93   EXPECT_EQ(OK, connect_callback.WaitForResult());
94   EXPECT_EQ(OK, accept_callback.WaitForResult());
95 
96   EXPECT_TRUE(accepted_socket != NULL);
97 
98   // Both sockets should be on the loopback network interface.
99   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
100             local_address_.address());
101 }
102 
103 // Accept two connections simultaneously.
TEST_F(TCPServerSocketTest,Accept2Connections)104 TEST_F(TCPServerSocketTest, Accept2Connections) {
105   TestCompletionCallback accept_callback;
106   scoped_ptr<ClientSocket> accepted_socket;
107 
108   ASSERT_EQ(ERR_IO_PENDING,
109             socket_.Accept(&accepted_socket, &accept_callback));
110 
111   TestCompletionCallback connect_callback;
112   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
113                                                 local_address_.port(), false),
114                                     NULL, NetLog::Source());
115   connecting_socket.Connect(&connect_callback);
116 
117   TestCompletionCallback connect_callback2;
118   TCPClientSocket connecting_socket2(AddressList(local_address_.address(),
119                                                  local_address_.port(), false),
120                                      NULL, NetLog::Source());
121   connecting_socket2.Connect(&connect_callback2);
122 
123   EXPECT_EQ(OK, accept_callback.WaitForResult());
124 
125   TestCompletionCallback accept_callback2;
126   scoped_ptr<ClientSocket> accepted_socket2;
127   int result = socket_.Accept(&accepted_socket2, &accept_callback2);
128   if (result == ERR_IO_PENDING)
129     result = accept_callback2.WaitForResult();
130   ASSERT_EQ(OK, result);
131 
132   EXPECT_EQ(OK, connect_callback.WaitForResult());
133 
134   EXPECT_TRUE(accepted_socket != NULL);
135   EXPECT_TRUE(accepted_socket2 != NULL);
136   EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
137 
138   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
139             local_address_.address());
140   EXPECT_EQ(GetPeerAddress(accepted_socket2.get()).address(),
141             local_address_.address());
142 }
143 
144 }  // namespace
145 
146 }  // namespace net
147