Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: net/udp/udp_socket_unittest.cc

Issue 2508593002: net: move udp directory into socket (Closed)
Patch Set: revert sys/socket.h change Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/udp/udp_socket_posix.cc ('k') | net/udp/udp_socket_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « net/udp/udp_socket_posix.cc ('k') | net/udp/udp_socket_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698