| OLD | NEW |
| (Empty) |
| 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 #include "net/udp/udp_socket.h" | |
| 6 | |
| 7 #include "net/udp/udp_client_socket.h" | |
| 8 #include "net/udp/udp_server_socket.h" | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/bind.h" | |
| 12 #include "base/memory/weak_ptr.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/metrics/histogram.h" | |
| 15 #include "base/run_loop.h" | |
| 16 #include "base/stl_util.h" | |
| 17 #include "net/base/io_buffer.h" | |
| 18 #include "net/base/ip_endpoint.h" | |
| 19 #include "net/base/net_errors.h" | |
| 20 #include "net/base/net_log_unittest.h" | |
| 21 #include "net/base/net_util.h" | |
| 22 #include "net/base/test_completion_callback.h" | |
| 23 #include "net/test/net_test_suite.h" | |
| 24 #include "testing/gtest/include/gtest/gtest.h" | |
| 25 #include "testing/platform_test.h" | |
| 26 | |
| 27 namespace net { | |
| 28 | |
| 29 namespace { | |
| 30 | |
| 31 class UDPSocketTest : public PlatformTest { | |
| 32 public: | |
| 33 UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {} | |
| 34 | |
| 35 // Blocks until data is read from the socket. | |
| 36 std::string RecvFromSocket(UDPServerSocket* socket) { | |
| 37 TestCompletionCallback callback; | |
| 38 | |
| 39 int rv = socket->RecvFrom( | |
| 40 buffer_.get(), kMaxRead, &recv_from_address_, callback.callback()); | |
| 41 if (rv == ERR_IO_PENDING) | |
| 42 rv = callback.WaitForResult(); | |
| 43 if (rv < 0) | |
| 44 return std::string(); // error! | |
| 45 return std::string(buffer_->data(), rv); | |
| 46 } | |
| 47 | |
| 48 // Loop until |msg| has been written to the socket or until an | |
| 49 // error occurs. | |
| 50 // If |address| is specified, then it is used for the destination | |
| 51 // to send to. Otherwise, will send to the last socket this server | |
| 52 // received from. | |
| 53 int SendToSocket(UDPServerSocket* socket, std::string msg) { | |
| 54 return SendToSocket(socket, msg, recv_from_address_); | |
| 55 } | |
| 56 | |
| 57 int SendToSocket(UDPServerSocket* socket, | |
| 58 std::string msg, | |
| 59 const IPEndPoint& address) { | |
| 60 TestCompletionCallback callback; | |
| 61 | |
| 62 int length = msg.length(); | |
| 63 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg)); | |
| 64 scoped_refptr<DrainableIOBuffer> buffer( | |
| 65 new DrainableIOBuffer(io_buffer.get(), length)); | |
| 66 | |
| 67 int bytes_sent = 0; | |
| 68 while (buffer->BytesRemaining()) { | |
| 69 int rv = socket->SendTo( | |
| 70 buffer.get(), buffer->BytesRemaining(), address, callback.callback()); | |
| 71 if (rv == ERR_IO_PENDING) | |
| 72 rv = callback.WaitForResult(); | |
| 73 if (rv <= 0) | |
| 74 return bytes_sent > 0 ? bytes_sent : rv; | |
| 75 bytes_sent += rv; | |
| 76 buffer->DidConsume(rv); | |
| 77 } | |
| 78 return bytes_sent; | |
| 79 } | |
| 80 | |
| 81 std::string ReadSocket(UDPClientSocket* socket) { | |
| 82 TestCompletionCallback callback; | |
| 83 | |
| 84 int rv = socket->Read(buffer_.get(), kMaxRead, callback.callback()); | |
| 85 if (rv == ERR_IO_PENDING) | |
| 86 rv = callback.WaitForResult(); | |
| 87 if (rv < 0) | |
| 88 return std::string(); // error! | |
| 89 return std::string(buffer_->data(), rv); | |
| 90 } | |
| 91 | |
| 92 // Loop until |msg| has been written to the socket or until an | |
| 93 // error occurs. | |
| 94 int WriteSocket(UDPClientSocket* socket, std::string msg) { | |
| 95 TestCompletionCallback callback; | |
| 96 | |
| 97 int length = msg.length(); | |
| 98 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg)); | |
| 99 scoped_refptr<DrainableIOBuffer> buffer( | |
| 100 new DrainableIOBuffer(io_buffer.get(), length)); | |
| 101 | |
| 102 int bytes_sent = 0; | |
| 103 while (buffer->BytesRemaining()) { | |
| 104 int rv = socket->Write( | |
| 105 buffer.get(), buffer->BytesRemaining(), callback.callback()); | |
| 106 if (rv == ERR_IO_PENDING) | |
| 107 rv = callback.WaitForResult(); | |
| 108 if (rv <= 0) | |
| 109 return bytes_sent > 0 ? bytes_sent : rv; | |
| 110 bytes_sent += rv; | |
| 111 buffer->DidConsume(rv); | |
| 112 } | |
| 113 return bytes_sent; | |
| 114 } | |
| 115 | |
| 116 void WriteSocketIgnoreResult(UDPClientSocket* socket, std::string msg) { | |
| 117 WriteSocket(socket, msg); | |
| 118 } | |
| 119 | |
| 120 // Creates an address from ip address and port and writes it to |*address|. | |
| 121 void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) { | |
| 122 IPAddressNumber ip_number; | |
| 123 bool rv = ParseIPLiteralToNumber(ip_str, &ip_number); | |
| 124 if (!rv) | |
| 125 return; | |
| 126 *address = IPEndPoint(ip_number, port); | |
| 127 } | |
| 128 | |
| 129 // Run unit test for a connection test. | |
| 130 // |use_nonblocking_io| is used to switch between overlapped and non-blocking | |
| 131 // IO on Windows. It has no effect in other ports. | |
| 132 void ConnectTest(bool use_nonblocking_io); | |
| 133 | |
| 134 protected: | |
| 135 static const int kMaxRead = 1024; | |
| 136 scoped_refptr<IOBufferWithSize> buffer_; | |
| 137 IPEndPoint recv_from_address_; | |
| 138 }; | |
| 139 | |
| 140 void ReadCompleteCallback(int* result_out, base::Closure callback, int result) { | |
| 141 *result_out = result; | |
| 142 callback.Run(); | |
| 143 } | |
| 144 | |
| 145 void UDPSocketTest::ConnectTest(bool use_nonblocking_io) { | |
| 146 const uint16 kPort = 9999; | |
| 147 std::string simple_message("hello world!"); | |
| 148 | |
| 149 // Setup the server to listen. | |
| 150 IPEndPoint bind_address; | |
| 151 CreateUDPAddress("127.0.0.1", kPort, &bind_address); | |
| 152 CapturingNetLog server_log; | |
| 153 scoped_ptr<UDPServerSocket> server( | |
| 154 new UDPServerSocket(&server_log, NetLog::Source())); | |
| 155 #if defined(OS_WIN) | |
| 156 if (use_nonblocking_io) | |
| 157 server->UseNonBlockingIO(); | |
| 158 #endif | |
| 159 server->AllowAddressReuse(); | |
| 160 int rv = server->Listen(bind_address); | |
| 161 ASSERT_EQ(OK, rv); | |
| 162 | |
| 163 // Setup the client. | |
| 164 IPEndPoint server_address; | |
| 165 CreateUDPAddress("127.0.0.1", kPort, &server_address); | |
| 166 CapturingNetLog client_log; | |
| 167 scoped_ptr<UDPClientSocket> client( | |
| 168 new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), | |
| 169 &client_log, NetLog::Source())); | |
| 170 #if defined(OS_WIN) | |
| 171 if (use_nonblocking_io) | |
| 172 client->UseNonBlockingIO(); | |
| 173 #endif | |
| 174 | |
| 175 rv = client->Connect(server_address); | |
| 176 EXPECT_EQ(OK, rv); | |
| 177 | |
| 178 // Client sends to the server. | |
| 179 rv = WriteSocket(client.get(), simple_message); | |
| 180 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
| 181 | |
| 182 // Server waits for message. | |
| 183 std::string str = RecvFromSocket(server.get()); | |
| 184 DCHECK(simple_message == str); | |
| 185 | |
| 186 // Server echoes reply. | |
| 187 rv = SendToSocket(server.get(), simple_message); | |
| 188 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
| 189 | |
| 190 // Client waits for response. | |
| 191 str = ReadSocket(client.get()); | |
| 192 DCHECK(simple_message == str); | |
| 193 | |
| 194 // Test asynchronous read. Server waits for message. | |
| 195 base::RunLoop run_loop; | |
| 196 int read_result = 0; | |
| 197 rv = server->RecvFrom( | |
| 198 buffer_.get(), kMaxRead, &recv_from_address_, | |
| 199 base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure())); | |
| 200 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 201 | |
| 202 // Client sends to the server. | |
| 203 base::MessageLoop::current()->PostTask( | |
| 204 FROM_HERE, | |
| 205 base::Bind(&UDPSocketTest::WriteSocketIgnoreResult, | |
| 206 base::Unretained(this), client.get(), simple_message)); | |
| 207 run_loop.Run(); | |
| 208 EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result)); | |
| 209 EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result)); | |
| 210 | |
| 211 // Delete sockets so they log their final events. | |
| 212 server.reset(); | |
| 213 client.reset(); | |
| 214 | |
| 215 // Check the server's log. | |
| 216 CapturingNetLog::CapturedEntryList server_entries; | |
| 217 server_log.GetEntries(&server_entries); | |
| 218 EXPECT_EQ(5u, server_entries.size()); | |
| 219 EXPECT_TRUE( | |
| 220 LogContainsBeginEvent(server_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); | |
| 221 EXPECT_TRUE(LogContainsEvent( | |
| 222 server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); | |
| 223 EXPECT_TRUE(LogContainsEvent(server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, | |
| 224 NetLog::PHASE_NONE)); | |
| 225 EXPECT_TRUE(LogContainsEvent( | |
| 226 server_entries, 3, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); | |
| 227 EXPECT_TRUE( | |
| 228 LogContainsEndEvent(server_entries, 4, NetLog::TYPE_SOCKET_ALIVE)); | |
| 229 | |
| 230 // Check the client's log. | |
| 231 CapturingNetLog::CapturedEntryList client_entries; | |
| 232 client_log.GetEntries(&client_entries); | |
| 233 EXPECT_EQ(7u, client_entries.size()); | |
| 234 EXPECT_TRUE( | |
| 235 LogContainsBeginEvent(client_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); | |
| 236 EXPECT_TRUE( | |
| 237 LogContainsBeginEvent(client_entries, 1, NetLog::TYPE_UDP_CONNECT)); | |
| 238 EXPECT_TRUE(LogContainsEndEvent(client_entries, 2, NetLog::TYPE_UDP_CONNECT)); | |
| 239 EXPECT_TRUE(LogContainsEvent(client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, | |
| 240 NetLog::PHASE_NONE)); | |
| 241 EXPECT_TRUE(LogContainsEvent( | |
| 242 client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); | |
| 243 EXPECT_TRUE(LogContainsEvent(client_entries, 5, NetLog::TYPE_UDP_BYTES_SENT, | |
| 244 NetLog::PHASE_NONE)); | |
| 245 EXPECT_TRUE( | |
| 246 LogContainsEndEvent(client_entries, 6, NetLog::TYPE_SOCKET_ALIVE)); | |
| 247 } | |
| 248 | |
| 249 TEST_F(UDPSocketTest, Connect) { | |
| 250 // The variable |use_nonblocking_io| has no effect in non-Windows ports. | |
| 251 ConnectTest(false); | |
| 252 } | |
| 253 | |
| 254 #if defined(OS_WIN) | |
| 255 TEST_F(UDPSocketTest, ConnectNonBlocking) { | |
| 256 ConnectTest(true); | |
| 257 } | |
| 258 #endif | |
| 259 | |
| 260 #if defined(OS_MACOSX) | |
| 261 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires | |
| 262 // root permissions on OSX 10.7+. | |
| 263 TEST_F(UDPSocketTest, DISABLED_Broadcast) { | |
| 264 #elif defined(OS_ANDROID) | |
| 265 // It is also disabled for Android because it is extremely flaky. | |
| 266 // The first call to SendToSocket returns -109 (Address not reachable) | |
| 267 // in some unpredictable cases. crbug.com/139144. | |
| 268 TEST_F(UDPSocketTest, DISABLED_Broadcast) { | |
| 269 #else | |
| 270 TEST_F(UDPSocketTest, Broadcast) { | |
| 271 #endif | |
| 272 const uint16 kPort = 9999; | |
| 273 std::string first_message("first message"), second_message("second message"); | |
| 274 | |
| 275 IPEndPoint broadcast_address; | |
| 276 CreateUDPAddress("255.255.255.255", kPort, &broadcast_address); | |
| 277 IPEndPoint listen_address; | |
| 278 CreateUDPAddress("0.0.0.0", kPort, &listen_address); | |
| 279 | |
| 280 CapturingNetLog server1_log, server2_log; | |
| 281 scoped_ptr<UDPServerSocket> server1( | |
| 282 new UDPServerSocket(&server1_log, NetLog::Source())); | |
| 283 scoped_ptr<UDPServerSocket> server2( | |
| 284 new UDPServerSocket(&server2_log, NetLog::Source())); | |
| 285 server1->AllowAddressReuse(); | |
| 286 server1->AllowBroadcast(); | |
| 287 server2->AllowAddressReuse(); | |
| 288 server2->AllowBroadcast(); | |
| 289 | |
| 290 int rv = server1->Listen(listen_address); | |
| 291 EXPECT_EQ(OK, rv); | |
| 292 rv = server2->Listen(listen_address); | |
| 293 EXPECT_EQ(OK, rv); | |
| 294 | |
| 295 rv = SendToSocket(server1.get(), first_message, broadcast_address); | |
| 296 ASSERT_EQ(static_cast<int>(first_message.size()), rv); | |
| 297 std::string str = RecvFromSocket(server1.get()); | |
| 298 ASSERT_EQ(first_message, str); | |
| 299 str = RecvFromSocket(server2.get()); | |
| 300 ASSERT_EQ(first_message, str); | |
| 301 | |
| 302 rv = SendToSocket(server2.get(), second_message, broadcast_address); | |
| 303 ASSERT_EQ(static_cast<int>(second_message.size()), rv); | |
| 304 str = RecvFromSocket(server1.get()); | |
| 305 ASSERT_EQ(second_message, str); | |
| 306 str = RecvFromSocket(server2.get()); | |
| 307 ASSERT_EQ(second_message, str); | |
| 308 } | |
| 309 | |
| 310 // In this test, we verify that random binding logic works, which attempts | |
| 311 // to bind to a random port and returns if succeeds, otherwise retries for | |
| 312 // |kBindRetries| number of times. | |
| 313 | |
| 314 // To generate the scenario, we first create |kBindRetries| number of | |
| 315 // UDPClientSockets with default binding policy and connect to the same | |
| 316 // peer and save the used port numbers. Then we get rid of the last | |
| 317 // socket, making sure that the local port it was bound to is available. | |
| 318 // Finally, we create a socket with random binding policy, passing it a | |
| 319 // test PRNG that would serve used port numbers in the array, one after | |
| 320 // another. At the end, we make sure that the test socket was bound to the | |
| 321 // port that became available after deleting the last socket with default | |
| 322 // binding policy. | |
| 323 | |
| 324 // We do not test the randomness of bound ports, but that we are using | |
| 325 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong | |
| 326 // random numbers. | |
| 327 static const int kBindRetries = 10; | |
| 328 | |
| 329 class TestPrng { | |
| 330 public: | |
| 331 explicit TestPrng(const std::deque<int>& numbers) : numbers_(numbers) {} | |
| 332 int GetNext(int /* min */, int /* max */) { | |
| 333 DCHECK(!numbers_.empty()); | |
| 334 int rv = numbers_.front(); | |
| 335 numbers_.pop_front(); | |
| 336 return rv; | |
| 337 } | |
| 338 private: | |
| 339 std::deque<int> numbers_; | |
| 340 | |
| 341 DISALLOW_COPY_AND_ASSIGN(TestPrng); | |
| 342 }; | |
| 343 | |
| 344 #if defined(OS_ANDROID) | |
| 345 // Disabled on Android for lack of 192.168.1.13. crbug.com/161245 | |
| 346 TEST_F(UDPSocketTest, DISABLED_ConnectRandomBind) { | |
| 347 #else | |
| 348 TEST_F(UDPSocketTest, ConnectRandomBind) { | |
| 349 #endif | |
| 350 std::vector<UDPClientSocket*> sockets; | |
| 351 IPEndPoint peer_address; | |
| 352 CreateUDPAddress("192.168.1.13", 53, &peer_address); | |
| 353 | |
| 354 // Create and connect sockets and save port numbers. | |
| 355 std::deque<int> used_ports; | |
| 356 for (int i = 0; i < kBindRetries; ++i) { | |
| 357 UDPClientSocket* socket = | |
| 358 new UDPClientSocket(DatagramSocket::DEFAULT_BIND, | |
| 359 RandIntCallback(), | |
| 360 NULL, | |
| 361 NetLog::Source()); | |
| 362 sockets.push_back(socket); | |
| 363 EXPECT_EQ(OK, socket->Connect(peer_address)); | |
| 364 | |
| 365 IPEndPoint client_address; | |
| 366 EXPECT_EQ(OK, socket->GetLocalAddress(&client_address)); | |
| 367 used_ports.push_back(client_address.port()); | |
| 368 } | |
| 369 | |
| 370 // Free the last socket, its local port is still in |used_ports|. | |
| 371 delete sockets.back(); | |
| 372 sockets.pop_back(); | |
| 373 | |
| 374 TestPrng test_prng(used_ports); | |
| 375 RandIntCallback rand_int_cb = | |
| 376 base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); | |
| 377 | |
| 378 // Create a socket with random binding policy and connect. | |
| 379 scoped_ptr<UDPClientSocket> test_socket( | |
| 380 new UDPClientSocket(DatagramSocket::RANDOM_BIND, | |
| 381 rand_int_cb, | |
| 382 NULL, | |
| 383 NetLog::Source())); | |
| 384 EXPECT_EQ(OK, test_socket->Connect(peer_address)); | |
| 385 | |
| 386 // Make sure that the last port number in the |used_ports| was used. | |
| 387 IPEndPoint client_address; | |
| 388 EXPECT_EQ(OK, test_socket->GetLocalAddress(&client_address)); | |
| 389 EXPECT_EQ(used_ports.back(), client_address.port()); | |
| 390 | |
| 391 STLDeleteElements(&sockets); | |
| 392 } | |
| 393 | |
| 394 // Return a privileged port (under 1024) so binding will fail. | |
| 395 int PrivilegedRand(int min, int max) { | |
| 396 // Chosen by fair dice roll. Guaranteed to be random. | |
| 397 return 4; | |
| 398 } | |
| 399 | |
| 400 TEST_F(UDPSocketTest, ConnectFail) { | |
| 401 IPEndPoint peer_address; | |
| 402 CreateUDPAddress("0.0.0.0", 53, &peer_address); | |
| 403 | |
| 404 scoped_ptr<UDPSocket> socket( | |
| 405 new UDPSocket(DatagramSocket::RANDOM_BIND, | |
| 406 base::Bind(&PrivilegedRand), | |
| 407 NULL, | |
| 408 NetLog::Source())); | |
| 409 int rv = socket->Open(peer_address.GetFamily()); | |
| 410 EXPECT_EQ(OK, rv); | |
| 411 rv = socket->Connect(peer_address); | |
| 412 // Connect should have failed since we couldn't bind to that port, | |
| 413 EXPECT_NE(OK, rv); | |
| 414 // Make sure that UDPSocket actually closed the socket. | |
| 415 EXPECT_FALSE(socket->is_connected()); | |
| 416 } | |
| 417 | |
| 418 // In this test, we verify that connect() on a socket will have the effect | |
| 419 // of filtering reads on this socket only to data read from the destination | |
| 420 // we connected to. | |
| 421 // | |
| 422 // The purpose of this test is that some documentation indicates that connect | |
| 423 // binds the client's sends to send to a particular server endpoint, but does | |
| 424 // not bind the client's reads to only be from that endpoint, and that we need | |
| 425 // to always use recvfrom() to disambiguate. | |
| 426 TEST_F(UDPSocketTest, VerifyConnectBindsAddr) { | |
| 427 const uint16 kPort1 = 9999; | |
| 428 const uint16 kPort2 = 10000; | |
| 429 std::string simple_message("hello world!"); | |
| 430 std::string foreign_message("BAD MESSAGE TO GET!!"); | |
| 431 | |
| 432 // Setup the first server to listen. | |
| 433 IPEndPoint bind_address; | |
| 434 CreateUDPAddress("127.0.0.1", kPort1, &bind_address); | |
| 435 UDPServerSocket server1(NULL, NetLog::Source()); | |
| 436 server1.AllowAddressReuse(); | |
| 437 int rv = server1.Listen(bind_address); | |
| 438 ASSERT_EQ(OK, rv); | |
| 439 | |
| 440 // Setup the second server to listen. | |
| 441 CreateUDPAddress("127.0.0.1", kPort2, &bind_address); | |
| 442 UDPServerSocket server2(NULL, NetLog::Source()); | |
| 443 server2.AllowAddressReuse(); | |
| 444 rv = server2.Listen(bind_address); | |
| 445 ASSERT_EQ(OK, rv); | |
| 446 | |
| 447 // Setup the client, connected to server 1. | |
| 448 IPEndPoint server_address; | |
| 449 CreateUDPAddress("127.0.0.1", kPort1, &server_address); | |
| 450 UDPClientSocket client(DatagramSocket::DEFAULT_BIND, | |
| 451 RandIntCallback(), | |
| 452 NULL, | |
| 453 NetLog::Source()); | |
| 454 rv = client.Connect(server_address); | |
| 455 EXPECT_EQ(OK, rv); | |
| 456 | |
| 457 // Client sends to server1. | |
| 458 rv = WriteSocket(&client, simple_message); | |
| 459 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
| 460 | |
| 461 // Server1 waits for message. | |
| 462 std::string str = RecvFromSocket(&server1); | |
| 463 DCHECK(simple_message == str); | |
| 464 | |
| 465 // Get the client's address. | |
| 466 IPEndPoint client_address; | |
| 467 rv = client.GetLocalAddress(&client_address); | |
| 468 EXPECT_EQ(OK, rv); | |
| 469 | |
| 470 // Server2 sends reply. | |
| 471 rv = SendToSocket(&server2, foreign_message, | |
| 472 client_address); | |
| 473 EXPECT_EQ(foreign_message.length(), static_cast<size_t>(rv)); | |
| 474 | |
| 475 // Server1 sends reply. | |
| 476 rv = SendToSocket(&server1, simple_message, | |
| 477 client_address); | |
| 478 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
| 479 | |
| 480 // Client waits for response. | |
| 481 str = ReadSocket(&client); | |
| 482 DCHECK(simple_message == str); | |
| 483 } | |
| 484 | |
| 485 TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) { | |
| 486 struct TestData { | |
| 487 std::string remote_address; | |
| 488 std::string local_address; | |
| 489 bool may_fail; | |
| 490 } tests[] = { | |
| 491 { "127.0.00.1", "127.0.0.1", false }, | |
| 492 { "::1", "::1", true }, | |
| 493 #if !defined(OS_ANDROID) | |
| 494 // Addresses below are disabled on Android. See crbug.com/161248 | |
| 495 { "192.168.1.1", "127.0.0.1", false }, | |
| 496 { "2001:db8:0::42", "::1", true }, | |
| 497 #endif | |
| 498 }; | |
| 499 for (size_t i = 0; i < arraysize(tests); i++) { | |
| 500 SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address + | |
| 501 std::string(" to ") + tests[i].remote_address); | |
| 502 | |
| 503 IPAddressNumber ip_number; | |
| 504 ParseIPLiteralToNumber(tests[i].remote_address, &ip_number); | |
| 505 IPEndPoint remote_address(ip_number, 80); | |
| 506 ParseIPLiteralToNumber(tests[i].local_address, &ip_number); | |
| 507 IPEndPoint local_address(ip_number, 80); | |
| 508 | |
| 509 UDPClientSocket client(DatagramSocket::DEFAULT_BIND, | |
| 510 RandIntCallback(), | |
| 511 NULL, | |
| 512 NetLog::Source()); | |
| 513 int rv = client.Connect(remote_address); | |
| 514 if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) { | |
| 515 // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6 | |
| 516 // addresses if IPv6 is not configured. | |
| 517 continue; | |
| 518 } | |
| 519 | |
| 520 EXPECT_LE(ERR_IO_PENDING, rv); | |
| 521 | |
| 522 IPEndPoint fetched_local_address; | |
| 523 rv = client.GetLocalAddress(&fetched_local_address); | |
| 524 EXPECT_EQ(OK, rv); | |
| 525 | |
| 526 // TODO(mbelshe): figure out how to verify the IP and port. | |
| 527 // The port is dynamically generated by the udp stack. | |
| 528 // The IP is the real IP of the client, not necessarily | |
| 529 // loopback. | |
| 530 //EXPECT_EQ(local_address.address(), fetched_local_address.address()); | |
| 531 | |
| 532 IPEndPoint fetched_remote_address; | |
| 533 rv = client.GetPeerAddress(&fetched_remote_address); | |
| 534 EXPECT_EQ(OK, rv); | |
| 535 | |
| 536 EXPECT_EQ(remote_address, fetched_remote_address); | |
| 537 } | |
| 538 } | |
| 539 | |
| 540 TEST_F(UDPSocketTest, ServerGetLocalAddress) { | |
| 541 IPEndPoint bind_address; | |
| 542 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
| 543 UDPServerSocket server(NULL, NetLog::Source()); | |
| 544 int rv = server.Listen(bind_address); | |
| 545 EXPECT_EQ(OK, rv); | |
| 546 | |
| 547 IPEndPoint local_address; | |
| 548 rv = server.GetLocalAddress(&local_address); | |
| 549 EXPECT_EQ(rv, 0); | |
| 550 | |
| 551 // Verify that port was allocated. | |
| 552 EXPECT_GT(local_address.port(), 0); | |
| 553 EXPECT_EQ(local_address.address(), bind_address.address()); | |
| 554 } | |
| 555 | |
| 556 TEST_F(UDPSocketTest, ServerGetPeerAddress) { | |
| 557 IPEndPoint bind_address; | |
| 558 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
| 559 UDPServerSocket server(NULL, NetLog::Source()); | |
| 560 int rv = server.Listen(bind_address); | |
| 561 EXPECT_EQ(OK, rv); | |
| 562 | |
| 563 IPEndPoint peer_address; | |
| 564 rv = server.GetPeerAddress(&peer_address); | |
| 565 EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED); | |
| 566 } | |
| 567 | |
| 568 // Close the socket while read is pending. | |
| 569 TEST_F(UDPSocketTest, CloseWithPendingRead) { | |
| 570 IPEndPoint bind_address; | |
| 571 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
| 572 UDPServerSocket server(NULL, NetLog::Source()); | |
| 573 int rv = server.Listen(bind_address); | |
| 574 EXPECT_EQ(OK, rv); | |
| 575 | |
| 576 TestCompletionCallback callback; | |
| 577 IPEndPoint from; | |
| 578 rv = server.RecvFrom(buffer_.get(), kMaxRead, &from, callback.callback()); | |
| 579 EXPECT_EQ(rv, ERR_IO_PENDING); | |
| 580 | |
| 581 server.Close(); | |
| 582 | |
| 583 EXPECT_FALSE(callback.have_result()); | |
| 584 } | |
| 585 | |
| 586 #if defined(OS_ANDROID) | |
| 587 // Some Android devices do not support multicast socket. | |
| 588 // The ones supporting multicast need WifiManager.MulitcastLock to enable it. | |
| 589 // http://goo.gl/jjAk9 | |
| 590 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup | |
| 591 #else | |
| 592 #define MAYBE_JoinMulticastGroup JoinMulticastGroup | |
| 593 #endif // defined(OS_ANDROID) | |
| 594 | |
| 595 TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) { | |
| 596 const uint16 kPort = 9999; | |
| 597 const char kGroup[] = "237.132.100.17"; | |
| 598 | |
| 599 IPEndPoint bind_address; | |
| 600 CreateUDPAddress("0.0.0.0", kPort, &bind_address); | |
| 601 IPAddressNumber group_ip; | |
| 602 EXPECT_TRUE(ParseIPLiteralToNumber(kGroup, &group_ip)); | |
| 603 | |
| 604 UDPSocket socket(DatagramSocket::DEFAULT_BIND, | |
| 605 RandIntCallback(), | |
| 606 NULL, | |
| 607 NetLog::Source()); | |
| 608 EXPECT_EQ(OK, socket.Open(bind_address.GetFamily())); | |
| 609 EXPECT_EQ(OK, socket.Bind(bind_address)); | |
| 610 EXPECT_EQ(OK, socket.JoinGroup(group_ip)); | |
| 611 // Joining group multiple times. | |
| 612 EXPECT_NE(OK, socket.JoinGroup(group_ip)); | |
| 613 EXPECT_EQ(OK, socket.LeaveGroup(group_ip)); | |
| 614 // Leaving group multiple times. | |
| 615 EXPECT_NE(OK, socket.LeaveGroup(group_ip)); | |
| 616 | |
| 617 socket.Close(); | |
| 618 } | |
| 619 | |
| 620 TEST_F(UDPSocketTest, MulticastOptions) { | |
| 621 const uint16 kPort = 9999; | |
| 622 IPEndPoint bind_address; | |
| 623 CreateUDPAddress("0.0.0.0", kPort, &bind_address); | |
| 624 | |
| 625 UDPSocket socket(DatagramSocket::DEFAULT_BIND, | |
| 626 RandIntCallback(), | |
| 627 NULL, | |
| 628 NetLog::Source()); | |
| 629 // Before binding. | |
| 630 EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(false)); | |
| 631 EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(true)); | |
| 632 EXPECT_EQ(OK, socket.SetMulticastTimeToLive(0)); | |
| 633 EXPECT_EQ(OK, socket.SetMulticastTimeToLive(3)); | |
| 634 EXPECT_NE(OK, socket.SetMulticastTimeToLive(-1)); | |
| 635 EXPECT_EQ(OK, socket.SetMulticastInterface(0)); | |
| 636 | |
| 637 EXPECT_EQ(OK, socket.Open(bind_address.GetFamily())); | |
| 638 EXPECT_EQ(OK, socket.Bind(bind_address)); | |
| 639 | |
| 640 EXPECT_NE(OK, socket.SetMulticastLoopbackMode(false)); | |
| 641 EXPECT_NE(OK, socket.SetMulticastTimeToLive(0)); | |
| 642 EXPECT_NE(OK, socket.SetMulticastInterface(0)); | |
| 643 | |
| 644 socket.Close(); | |
| 645 } | |
| 646 | |
| 647 // Checking that DSCP bits are set correctly is difficult, | |
| 648 // but let's check that the code doesn't crash at least. | |
| 649 TEST_F(UDPSocketTest, SetDSCP) { | |
| 650 // Setup the server to listen. | |
| 651 IPEndPoint bind_address; | |
| 652 UDPSocket client(DatagramSocket::DEFAULT_BIND, | |
| 653 RandIntCallback(), | |
| 654 NULL, | |
| 655 NetLog::Source()); | |
| 656 // We need a real IP, but we won't actually send anything to it. | |
| 657 CreateUDPAddress("8.8.8.8", 9999, &bind_address); | |
| 658 int rv = client.Open(bind_address.GetFamily()); | |
| 659 EXPECT_EQ(OK, rv); | |
| 660 | |
| 661 rv = client.Connect(bind_address); | |
| 662 if (rv != OK) { | |
| 663 // Let's try localhost then.. | |
| 664 CreateUDPAddress("127.0.0.1", 9999, &bind_address); | |
| 665 rv = client.Connect(bind_address); | |
| 666 } | |
| 667 EXPECT_EQ(OK, rv); | |
| 668 | |
| 669 client.SetDiffServCodePoint(DSCP_NO_CHANGE); | |
| 670 client.SetDiffServCodePoint(DSCP_AF41); | |
| 671 client.SetDiffServCodePoint(DSCP_DEFAULT); | |
| 672 client.SetDiffServCodePoint(DSCP_CS2); | |
| 673 client.SetDiffServCodePoint(DSCP_NO_CHANGE); | |
| 674 client.SetDiffServCodePoint(DSCP_DEFAULT); | |
| 675 client.Close(); | |
| 676 } | |
| 677 | |
| 678 } // namespace | |
| 679 | |
| 680 #if defined(OS_WIN) | |
| 681 | |
| 682 namespace { | |
| 683 | |
| 684 const HANDLE kFakeHandle = (HANDLE)19; | |
| 685 const QOS_FLOWID kFakeFlowId = (QOS_FLOWID)27; | |
| 686 | |
| 687 BOOL WINAPI FakeQOSCreateHandleFAIL(PQOS_VERSION version, PHANDLE handle) { | |
| 688 EXPECT_EQ(0, version->MinorVersion); | |
| 689 EXPECT_EQ(1, version->MajorVersion); | |
| 690 SetLastError(ERROR_OPEN_FAILED); | |
| 691 return false; | |
| 692 } | |
| 693 | |
| 694 BOOL WINAPI FakeQOSCreateHandle(PQOS_VERSION version, PHANDLE handle) { | |
| 695 EXPECT_EQ(0, version->MinorVersion); | |
| 696 EXPECT_EQ(1, version->MajorVersion); | |
| 697 *handle = kFakeHandle; | |
| 698 return true; | |
| 699 } | |
| 700 | |
| 701 BOOL WINAPI FakeQOSCloseHandle(HANDLE handle) { | |
| 702 EXPECT_EQ(kFakeHandle, handle); | |
| 703 return true; | |
| 704 } | |
| 705 | |
| 706 QOS_TRAFFIC_TYPE g_expected_traffic_type; | |
| 707 | |
| 708 BOOL WINAPI FakeQOSAddSocketToFlow(HANDLE handle, | |
| 709 SOCKET socket, | |
| 710 PSOCKADDR addr, | |
| 711 QOS_TRAFFIC_TYPE traffic_type, | |
| 712 DWORD flags, | |
| 713 PQOS_FLOWID flow_id) { | |
| 714 EXPECT_EQ(kFakeHandle, handle); | |
| 715 EXPECT_EQ(NULL, addr); | |
| 716 EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW, flags); | |
| 717 EXPECT_EQ(0, *flow_id); | |
| 718 *flow_id = kFakeFlowId; | |
| 719 return true; | |
| 720 } | |
| 721 | |
| 722 BOOL WINAPI FakeQOSRemoveSocketFromFlow(HANDLE handle, | |
| 723 SOCKET socket, | |
| 724 QOS_FLOWID flowid, | |
| 725 DWORD reserved) { | |
| 726 EXPECT_EQ(kFakeHandle, handle); | |
| 727 EXPECT_EQ(NULL, socket); | |
| 728 EXPECT_EQ(kFakeFlowId, flowid); | |
| 729 EXPECT_EQ(0, reserved); | |
| 730 return true; | |
| 731 } | |
| 732 | |
| 733 DWORD g_expected_dscp; | |
| 734 | |
| 735 BOOL WINAPI FakeQOSSetFlow(HANDLE handle, | |
| 736 QOS_FLOWID flow_id, | |
| 737 QOS_SET_FLOW op, | |
| 738 ULONG size, | |
| 739 PVOID data, | |
| 740 DWORD reserved, | |
| 741 LPOVERLAPPED overlapped) { | |
| 742 EXPECT_EQ(kFakeHandle, handle); | |
| 743 EXPECT_EQ(QOSSetOutgoingDSCPValue, op); | |
| 744 EXPECT_EQ(sizeof(DWORD), size); | |
| 745 EXPECT_EQ(g_expected_dscp, *reinterpret_cast<DWORD*>(data)); | |
| 746 EXPECT_EQ(kFakeFlowId, flow_id); | |
| 747 EXPECT_EQ(0, reserved); | |
| 748 EXPECT_EQ(NULL, overlapped); | |
| 749 return true; | |
| 750 } | |
| 751 | |
| 752 } // namespace | |
| 753 | |
| 754 // Mock out the Qwave functions and make sure they are | |
| 755 // called correctly. Must be in net namespace for friendship | |
| 756 // reasons. | |
| 757 TEST_F(UDPSocketTest, SetDSCPFake) { | |
| 758 // Setup the server to listen. | |
| 759 IPEndPoint bind_address; | |
| 760 // We need a real IP, but we won't actually send anything to it. | |
| 761 CreateUDPAddress("8.8.8.8", 9999, &bind_address); | |
| 762 UDPSocket client(DatagramSocket::DEFAULT_BIND, | |
| 763 RandIntCallback(), | |
| 764 NULL, | |
| 765 NetLog::Source()); | |
| 766 int rv = client.SetDiffServCodePoint(DSCP_AF41); | |
| 767 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, rv); | |
| 768 | |
| 769 rv = client.Open(bind_address.GetFamily()); | |
| 770 EXPECT_EQ(OK, rv); | |
| 771 | |
| 772 rv = client.Connect(bind_address); | |
| 773 EXPECT_EQ(OK, rv); | |
| 774 | |
| 775 QwaveAPI& qos(QwaveAPI::Get()); | |
| 776 qos.create_handle_func_ = FakeQOSCreateHandleFAIL; | |
| 777 qos.close_handle_func_ = FakeQOSCloseHandle; | |
| 778 qos.add_socket_to_flow_func_ = FakeQOSAddSocketToFlow; | |
| 779 qos.remove_socket_from_flow_func_ = FakeQOSRemoveSocketFromFlow; | |
| 780 qos.set_flow_func_ = FakeQOSSetFlow; | |
| 781 qos.qwave_supported_ = true; | |
| 782 | |
| 783 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE)); | |
| 784 EXPECT_EQ(ERROR_NOT_SUPPORTED, client.SetDiffServCodePoint(DSCP_AF41)); | |
| 785 qos.create_handle_func_ = FakeQOSCreateHandle; | |
| 786 g_expected_dscp = DSCP_AF41; | |
| 787 g_expected_traffic_type = QOSTrafficTypeAudioVideo; | |
| 788 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_AF41)); | |
| 789 g_expected_dscp = DSCP_DEFAULT; | |
| 790 g_expected_traffic_type = QOSTrafficTypeBestEffort; | |
| 791 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT)); | |
| 792 g_expected_dscp = DSCP_CS2; | |
| 793 g_expected_traffic_type = QOSTrafficTypeExcellentEffort; | |
| 794 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_CS2)); | |
| 795 g_expected_dscp = DSCP_CS3; | |
| 796 g_expected_traffic_type = QOSTrafficTypeExcellentEffort; | |
| 797 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE)); | |
| 798 g_expected_dscp = DSCP_DEFAULT; | |
| 799 g_expected_traffic_type = QOSTrafficTypeBestEffort; | |
| 800 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT)); | |
| 801 client.Close(); | |
| 802 } | |
| 803 #endif | |
| 804 | |
| 805 } // namespace net | |
| OLD | NEW |