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