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