OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/tcp_socket.h" | 5 #include "net/socket/tcp_socket.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "net/base/address_list.h" | 14 #include "net/base/address_list.h" |
15 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
16 #include "net/base/ip_endpoint.h" | 16 #include "net/base/ip_endpoint.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 #include "net/base/test_completion_callback.h" | 18 #include "net/base/test_completion_callback.h" |
19 #include "net/socket/tcp_client_socket.h" | 19 #include "net/socket/tcp_client_socket.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
21 #include "testing/platform_test.h" | 21 #include "testing/platform_test.h" |
22 | 22 |
23 namespace net { | 23 namespace net { |
24 | 24 |
25 namespace { | 25 namespace { |
26 const int kListenBacklog = 5; | 26 const int kListenBacklog = 5; |
27 | 27 |
28 class TCPSocketTest : public PlatformTest { | 28 class TCPSocketTest : public PlatformTest { |
29 protected: | 29 protected: |
30 TCPSocketTest() : socket_(NULL, NetLog::Source()) { | 30 TCPSocketTest() : socket_(NULL, NetLog::Source()) {} |
31 } | |
32 | 31 |
33 void SetUpListenIPv4() { | 32 void SetUpListenIPv4() { |
34 IPEndPoint address; | 33 IPEndPoint address; |
35 ParseAddress("127.0.0.1", 0, &address); | 34 ParseAddress("127.0.0.1", 0, &address); |
36 | 35 |
37 ASSERT_EQ(OK, socket_.Open(ADDRESS_FAMILY_IPV4)); | 36 ASSERT_EQ(OK, socket_.Open(ADDRESS_FAMILY_IPV4)); |
38 ASSERT_EQ(OK, socket_.Bind(address)); | 37 ASSERT_EQ(OK, socket_.Bind(address)); |
39 ASSERT_EQ(OK, socket_.Listen(kListenBacklog)); | 38 ASSERT_EQ(OK, socket_.Listen(kListenBacklog)); |
40 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_)); | 39 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_)); |
41 } | 40 } |
42 | 41 |
43 void SetUpListenIPv6(bool* success) { | 42 void SetUpListenIPv6(bool* success) { |
44 *success = false; | 43 *success = false; |
45 IPEndPoint address; | 44 IPEndPoint address; |
46 ParseAddress("::1", 0, &address); | 45 ParseAddress("::1", 0, &address); |
47 | 46 |
48 if (socket_.Open(ADDRESS_FAMILY_IPV6) != OK || | 47 if (socket_.Open(ADDRESS_FAMILY_IPV6) != OK || |
49 socket_.Bind(address) != OK || | 48 socket_.Bind(address) != OK || socket_.Listen(kListenBacklog) != OK) { |
50 socket_.Listen(kListenBacklog) != OK) { | |
51 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is " | 49 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is " |
52 "disabled. Skipping the test"; | 50 "disabled. Skipping the test"; |
53 return; | 51 return; |
54 } | 52 } |
55 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_)); | 53 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_)); |
56 *success = true; | 54 *success = true; |
57 } | 55 } |
58 | 56 |
59 void ParseAddress(const std::string& ip_str, int port, IPEndPoint* address) { | 57 void ParseAddress(const std::string& ip_str, int port, IPEndPoint* address) { |
60 IPAddressNumber ip_number; | 58 IPAddressNumber ip_number; |
61 bool rv = ParseIPLiteralToNumber(ip_str, &ip_number); | 59 bool rv = ParseIPLiteralToNumber(ip_str, &ip_number); |
62 if (!rv) | 60 if (!rv) |
63 return; | 61 return; |
64 *address = IPEndPoint(ip_number, port); | 62 *address = IPEndPoint(ip_number, port); |
65 } | 63 } |
66 | 64 |
67 void TestAcceptAsync() { | 65 void TestAcceptAsync() { |
68 TestCompletionCallback accept_callback; | 66 TestCompletionCallback accept_callback; |
69 scoped_ptr<TCPSocket> accepted_socket; | 67 scoped_ptr<TCPSocket> accepted_socket; |
70 IPEndPoint accepted_address; | 68 IPEndPoint accepted_address; |
71 ASSERT_EQ(ERR_IO_PENDING, | 69 ASSERT_EQ( |
72 socket_.Accept(&accepted_socket, &accepted_address, | 70 ERR_IO_PENDING, |
73 accept_callback.callback())); | 71 socket_.Accept( |
| 72 &accepted_socket, &accepted_address, accept_callback.callback())); |
74 | 73 |
75 TestCompletionCallback connect_callback; | 74 TestCompletionCallback connect_callback; |
76 TCPClientSocket connecting_socket(local_address_list(), | 75 TCPClientSocket connecting_socket( |
77 NULL, NetLog::Source()); | 76 local_address_list(), NULL, NetLog::Source()); |
78 connecting_socket.Connect(connect_callback.callback()); | 77 connecting_socket.Connect(connect_callback.callback()); |
79 | 78 |
80 EXPECT_EQ(OK, connect_callback.WaitForResult()); | 79 EXPECT_EQ(OK, connect_callback.WaitForResult()); |
81 EXPECT_EQ(OK, accept_callback.WaitForResult()); | 80 EXPECT_EQ(OK, accept_callback.WaitForResult()); |
82 | 81 |
83 EXPECT_TRUE(accepted_socket.get()); | 82 EXPECT_TRUE(accepted_socket.get()); |
84 | 83 |
85 // Both sockets should be on the loopback network interface. | 84 // Both sockets should be on the loopback network interface. |
86 EXPECT_EQ(accepted_address.address(), local_address_.address()); | 85 EXPECT_EQ(accepted_address.address(), local_address_.address()); |
87 } | 86 } |
88 | 87 |
89 AddressList local_address_list() const { | 88 AddressList local_address_list() const { return AddressList(local_address_); } |
90 return AddressList(local_address_); | |
91 } | |
92 | 89 |
93 TCPSocket socket_; | 90 TCPSocket socket_; |
94 IPEndPoint local_address_; | 91 IPEndPoint local_address_; |
95 }; | 92 }; |
96 | 93 |
97 // Test listening and accepting with a socket bound to an IPv4 address. | 94 // Test listening and accepting with a socket bound to an IPv4 address. |
98 TEST_F(TCPSocketTest, Accept) { | 95 TEST_F(TCPSocketTest, Accept) { |
99 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); | 96 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); |
100 | 97 |
101 TestCompletionCallback connect_callback; | 98 TestCompletionCallback connect_callback; |
102 // TODO(yzshen): Switch to use TCPSocket when it supports client socket | 99 // TODO(yzshen): Switch to use TCPSocket when it supports client socket |
103 // operations. | 100 // operations. |
104 TCPClientSocket connecting_socket(local_address_list(), | 101 TCPClientSocket connecting_socket( |
105 NULL, NetLog::Source()); | 102 local_address_list(), NULL, NetLog::Source()); |
106 connecting_socket.Connect(connect_callback.callback()); | 103 connecting_socket.Connect(connect_callback.callback()); |
107 | 104 |
108 TestCompletionCallback accept_callback; | 105 TestCompletionCallback accept_callback; |
109 scoped_ptr<TCPSocket> accepted_socket; | 106 scoped_ptr<TCPSocket> accepted_socket; |
110 IPEndPoint accepted_address; | 107 IPEndPoint accepted_address; |
111 int result = socket_.Accept(&accepted_socket, &accepted_address, | 108 int result = socket_.Accept( |
112 accept_callback.callback()); | 109 &accepted_socket, &accepted_address, accept_callback.callback()); |
113 if (result == ERR_IO_PENDING) | 110 if (result == ERR_IO_PENDING) |
114 result = accept_callback.WaitForResult(); | 111 result = accept_callback.WaitForResult(); |
115 ASSERT_EQ(OK, result); | 112 ASSERT_EQ(OK, result); |
116 | 113 |
117 EXPECT_TRUE(accepted_socket.get()); | 114 EXPECT_TRUE(accepted_socket.get()); |
118 | 115 |
119 // Both sockets should be on the loopback network interface. | 116 // Both sockets should be on the loopback network interface. |
120 EXPECT_EQ(accepted_address.address(), local_address_.address()); | 117 EXPECT_EQ(accepted_address.address(), local_address_.address()); |
121 | 118 |
122 EXPECT_EQ(OK, connect_callback.WaitForResult()); | 119 EXPECT_EQ(OK, connect_callback.WaitForResult()); |
(...skipping 26 matching lines...) Expand all Loading... |
149 #endif | 146 #endif |
150 | 147 |
151 // Accept two connections simultaneously. | 148 // Accept two connections simultaneously. |
152 TEST_F(TCPSocketTest, Accept2Connections) { | 149 TEST_F(TCPSocketTest, Accept2Connections) { |
153 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); | 150 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); |
154 | 151 |
155 TestCompletionCallback accept_callback; | 152 TestCompletionCallback accept_callback; |
156 scoped_ptr<TCPSocket> accepted_socket; | 153 scoped_ptr<TCPSocket> accepted_socket; |
157 IPEndPoint accepted_address; | 154 IPEndPoint accepted_address; |
158 | 155 |
159 ASSERT_EQ(ERR_IO_PENDING, | 156 ASSERT_EQ( |
160 socket_.Accept(&accepted_socket, &accepted_address, | 157 ERR_IO_PENDING, |
161 accept_callback.callback())); | 158 socket_.Accept( |
| 159 &accepted_socket, &accepted_address, accept_callback.callback())); |
162 | 160 |
163 TestCompletionCallback connect_callback; | 161 TestCompletionCallback connect_callback; |
164 TCPClientSocket connecting_socket(local_address_list(), | 162 TCPClientSocket connecting_socket( |
165 NULL, NetLog::Source()); | 163 local_address_list(), NULL, NetLog::Source()); |
166 connecting_socket.Connect(connect_callback.callback()); | 164 connecting_socket.Connect(connect_callback.callback()); |
167 | 165 |
168 TestCompletionCallback connect_callback2; | 166 TestCompletionCallback connect_callback2; |
169 TCPClientSocket connecting_socket2(local_address_list(), | 167 TCPClientSocket connecting_socket2( |
170 NULL, NetLog::Source()); | 168 local_address_list(), NULL, NetLog::Source()); |
171 connecting_socket2.Connect(connect_callback2.callback()); | 169 connecting_socket2.Connect(connect_callback2.callback()); |
172 | 170 |
173 EXPECT_EQ(OK, accept_callback.WaitForResult()); | 171 EXPECT_EQ(OK, accept_callback.WaitForResult()); |
174 | 172 |
175 TestCompletionCallback accept_callback2; | 173 TestCompletionCallback accept_callback2; |
176 scoped_ptr<TCPSocket> accepted_socket2; | 174 scoped_ptr<TCPSocket> accepted_socket2; |
177 IPEndPoint accepted_address2; | 175 IPEndPoint accepted_address2; |
178 | 176 |
179 int result = socket_.Accept(&accepted_socket2, &accepted_address2, | 177 int result = socket_.Accept( |
180 accept_callback2.callback()); | 178 &accepted_socket2, &accepted_address2, accept_callback2.callback()); |
181 if (result == ERR_IO_PENDING) | 179 if (result == ERR_IO_PENDING) |
182 result = accept_callback2.WaitForResult(); | 180 result = accept_callback2.WaitForResult(); |
183 ASSERT_EQ(OK, result); | 181 ASSERT_EQ(OK, result); |
184 | 182 |
185 EXPECT_EQ(OK, connect_callback.WaitForResult()); | 183 EXPECT_EQ(OK, connect_callback.WaitForResult()); |
186 EXPECT_EQ(OK, connect_callback2.WaitForResult()); | 184 EXPECT_EQ(OK, connect_callback2.WaitForResult()); |
187 | 185 |
188 EXPECT_TRUE(accepted_socket.get()); | 186 EXPECT_TRUE(accepted_socket.get()); |
189 EXPECT_TRUE(accepted_socket2.get()); | 187 EXPECT_TRUE(accepted_socket2.get()); |
190 EXPECT_NE(accepted_socket.get(), accepted_socket2.get()); | 188 EXPECT_NE(accepted_socket.get(), accepted_socket2.get()); |
191 | 189 |
192 EXPECT_EQ(accepted_address.address(), local_address_.address()); | 190 EXPECT_EQ(accepted_address.address(), local_address_.address()); |
193 EXPECT_EQ(accepted_address2.address(), local_address_.address()); | 191 EXPECT_EQ(accepted_address2.address(), local_address_.address()); |
194 } | 192 } |
195 | 193 |
196 // Test listening and accepting with a socket bound to an IPv6 address. | 194 // Test listening and accepting with a socket bound to an IPv6 address. |
197 TEST_F(TCPSocketTest, AcceptIPv6) { | 195 TEST_F(TCPSocketTest, AcceptIPv6) { |
198 bool initialized = false; | 196 bool initialized = false; |
199 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized)); | 197 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized)); |
200 if (!initialized) | 198 if (!initialized) |
201 return; | 199 return; |
202 | 200 |
203 TestCompletionCallback connect_callback; | 201 TestCompletionCallback connect_callback; |
204 TCPClientSocket connecting_socket(local_address_list(), | 202 TCPClientSocket connecting_socket( |
205 NULL, NetLog::Source()); | 203 local_address_list(), NULL, NetLog::Source()); |
206 connecting_socket.Connect(connect_callback.callback()); | 204 connecting_socket.Connect(connect_callback.callback()); |
207 | 205 |
208 TestCompletionCallback accept_callback; | 206 TestCompletionCallback accept_callback; |
209 scoped_ptr<TCPSocket> accepted_socket; | 207 scoped_ptr<TCPSocket> accepted_socket; |
210 IPEndPoint accepted_address; | 208 IPEndPoint accepted_address; |
211 int result = socket_.Accept(&accepted_socket, &accepted_address, | 209 int result = socket_.Accept( |
212 accept_callback.callback()); | 210 &accepted_socket, &accepted_address, accept_callback.callback()); |
213 if (result == ERR_IO_PENDING) | 211 if (result == ERR_IO_PENDING) |
214 result = accept_callback.WaitForResult(); | 212 result = accept_callback.WaitForResult(); |
215 ASSERT_EQ(OK, result); | 213 ASSERT_EQ(OK, result); |
216 | 214 |
217 EXPECT_TRUE(accepted_socket.get()); | 215 EXPECT_TRUE(accepted_socket.get()); |
218 | 216 |
219 // Both sockets should be on the loopback network interface. | 217 // Both sockets should be on the loopback network interface. |
220 EXPECT_EQ(accepted_address.address(), local_address_.address()); | 218 EXPECT_EQ(accepted_address.address(), local_address_.address()); |
221 | 219 |
222 EXPECT_EQ(OK, connect_callback.WaitForResult()); | 220 EXPECT_EQ(OK, connect_callback.WaitForResult()); |
223 } | 221 } |
224 | 222 |
225 TEST_F(TCPSocketTest, ReadWrite) { | 223 TEST_F(TCPSocketTest, ReadWrite) { |
226 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); | 224 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); |
227 | 225 |
228 TestCompletionCallback connect_callback; | 226 TestCompletionCallback connect_callback; |
229 TCPSocket connecting_socket(NULL, NetLog::Source()); | 227 TCPSocket connecting_socket(NULL, NetLog::Source()); |
230 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4); | 228 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4); |
231 ASSERT_EQ(OK, result); | 229 ASSERT_EQ(OK, result); |
232 connecting_socket.Connect(local_address_, connect_callback.callback()); | 230 connecting_socket.Connect(local_address_, connect_callback.callback()); |
233 | 231 |
234 TestCompletionCallback accept_callback; | 232 TestCompletionCallback accept_callback; |
235 scoped_ptr<TCPSocket> accepted_socket; | 233 scoped_ptr<TCPSocket> accepted_socket; |
236 IPEndPoint accepted_address; | 234 IPEndPoint accepted_address; |
237 result = socket_.Accept(&accepted_socket, &accepted_address, | 235 result = socket_.Accept( |
238 accept_callback.callback()); | 236 &accepted_socket, &accepted_address, accept_callback.callback()); |
239 ASSERT_EQ(OK, accept_callback.GetResult(result)); | 237 ASSERT_EQ(OK, accept_callback.GetResult(result)); |
240 | 238 |
241 ASSERT_TRUE(accepted_socket.get()); | 239 ASSERT_TRUE(accepted_socket.get()); |
242 | 240 |
243 // Both sockets should be on the loopback network interface. | 241 // Both sockets should be on the loopback network interface. |
244 EXPECT_EQ(accepted_address.address(), local_address_.address()); | 242 EXPECT_EQ(accepted_address.address(), local_address_.address()); |
245 | 243 |
246 EXPECT_EQ(OK, connect_callback.WaitForResult()); | 244 EXPECT_EQ(OK, connect_callback.WaitForResult()); |
247 | 245 |
248 const std::string message("test message"); | 246 const std::string message("test message"); |
249 std::vector<char> buffer(message.size()); | 247 std::vector<char> buffer(message.size()); |
250 | 248 |
251 size_t bytes_written = 0; | 249 size_t bytes_written = 0; |
252 while (bytes_written < message.size()) { | 250 while (bytes_written < message.size()) { |
253 scoped_refptr<IOBufferWithSize> write_buffer( | 251 scoped_refptr<IOBufferWithSize> write_buffer( |
254 new IOBufferWithSize(message.size() - bytes_written)); | 252 new IOBufferWithSize(message.size() - bytes_written)); |
255 memmove(write_buffer->data(), message.data() + bytes_written, | 253 memmove(write_buffer->data(), |
| 254 message.data() + bytes_written, |
256 message.size() - bytes_written); | 255 message.size() - bytes_written); |
257 | 256 |
258 TestCompletionCallback write_callback; | 257 TestCompletionCallback write_callback; |
259 int write_result = accepted_socket->Write( | 258 int write_result = accepted_socket->Write( |
260 write_buffer.get(), write_buffer->size(), write_callback.callback()); | 259 write_buffer.get(), write_buffer->size(), write_callback.callback()); |
261 write_result = write_callback.GetResult(write_result); | 260 write_result = write_callback.GetResult(write_result); |
262 ASSERT_TRUE(write_result >= 0); | 261 ASSERT_TRUE(write_result >= 0); |
263 bytes_written += write_result; | 262 bytes_written += write_result; |
264 ASSERT_TRUE(bytes_written <= message.size()); | 263 ASSERT_TRUE(bytes_written <= message.size()); |
265 } | 264 } |
(...skipping 11 matching lines...) Expand all Loading... |
277 memmove(&buffer[bytes_read], read_buffer->data(), read_result); | 276 memmove(&buffer[bytes_read], read_buffer->data(), read_result); |
278 bytes_read += read_result; | 277 bytes_read += read_result; |
279 } | 278 } |
280 | 279 |
281 std::string received_message(buffer.begin(), buffer.end()); | 280 std::string received_message(buffer.begin(), buffer.end()); |
282 ASSERT_EQ(message, received_message); | 281 ASSERT_EQ(message, received_message); |
283 } | 282 } |
284 | 283 |
285 } // namespace | 284 } // namespace |
286 } // namespace net | 285 } // namespace net |
OLD | NEW |