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/metrics/histogram.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/ip_endpoint.h"
21 #include "net/base/net_errors.h"
22 #include "net/base/net_util.h"
23 #include "net/base/test_completion_callback.h"
24 #include "net/log/test_net_log.h"
25 #include "net/log/test_net_log_entry.h"
26 #include "net/log/test_net_log_util.h"
27 #include "net/test/net_test_suite.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
35 class UDPSocketTest
: public PlatformTest
{
37 UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead
)) {}
39 // Blocks until data is read from the socket.
40 std::string
RecvFromSocket(UDPServerSocket
* socket
) {
41 TestCompletionCallback callback
;
43 int rv
= socket
->RecvFrom(
44 buffer_
.get(), kMaxRead
, &recv_from_address_
, callback
.callback());
45 if (rv
== ERR_IO_PENDING
)
46 rv
= callback
.WaitForResult();
48 return std::string(); // error!
49 return std::string(buffer_
->data(), rv
);
52 // Loop until |msg| has been written to the socket or until an
54 // If |address| is specified, then it is used for the destination
55 // to send to. Otherwise, will send to the last socket this server
57 int SendToSocket(UDPServerSocket
* socket
, std::string msg
) {
58 return SendToSocket(socket
, msg
, recv_from_address_
);
61 int SendToSocket(UDPServerSocket
* socket
,
63 const IPEndPoint
& address
) {
64 TestCompletionCallback callback
;
66 int length
= msg
.length();
67 scoped_refptr
<StringIOBuffer
> io_buffer(new StringIOBuffer(msg
));
68 scoped_refptr
<DrainableIOBuffer
> buffer(
69 new DrainableIOBuffer(io_buffer
.get(), length
));
72 while (buffer
->BytesRemaining()) {
73 int rv
= socket
->SendTo(
74 buffer
.get(), buffer
->BytesRemaining(), address
, callback
.callback());
75 if (rv
== ERR_IO_PENDING
)
76 rv
= callback
.WaitForResult();
78 return bytes_sent
> 0 ? bytes_sent
: rv
;
80 buffer
->DidConsume(rv
);
85 std::string
ReadSocket(UDPClientSocket
* socket
) {
86 TestCompletionCallback callback
;
88 int rv
= socket
->Read(buffer_
.get(), kMaxRead
, callback
.callback());
89 if (rv
== ERR_IO_PENDING
)
90 rv
= callback
.WaitForResult();
92 return std::string(); // error!
93 return std::string(buffer_
->data(), rv
);
96 // Loop until |msg| has been written to the socket or until an
98 int WriteSocket(UDPClientSocket
* socket
, std::string msg
) {
99 TestCompletionCallback callback
;
101 int length
= msg
.length();
102 scoped_refptr
<StringIOBuffer
> io_buffer(new StringIOBuffer(msg
));
103 scoped_refptr
<DrainableIOBuffer
> buffer(
104 new DrainableIOBuffer(io_buffer
.get(), length
));
107 while (buffer
->BytesRemaining()) {
108 int rv
= socket
->Write(
109 buffer
.get(), buffer
->BytesRemaining(), callback
.callback());
110 if (rv
== ERR_IO_PENDING
)
111 rv
= callback
.WaitForResult();
113 return bytes_sent
> 0 ? bytes_sent
: rv
;
115 buffer
->DidConsume(rv
);
120 void WriteSocketIgnoreResult(UDPClientSocket
* socket
, std::string msg
) {
121 WriteSocket(socket
, msg
);
124 // Creates an address from ip address and port and writes it to |*address|.
125 void CreateUDPAddress(std::string ip_str
, uint16 port
, IPEndPoint
* address
) {
126 IPAddressNumber ip_number
;
127 bool rv
= ParseIPLiteralToNumber(ip_str
, &ip_number
);
130 *address
= IPEndPoint(ip_number
, port
);
133 // Run unit test for a connection test.
134 // |use_nonblocking_io| is used to switch between overlapped and non-blocking
135 // IO on Windows. It has no effect in other ports.
136 void ConnectTest(bool use_nonblocking_io
);
139 static const int kMaxRead
= 1024;
140 scoped_refptr
<IOBufferWithSize
> buffer_
;
141 IPEndPoint recv_from_address_
;
144 void ReadCompleteCallback(int* result_out
, base::Closure callback
, int result
) {
145 *result_out
= result
;
149 void UDPSocketTest::ConnectTest(bool use_nonblocking_io
) {
150 const uint16 kPort
= 9999;
151 std::string
simple_message("hello world!");
153 // Setup the server to listen.
154 IPEndPoint bind_address
;
155 CreateUDPAddress("127.0.0.1", kPort
, &bind_address
);
156 TestNetLog server_log
;
157 scoped_ptr
<UDPServerSocket
> server(
158 new UDPServerSocket(&server_log
, NetLog::Source()));
160 if (use_nonblocking_io
)
161 server
->UseNonBlockingIO();
163 server
->AllowAddressReuse();
164 int rv
= server
->Listen(bind_address
);
168 IPEndPoint server_address
;
169 CreateUDPAddress("127.0.0.1", kPort
, &server_address
);
170 TestNetLog client_log
;
171 scoped_ptr
<UDPClientSocket
> client(
172 new UDPClientSocket(DatagramSocket::DEFAULT_BIND
, RandIntCallback(),
173 &client_log
, NetLog::Source()));
175 if (use_nonblocking_io
)
176 client
->UseNonBlockingIO();
179 rv
= client
->Connect(server_address
);
182 // Client sends to the server.
183 rv
= WriteSocket(client
.get(), simple_message
);
184 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
186 // Server waits for message.
187 std::string str
= RecvFromSocket(server
.get());
188 DCHECK(simple_message
== str
);
190 // Server echoes reply.
191 rv
= SendToSocket(server
.get(), simple_message
);
192 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
194 // Client waits for response.
195 str
= ReadSocket(client
.get());
196 DCHECK(simple_message
== str
);
198 // Test asynchronous read. Server waits for message.
199 base::RunLoop run_loop
;
201 rv
= server
->RecvFrom(
202 buffer_
.get(), kMaxRead
, &recv_from_address_
,
203 base::Bind(&ReadCompleteCallback
, &read_result
, run_loop
.QuitClosure()));
204 EXPECT_EQ(ERR_IO_PENDING
, rv
);
206 // Client sends to the server.
207 base::ThreadTaskRunnerHandle::Get()->PostTask(
209 base::Bind(&UDPSocketTest::WriteSocketIgnoreResult
,
210 base::Unretained(this), client
.get(), simple_message
));
212 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(read_result
));
213 EXPECT_EQ(simple_message
, std::string(buffer_
->data(), read_result
));
215 // Delete sockets so they log their final events.
219 // Check the server's log.
220 TestNetLogEntry::List server_entries
;
221 server_log
.GetEntries(&server_entries
);
222 EXPECT_EQ(5u, server_entries
.size());
224 LogContainsBeginEvent(server_entries
, 0, NetLog::TYPE_SOCKET_ALIVE
));
225 EXPECT_TRUE(LogContainsEvent(
226 server_entries
, 1, NetLog::TYPE_UDP_BYTES_RECEIVED
, NetLog::PHASE_NONE
));
227 EXPECT_TRUE(LogContainsEvent(server_entries
, 2, NetLog::TYPE_UDP_BYTES_SENT
,
228 NetLog::PHASE_NONE
));
229 EXPECT_TRUE(LogContainsEvent(
230 server_entries
, 3, NetLog::TYPE_UDP_BYTES_RECEIVED
, NetLog::PHASE_NONE
));
232 LogContainsEndEvent(server_entries
, 4, NetLog::TYPE_SOCKET_ALIVE
));
234 // Check the client's log.
235 TestNetLogEntry::List client_entries
;
236 client_log
.GetEntries(&client_entries
);
237 EXPECT_EQ(7u, client_entries
.size());
239 LogContainsBeginEvent(client_entries
, 0, NetLog::TYPE_SOCKET_ALIVE
));
241 LogContainsBeginEvent(client_entries
, 1, NetLog::TYPE_UDP_CONNECT
));
242 EXPECT_TRUE(LogContainsEndEvent(client_entries
, 2, NetLog::TYPE_UDP_CONNECT
));
243 EXPECT_TRUE(LogContainsEvent(client_entries
, 3, NetLog::TYPE_UDP_BYTES_SENT
,
244 NetLog::PHASE_NONE
));
245 EXPECT_TRUE(LogContainsEvent(
246 client_entries
, 4, NetLog::TYPE_UDP_BYTES_RECEIVED
, NetLog::PHASE_NONE
));
247 EXPECT_TRUE(LogContainsEvent(client_entries
, 5, NetLog::TYPE_UDP_BYTES_SENT
,
248 NetLog::PHASE_NONE
));
250 LogContainsEndEvent(client_entries
, 6, NetLog::TYPE_SOCKET_ALIVE
));
253 TEST_F(UDPSocketTest
, Connect
) {
254 // The variable |use_nonblocking_io| has no effect in non-Windows ports.
259 TEST_F(UDPSocketTest
, ConnectNonBlocking
) {
264 #if defined(OS_MACOSX)
265 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires
266 // root permissions on OSX 10.7+.
267 TEST_F(UDPSocketTest
, DISABLED_Broadcast
) {
268 #elif defined(OS_ANDROID)
269 // It is also disabled for Android because it is extremely flaky.
270 // The first call to SendToSocket returns -109 (Address not reachable)
271 // in some unpredictable cases. crbug.com/139144.
272 TEST_F(UDPSocketTest
, DISABLED_Broadcast
) {
274 TEST_F(UDPSocketTest
, Broadcast
) {
276 const uint16 kPort
= 9999;
277 std::string
first_message("first message"), second_message("second message");
279 IPEndPoint broadcast_address
;
280 CreateUDPAddress("255.255.255.255", kPort
, &broadcast_address
);
281 IPEndPoint listen_address
;
282 CreateUDPAddress("0.0.0.0", kPort
, &listen_address
);
284 TestNetLog server1_log
, server2_log
;
285 scoped_ptr
<UDPServerSocket
> server1(
286 new UDPServerSocket(&server1_log
, NetLog::Source()));
287 scoped_ptr
<UDPServerSocket
> server2(
288 new UDPServerSocket(&server2_log
, NetLog::Source()));
289 server1
->AllowAddressReuse();
290 server1
->AllowBroadcast();
291 server2
->AllowAddressReuse();
292 server2
->AllowBroadcast();
294 int rv
= server1
->Listen(listen_address
);
296 rv
= server2
->Listen(listen_address
);
299 rv
= SendToSocket(server1
.get(), first_message
, broadcast_address
);
300 ASSERT_EQ(static_cast<int>(first_message
.size()), rv
);
301 std::string str
= RecvFromSocket(server1
.get());
302 ASSERT_EQ(first_message
, str
);
303 str
= RecvFromSocket(server2
.get());
304 ASSERT_EQ(first_message
, str
);
306 rv
= SendToSocket(server2
.get(), second_message
, broadcast_address
);
307 ASSERT_EQ(static_cast<int>(second_message
.size()), rv
);
308 str
= RecvFromSocket(server1
.get());
309 ASSERT_EQ(second_message
, str
);
310 str
= RecvFromSocket(server2
.get());
311 ASSERT_EQ(second_message
, str
);
314 // In this test, we verify that random binding logic works, which attempts
315 // to bind to a random port and returns if succeeds, otherwise retries for
316 // |kBindRetries| number of times.
318 // To generate the scenario, we first create |kBindRetries| number of
319 // UDPClientSockets with default binding policy and connect to the same
320 // peer and save the used port numbers. Then we get rid of the last
321 // socket, making sure that the local port it was bound to is available.
322 // Finally, we create a socket with random binding policy, passing it a
323 // test PRNG that would serve used port numbers in the array, one after
324 // another. At the end, we make sure that the test socket was bound to the
325 // port that became available after deleting the last socket with default
328 // We do not test the randomness of bound ports, but that we are using
329 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
331 static const int kBindRetries
= 10;
335 explicit TestPrng(const std::deque
<int>& numbers
) : numbers_(numbers
) {}
336 int GetNext(int /* min */, int /* max */) {
337 DCHECK(!numbers_
.empty());
338 int rv
= numbers_
.front();
339 numbers_
.pop_front();
343 std::deque
<int> numbers_
;
345 DISALLOW_COPY_AND_ASSIGN(TestPrng
);
348 #if defined(OS_ANDROID)
349 // Disabled on Android for lack of 192.168.1.13. crbug.com/161245
350 TEST_F(UDPSocketTest
, DISABLED_ConnectRandomBind
) {
352 TEST_F(UDPSocketTest
, ConnectRandomBind
) {
354 std::vector
<UDPClientSocket
*> sockets
;
355 IPEndPoint peer_address
;
356 CreateUDPAddress("192.168.1.13", 53, &peer_address
);
358 // Create and connect sockets and save port numbers.
359 std::deque
<int> used_ports
;
360 for (int i
= 0; i
< kBindRetries
; ++i
) {
361 UDPClientSocket
* socket
=
362 new UDPClientSocket(DatagramSocket::DEFAULT_BIND
,
366 sockets
.push_back(socket
);
367 EXPECT_EQ(OK
, socket
->Connect(peer_address
));
369 IPEndPoint client_address
;
370 EXPECT_EQ(OK
, socket
->GetLocalAddress(&client_address
));
371 used_ports
.push_back(client_address
.port());
374 // Free the last socket, its local port is still in |used_ports|.
375 delete sockets
.back();
378 TestPrng
test_prng(used_ports
);
379 RandIntCallback rand_int_cb
=
380 base::Bind(&TestPrng::GetNext
, base::Unretained(&test_prng
));
382 // Create a socket with random binding policy and connect.
383 scoped_ptr
<UDPClientSocket
> test_socket(
384 new UDPClientSocket(DatagramSocket::RANDOM_BIND
,
388 EXPECT_EQ(OK
, test_socket
->Connect(peer_address
));
390 // Make sure that the last port number in the |used_ports| was used.
391 IPEndPoint client_address
;
392 EXPECT_EQ(OK
, test_socket
->GetLocalAddress(&client_address
));
393 EXPECT_EQ(used_ports
.back(), client_address
.port());
395 STLDeleteElements(&sockets
);
398 // Return a privileged port (under 1024) so binding will fail.
399 int PrivilegedRand(int min
, int max
) {
400 // Chosen by fair dice roll. Guaranteed to be random.
404 TEST_F(UDPSocketTest
, ConnectFail
) {
405 IPEndPoint peer_address
;
406 CreateUDPAddress("0.0.0.0", 53, &peer_address
);
408 scoped_ptr
<UDPSocket
> socket(
409 new UDPSocket(DatagramSocket::RANDOM_BIND
,
410 base::Bind(&PrivilegedRand
),
413 int rv
= socket
->Open(peer_address
.GetFamily());
415 rv
= socket
->Connect(peer_address
);
416 // Connect should have failed since we couldn't bind to that port,
418 // Make sure that UDPSocket actually closed the socket.
419 EXPECT_FALSE(socket
->is_connected());
422 // In this test, we verify that connect() on a socket will have the effect
423 // of filtering reads on this socket only to data read from the destination
426 // The purpose of this test is that some documentation indicates that connect
427 // binds the client's sends to send to a particular server endpoint, but does
428 // not bind the client's reads to only be from that endpoint, and that we need
429 // to always use recvfrom() to disambiguate.
430 TEST_F(UDPSocketTest
, VerifyConnectBindsAddr
) {
431 const uint16 kPort1
= 9999;
432 const uint16 kPort2
= 10000;
433 std::string
simple_message("hello world!");
434 std::string
foreign_message("BAD MESSAGE TO GET!!");
436 // Setup the first server to listen.
437 IPEndPoint bind_address
;
438 CreateUDPAddress("127.0.0.1", kPort1
, &bind_address
);
439 UDPServerSocket
server1(NULL
, NetLog::Source());
440 server1
.AllowAddressReuse();
441 int rv
= server1
.Listen(bind_address
);
444 // Setup the second server to listen.
445 CreateUDPAddress("127.0.0.1", kPort2
, &bind_address
);
446 UDPServerSocket
server2(NULL
, NetLog::Source());
447 server2
.AllowAddressReuse();
448 rv
= server2
.Listen(bind_address
);
451 // Setup the client, connected to server 1.
452 IPEndPoint server_address
;
453 CreateUDPAddress("127.0.0.1", kPort1
, &server_address
);
454 UDPClientSocket
client(DatagramSocket::DEFAULT_BIND
,
458 rv
= client
.Connect(server_address
);
461 // Client sends to server1.
462 rv
= WriteSocket(&client
, simple_message
);
463 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
465 // Server1 waits for message.
466 std::string str
= RecvFromSocket(&server1
);
467 DCHECK(simple_message
== str
);
469 // Get the client's address.
470 IPEndPoint client_address
;
471 rv
= client
.GetLocalAddress(&client_address
);
474 // Server2 sends reply.
475 rv
= SendToSocket(&server2
, foreign_message
,
477 EXPECT_EQ(foreign_message
.length(), static_cast<size_t>(rv
));
479 // Server1 sends reply.
480 rv
= SendToSocket(&server1
, simple_message
,
482 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
484 // Client waits for response.
485 str
= ReadSocket(&client
);
486 DCHECK(simple_message
== str
);
489 TEST_F(UDPSocketTest
, ClientGetLocalPeerAddresses
) {
491 std::string remote_address
;
492 std::string local_address
;
495 { "127.0.00.1", "127.0.0.1", false },
496 { "::1", "::1", true },
497 #if !defined(OS_ANDROID)
498 // Addresses below are disabled on Android. See crbug.com/161248
499 { "192.168.1.1", "127.0.0.1", false },
500 { "2001:db8:0::42", "::1", true },
503 for (size_t i
= 0; i
< arraysize(tests
); i
++) {
504 SCOPED_TRACE(std::string("Connecting from ") + tests
[i
].local_address
+
505 std::string(" to ") + tests
[i
].remote_address
);
507 IPAddressNumber ip_number
;
508 ParseIPLiteralToNumber(tests
[i
].remote_address
, &ip_number
);
509 IPEndPoint
remote_address(ip_number
, 80);
510 ParseIPLiteralToNumber(tests
[i
].local_address
, &ip_number
);
511 IPEndPoint
local_address(ip_number
, 80);
513 UDPClientSocket
client(DatagramSocket::DEFAULT_BIND
,
517 int rv
= client
.Connect(remote_address
);
518 if (tests
[i
].may_fail
&& rv
== ERR_ADDRESS_UNREACHABLE
) {
519 // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
520 // addresses if IPv6 is not configured.
524 EXPECT_LE(ERR_IO_PENDING
, rv
);
526 IPEndPoint fetched_local_address
;
527 rv
= client
.GetLocalAddress(&fetched_local_address
);
530 // TODO(mbelshe): figure out how to verify the IP and port.
531 // The port is dynamically generated by the udp stack.
532 // The IP is the real IP of the client, not necessarily
534 //EXPECT_EQ(local_address.address(), fetched_local_address.address());
536 IPEndPoint fetched_remote_address
;
537 rv
= client
.GetPeerAddress(&fetched_remote_address
);
540 EXPECT_EQ(remote_address
, fetched_remote_address
);
544 TEST_F(UDPSocketTest
, ServerGetLocalAddress
) {
545 IPEndPoint bind_address
;
546 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
547 UDPServerSocket
server(NULL
, NetLog::Source());
548 int rv
= server
.Listen(bind_address
);
551 IPEndPoint local_address
;
552 rv
= server
.GetLocalAddress(&local_address
);
555 // Verify that port was allocated.
556 EXPECT_GT(local_address
.port(), 0);
557 EXPECT_EQ(local_address
.address(), bind_address
.address());
560 TEST_F(UDPSocketTest
, ServerGetPeerAddress
) {
561 IPEndPoint bind_address
;
562 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
563 UDPServerSocket
server(NULL
, NetLog::Source());
564 int rv
= server
.Listen(bind_address
);
567 IPEndPoint peer_address
;
568 rv
= server
.GetPeerAddress(&peer_address
);
569 EXPECT_EQ(rv
, ERR_SOCKET_NOT_CONNECTED
);
572 // Close the socket while read is pending.
573 TEST_F(UDPSocketTest
, CloseWithPendingRead
) {
574 IPEndPoint bind_address
;
575 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
576 UDPServerSocket
server(NULL
, NetLog::Source());
577 int rv
= server
.Listen(bind_address
);
580 TestCompletionCallback callback
;
582 rv
= server
.RecvFrom(buffer_
.get(), kMaxRead
, &from
, callback
.callback());
583 EXPECT_EQ(rv
, ERR_IO_PENDING
);
587 EXPECT_FALSE(callback
.have_result());
590 #if defined(OS_ANDROID)
591 // Some Android devices do not support multicast socket.
592 // The ones supporting multicast need WifiManager.MulitcastLock to enable it.
593 // http://goo.gl/jjAk9
594 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup
596 #define MAYBE_JoinMulticastGroup JoinMulticastGroup
597 #endif // defined(OS_ANDROID)
599 TEST_F(UDPSocketTest
, MAYBE_JoinMulticastGroup
) {
600 const uint16 kPort
= 9999;
601 const char kGroup
[] = "237.132.100.17";
603 IPEndPoint bind_address
;
604 CreateUDPAddress("0.0.0.0", kPort
, &bind_address
);
605 IPAddressNumber group_ip
;
606 EXPECT_TRUE(ParseIPLiteralToNumber(kGroup
, &group_ip
));
608 UDPSocket
socket(DatagramSocket::DEFAULT_BIND
,
612 EXPECT_EQ(OK
, socket
.Open(bind_address
.GetFamily()));
613 EXPECT_EQ(OK
, socket
.Bind(bind_address
));
614 EXPECT_EQ(OK
, socket
.JoinGroup(group_ip
));
615 // Joining group multiple times.
616 EXPECT_NE(OK
, socket
.JoinGroup(group_ip
));
617 EXPECT_EQ(OK
, socket
.LeaveGroup(group_ip
));
618 // Leaving group multiple times.
619 EXPECT_NE(OK
, socket
.LeaveGroup(group_ip
));
624 TEST_F(UDPSocketTest
, MulticastOptions
) {
625 const uint16 kPort
= 9999;
626 IPEndPoint bind_address
;
627 CreateUDPAddress("0.0.0.0", kPort
, &bind_address
);
629 UDPSocket
socket(DatagramSocket::DEFAULT_BIND
,
634 EXPECT_EQ(OK
, socket
.SetMulticastLoopbackMode(false));
635 EXPECT_EQ(OK
, socket
.SetMulticastLoopbackMode(true));
636 EXPECT_EQ(OK
, socket
.SetMulticastTimeToLive(0));
637 EXPECT_EQ(OK
, socket
.SetMulticastTimeToLive(3));
638 EXPECT_NE(OK
, socket
.SetMulticastTimeToLive(-1));
639 EXPECT_EQ(OK
, socket
.SetMulticastInterface(0));
641 EXPECT_EQ(OK
, socket
.Open(bind_address
.GetFamily()));
642 EXPECT_EQ(OK
, socket
.Bind(bind_address
));
644 EXPECT_NE(OK
, socket
.SetMulticastLoopbackMode(false));
645 EXPECT_NE(OK
, socket
.SetMulticastTimeToLive(0));
646 EXPECT_NE(OK
, socket
.SetMulticastInterface(0));
651 // Checking that DSCP bits are set correctly is difficult,
652 // but let's check that the code doesn't crash at least.
653 TEST_F(UDPSocketTest
, SetDSCP
) {
654 // Setup the server to listen.
655 IPEndPoint bind_address
;
656 UDPSocket
client(DatagramSocket::DEFAULT_BIND
,
660 // We need a real IP, but we won't actually send anything to it.
661 CreateUDPAddress("8.8.8.8", 9999, &bind_address
);
662 int rv
= client
.Open(bind_address
.GetFamily());
665 rv
= client
.Connect(bind_address
);
667 // Let's try localhost then..
668 CreateUDPAddress("127.0.0.1", 9999, &bind_address
);
669 rv
= client
.Connect(bind_address
);
673 client
.SetDiffServCodePoint(DSCP_NO_CHANGE
);
674 client
.SetDiffServCodePoint(DSCP_AF41
);
675 client
.SetDiffServCodePoint(DSCP_DEFAULT
);
676 client
.SetDiffServCodePoint(DSCP_CS2
);
677 client
.SetDiffServCodePoint(DSCP_NO_CHANGE
);
678 client
.SetDiffServCodePoint(DSCP_DEFAULT
);
688 const HANDLE kFakeHandle
= (HANDLE
)19;
689 const QOS_FLOWID kFakeFlowId
= (QOS_FLOWID
)27;
691 BOOL WINAPI
FakeQOSCreateHandleFAIL(PQOS_VERSION version
, PHANDLE handle
) {
692 EXPECT_EQ(0, version
->MinorVersion
);
693 EXPECT_EQ(1, version
->MajorVersion
);
694 SetLastError(ERROR_OPEN_FAILED
);
698 BOOL WINAPI
FakeQOSCreateHandle(PQOS_VERSION version
, PHANDLE handle
) {
699 EXPECT_EQ(0, version
->MinorVersion
);
700 EXPECT_EQ(1, version
->MajorVersion
);
701 *handle
= kFakeHandle
;
705 BOOL WINAPI
FakeQOSCloseHandle(HANDLE handle
) {
706 EXPECT_EQ(kFakeHandle
, handle
);
710 QOS_TRAFFIC_TYPE g_expected_traffic_type
;
712 BOOL WINAPI
FakeQOSAddSocketToFlow(HANDLE handle
,
715 QOS_TRAFFIC_TYPE traffic_type
,
717 PQOS_FLOWID flow_id
) {
718 EXPECT_EQ(kFakeHandle
, handle
);
719 EXPECT_EQ(NULL
, addr
);
720 EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW
, flags
);
721 EXPECT_EQ(0, *flow_id
);
722 *flow_id
= kFakeFlowId
;
726 BOOL WINAPI
FakeQOSRemoveSocketFromFlow(HANDLE handle
,
730 EXPECT_EQ(kFakeHandle
, handle
);
731 EXPECT_EQ(NULL
, socket
);
732 EXPECT_EQ(kFakeFlowId
, flowid
);
733 EXPECT_EQ(0, reserved
);
737 DWORD g_expected_dscp
;
739 BOOL WINAPI
FakeQOSSetFlow(HANDLE handle
,
745 LPOVERLAPPED overlapped
) {
746 EXPECT_EQ(kFakeHandle
, handle
);
747 EXPECT_EQ(QOSSetOutgoingDSCPValue
, op
);
748 EXPECT_EQ(sizeof(DWORD
), size
);
749 EXPECT_EQ(g_expected_dscp
, *reinterpret_cast<DWORD
*>(data
));
750 EXPECT_EQ(kFakeFlowId
, flow_id
);
751 EXPECT_EQ(0, reserved
);
752 EXPECT_EQ(NULL
, overlapped
);
758 // Mock out the Qwave functions and make sure they are
759 // called correctly. Must be in net namespace for friendship
761 TEST_F(UDPSocketTest
, SetDSCPFake
) {
762 // Setup the server to listen.
763 IPEndPoint bind_address
;
764 // We need a real IP, but we won't actually send anything to it.
765 CreateUDPAddress("8.8.8.8", 9999, &bind_address
);
766 UDPSocket
client(DatagramSocket::DEFAULT_BIND
,
770 int rv
= client
.SetDiffServCodePoint(DSCP_AF41
);
771 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, rv
);
773 rv
= client
.Open(bind_address
.GetFamily());
776 rv
= client
.Connect(bind_address
);
779 QwaveAPI
& qos(QwaveAPI::Get());
780 qos
.create_handle_func_
= FakeQOSCreateHandleFAIL
;
781 qos
.close_handle_func_
= FakeQOSCloseHandle
;
782 qos
.add_socket_to_flow_func_
= FakeQOSAddSocketToFlow
;
783 qos
.remove_socket_from_flow_func_
= FakeQOSRemoveSocketFromFlow
;
784 qos
.set_flow_func_
= FakeQOSSetFlow
;
785 qos
.qwave_supported_
= true;
787 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_NO_CHANGE
));
788 EXPECT_EQ(ERROR_NOT_SUPPORTED
, client
.SetDiffServCodePoint(DSCP_AF41
));
789 qos
.create_handle_func_
= FakeQOSCreateHandle
;
790 g_expected_dscp
= DSCP_AF41
;
791 g_expected_traffic_type
= QOSTrafficTypeAudioVideo
;
792 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_AF41
));
793 g_expected_dscp
= DSCP_DEFAULT
;
794 g_expected_traffic_type
= QOSTrafficTypeBestEffort
;
795 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_DEFAULT
));
796 g_expected_dscp
= DSCP_CS2
;
797 g_expected_traffic_type
= QOSTrafficTypeExcellentEffort
;
798 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_CS2
));
799 g_expected_dscp
= DSCP_CS3
;
800 g_expected_traffic_type
= QOSTrafficTypeExcellentEffort
;
801 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_NO_CHANGE
));
802 g_expected_dscp
= DSCP_DEFAULT
;
803 g_expected_traffic_type
= QOSTrafficTypeBestEffort
;
804 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_DEFAULT
));