| 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 |