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