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/metrics/histogram.h"
13 #include "base/stl_util.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/ip_endpoint.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/net_log_unittest.h"
18 #include "net/base/net_util.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/test/net_test_suite.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/platform_test.h"
28 class UDPSocketTest
: public PlatformTest
{
31 : buffer_(new IOBufferWithSize(kMaxRead
)) {
34 // Blocks until data is read from the socket.
35 std::string
RecvFromSocket(UDPServerSocket
* socket
) {
36 TestCompletionCallback callback
;
38 int rv
= socket
->RecvFrom(
39 buffer_
.get(), kMaxRead
, &recv_from_address_
, callback
.callback());
40 if (rv
== ERR_IO_PENDING
)
41 rv
= callback
.WaitForResult();
43 return std::string(); // error!
44 return std::string(buffer_
->data(), rv
);
47 // Loop until |msg| has been written to the socket or until an
49 // If |address| is specified, then it is used for the destination
50 // to send to. Otherwise, will send to the last socket this server
52 int SendToSocket(UDPServerSocket
* socket
, std::string msg
) {
53 return SendToSocket(socket
, msg
, recv_from_address_
);
56 int SendToSocket(UDPServerSocket
* socket
,
58 const IPEndPoint
& address
) {
59 TestCompletionCallback callback
;
61 int length
= msg
.length();
62 scoped_refptr
<StringIOBuffer
> io_buffer(new StringIOBuffer(msg
));
63 scoped_refptr
<DrainableIOBuffer
> buffer(
64 new DrainableIOBuffer(io_buffer
.get(), length
));
67 while (buffer
->BytesRemaining()) {
68 int rv
= socket
->SendTo(
69 buffer
.get(), buffer
->BytesRemaining(), address
, callback
.callback());
70 if (rv
== ERR_IO_PENDING
)
71 rv
= callback
.WaitForResult();
73 return bytes_sent
> 0 ? bytes_sent
: rv
;
75 buffer
->DidConsume(rv
);
80 std::string
ReadSocket(UDPClientSocket
* socket
) {
81 TestCompletionCallback callback
;
83 int rv
= socket
->Read(buffer_
.get(), kMaxRead
, callback
.callback());
84 if (rv
== ERR_IO_PENDING
)
85 rv
= callback
.WaitForResult();
87 return std::string(); // error!
88 return std::string(buffer_
->data(), rv
);
91 // Loop until |msg| has been written to the socket or until an
93 int WriteSocket(UDPClientSocket
* socket
, std::string msg
) {
94 TestCompletionCallback callback
;
96 int length
= msg
.length();
97 scoped_refptr
<StringIOBuffer
> io_buffer(new StringIOBuffer(msg
));
98 scoped_refptr
<DrainableIOBuffer
> buffer(
99 new DrainableIOBuffer(io_buffer
.get(), length
));
102 while (buffer
->BytesRemaining()) {
103 int rv
= socket
->Write(
104 buffer
.get(), buffer
->BytesRemaining(), callback
.callback());
105 if (rv
== ERR_IO_PENDING
)
106 rv
= callback
.WaitForResult();
108 return bytes_sent
> 0 ? bytes_sent
: rv
;
110 buffer
->DidConsume(rv
);
116 static const int kMaxRead
= 1024;
117 scoped_refptr
<IOBufferWithSize
> buffer_
;
118 IPEndPoint recv_from_address_
;
121 // Creates and address from an ip/port and returns it in |address|.
122 void CreateUDPAddress(std::string ip_str
, int port
, IPEndPoint
* address
) {
123 IPAddressNumber ip_number
;
124 bool rv
= ParseIPLiteralToNumber(ip_str
, &ip_number
);
127 *address
= IPEndPoint(ip_number
, port
);
130 TEST_F(UDPSocketTest
, Connect
) {
131 const int kPort
= 9999;
132 std::string
simple_message("hello world!");
134 // Setup the server to listen.
135 IPEndPoint bind_address
;
136 CreateUDPAddress("127.0.0.1", kPort
, &bind_address
);
137 CapturingNetLog server_log
;
138 scoped_ptr
<UDPServerSocket
> server(
139 new UDPServerSocket(&server_log
, NetLog::Source()));
140 server
->AllowAddressReuse();
141 int rv
= server
->Listen(bind_address
);
145 IPEndPoint server_address
;
146 CreateUDPAddress("127.0.0.1", kPort
, &server_address
);
147 CapturingNetLog client_log
;
148 scoped_ptr
<UDPClientSocket
> client(
149 new UDPClientSocket(DatagramSocket::DEFAULT_BIND
,
153 rv
= client
->Connect(server_address
);
156 // Client sends to the server.
157 rv
= WriteSocket(client
.get(), simple_message
);
158 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
160 // Server waits for message.
161 std::string str
= RecvFromSocket(server
.get());
162 DCHECK(simple_message
== str
);
164 // Server echoes reply.
165 rv
= SendToSocket(server
.get(), simple_message
);
166 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
168 // Client waits for response.
169 str
= ReadSocket(client
.get());
170 DCHECK(simple_message
== str
);
172 // Delete sockets so they log their final events.
176 // Check the server's log.
177 CapturingNetLog::CapturedEntryList server_entries
;
178 server_log
.GetEntries(&server_entries
);
179 EXPECT_EQ(4u, server_entries
.size());
180 EXPECT_TRUE(LogContainsBeginEvent(
181 server_entries
, 0, NetLog::TYPE_SOCKET_ALIVE
));
182 EXPECT_TRUE(LogContainsEvent(
183 server_entries
, 1, NetLog::TYPE_UDP_BYTES_RECEIVED
, NetLog::PHASE_NONE
));
184 EXPECT_TRUE(LogContainsEvent(
185 server_entries
, 2, NetLog::TYPE_UDP_BYTES_SENT
, NetLog::PHASE_NONE
));
186 EXPECT_TRUE(LogContainsEndEvent(
187 server_entries
, 3, NetLog::TYPE_SOCKET_ALIVE
));
189 // Check the client's log.
190 CapturingNetLog::CapturedEntryList client_entries
;
191 client_log
.GetEntries(&client_entries
);
192 EXPECT_EQ(6u, client_entries
.size());
193 EXPECT_TRUE(LogContainsBeginEvent(
194 client_entries
, 0, NetLog::TYPE_SOCKET_ALIVE
));
195 EXPECT_TRUE(LogContainsBeginEvent(
196 client_entries
, 1, NetLog::TYPE_UDP_CONNECT
));
197 EXPECT_TRUE(LogContainsEndEvent(
198 client_entries
, 2, NetLog::TYPE_UDP_CONNECT
));
199 EXPECT_TRUE(LogContainsEvent(
200 client_entries
, 3, NetLog::TYPE_UDP_BYTES_SENT
, NetLog::PHASE_NONE
));
201 EXPECT_TRUE(LogContainsEvent(
202 client_entries
, 4, NetLog::TYPE_UDP_BYTES_RECEIVED
, NetLog::PHASE_NONE
));
203 EXPECT_TRUE(LogContainsEndEvent(
204 client_entries
, 5, NetLog::TYPE_SOCKET_ALIVE
));
207 #if defined(OS_MACOSX)
208 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires
209 // root permissions on OSX 10.7+.
210 TEST_F(UDPSocketTest
, DISABLED_Broadcast
) {
211 #elif defined(OS_ANDROID)
212 // It is also disabled for Android because it is extremely flaky.
213 // The first call to SendToSocket returns -109 (Address not reachable)
214 // in some unpredictable cases. crbug.com/139144.
215 TEST_F(UDPSocketTest
, DISABLED_Broadcast
) {
217 TEST_F(UDPSocketTest
, Broadcast
) {
219 const int kPort
= 9999;
220 std::string
first_message("first message"), second_message("second message");
222 IPEndPoint broadcast_address
;
223 CreateUDPAddress("255.255.255.255", kPort
, &broadcast_address
);
224 IPEndPoint listen_address
;
225 CreateUDPAddress("0.0.0.0", kPort
, &listen_address
);
227 CapturingNetLog server1_log
, server2_log
;
228 scoped_ptr
<UDPServerSocket
> server1(
229 new UDPServerSocket(&server1_log
, NetLog::Source()));
230 scoped_ptr
<UDPServerSocket
> server2(
231 new UDPServerSocket(&server2_log
, NetLog::Source()));
232 server1
->AllowAddressReuse();
233 server1
->AllowBroadcast();
234 server2
->AllowAddressReuse();
235 server2
->AllowBroadcast();
237 int rv
= server1
->Listen(listen_address
);
239 rv
= server2
->Listen(listen_address
);
242 rv
= SendToSocket(server1
.get(), first_message
, broadcast_address
);
243 ASSERT_EQ(static_cast<int>(first_message
.size()), rv
);
244 std::string str
= RecvFromSocket(server1
.get());
245 ASSERT_EQ(first_message
, str
);
246 str
= RecvFromSocket(server2
.get());
247 ASSERT_EQ(first_message
, str
);
249 rv
= SendToSocket(server2
.get(), second_message
, broadcast_address
);
250 ASSERT_EQ(static_cast<int>(second_message
.size()), rv
);
251 str
= RecvFromSocket(server1
.get());
252 ASSERT_EQ(second_message
, str
);
253 str
= RecvFromSocket(server2
.get());
254 ASSERT_EQ(second_message
, str
);
257 // In this test, we verify that random binding logic works, which attempts
258 // to bind to a random port and returns if succeeds, otherwise retries for
259 // |kBindRetries| number of times.
261 // To generate the scenario, we first create |kBindRetries| number of
262 // UDPClientSockets with default binding policy and connect to the same
263 // peer and save the used port numbers. Then we get rid of the last
264 // socket, making sure that the local port it was bound to is available.
265 // Finally, we create a socket with random binding policy, passing it a
266 // test PRNG that would serve used port numbers in the array, one after
267 // another. At the end, we make sure that the test socket was bound to the
268 // port that became available after deleting the last socket with default
271 // We do not test the randomness of bound ports, but that we are using
272 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
274 static const int kBindRetries
= 10;
278 explicit TestPrng(const std::deque
<int>& numbers
) : numbers_(numbers
) {}
279 int GetNext(int /* min */, int /* max */) {
280 DCHECK(!numbers_
.empty());
281 int rv
= numbers_
.front();
282 numbers_
.pop_front();
286 std::deque
<int> numbers_
;
288 DISALLOW_COPY_AND_ASSIGN(TestPrng
);
291 #if defined(OS_ANDROID)
292 // Disabled on Android for lack of 192.168.1.13. crbug.com/161245
293 TEST_F(UDPSocketTest
, DISABLED_ConnectRandomBind
) {
295 TEST_F(UDPSocketTest
, ConnectRandomBind
) {
297 std::vector
<UDPClientSocket
*> sockets
;
298 IPEndPoint peer_address
;
299 CreateUDPAddress("192.168.1.13", 53, &peer_address
);
301 // Create and connect sockets and save port numbers.
302 std::deque
<int> used_ports
;
303 for (int i
= 0; i
< kBindRetries
; ++i
) {
304 UDPClientSocket
* socket
=
305 new UDPClientSocket(DatagramSocket::DEFAULT_BIND
,
309 sockets
.push_back(socket
);
310 EXPECT_EQ(OK
, socket
->Connect(peer_address
));
312 IPEndPoint client_address
;
313 EXPECT_EQ(OK
, socket
->GetLocalAddress(&client_address
));
314 used_ports
.push_back(client_address
.port());
317 // Free the last socket, its local port is still in |used_ports|.
318 delete sockets
.back();
321 TestPrng
test_prng(used_ports
);
322 RandIntCallback rand_int_cb
=
323 base::Bind(&TestPrng::GetNext
, base::Unretained(&test_prng
));
325 // Create a socket with random binding policy and connect.
326 scoped_ptr
<UDPClientSocket
> test_socket(
327 new UDPClientSocket(DatagramSocket::RANDOM_BIND
,
331 EXPECT_EQ(OK
, test_socket
->Connect(peer_address
));
333 // Make sure that the last port number in the |used_ports| was used.
334 IPEndPoint client_address
;
335 EXPECT_EQ(OK
, test_socket
->GetLocalAddress(&client_address
));
336 EXPECT_EQ(used_ports
.back(), client_address
.port());
338 STLDeleteElements(&sockets
);
341 // Return a privileged port (under 1024) so binding will fail.
342 int PrivilegedRand(int min
, int max
) {
343 // Chosen by fair dice roll. Guaranteed to be random.
347 TEST_F(UDPSocketTest
, ConnectFail
) {
348 IPEndPoint peer_address
;
349 CreateUDPAddress("0.0.0.0", 53, &peer_address
);
351 scoped_ptr
<UDPSocket
> socket(
352 new UDPSocket(DatagramSocket::RANDOM_BIND
,
353 base::Bind(&PrivilegedRand
),
356 int rv
= socket
->Connect(peer_address
);
357 // Connect should have failed since we couldn't bind to that port,
359 // Make sure that UDPSocket actually closed the socket.
360 EXPECT_FALSE(socket
->is_connected());
363 // In this test, we verify that connect() on a socket will have the effect
364 // of filtering reads on this socket only to data read from the destination
367 // The purpose of this test is that some documentation indicates that connect
368 // binds the client's sends to send to a particular server endpoint, but does
369 // not bind the client's reads to only be from that endpoint, and that we need
370 // to always use recvfrom() to disambiguate.
371 TEST_F(UDPSocketTest
, VerifyConnectBindsAddr
) {
372 const int kPort1
= 9999;
373 const int kPort2
= 10000;
374 std::string
simple_message("hello world!");
375 std::string
foreign_message("BAD MESSAGE TO GET!!");
377 // Setup the first server to listen.
378 IPEndPoint bind_address
;
379 CreateUDPAddress("127.0.0.1", kPort1
, &bind_address
);
380 UDPServerSocket
server1(NULL
, NetLog::Source());
381 server1
.AllowAddressReuse();
382 int rv
= server1
.Listen(bind_address
);
385 // Setup the second server to listen.
386 CreateUDPAddress("127.0.0.1", kPort2
, &bind_address
);
387 UDPServerSocket
server2(NULL
, NetLog::Source());
388 server2
.AllowAddressReuse();
389 rv
= server2
.Listen(bind_address
);
392 // Setup the client, connected to server 1.
393 IPEndPoint server_address
;
394 CreateUDPAddress("127.0.0.1", kPort1
, &server_address
);
395 UDPClientSocket
client(DatagramSocket::DEFAULT_BIND
,
399 rv
= client
.Connect(server_address
);
402 // Client sends to server1.
403 rv
= WriteSocket(&client
, simple_message
);
404 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
406 // Server1 waits for message.
407 std::string str
= RecvFromSocket(&server1
);
408 DCHECK(simple_message
== str
);
410 // Get the client's address.
411 IPEndPoint client_address
;
412 rv
= client
.GetLocalAddress(&client_address
);
415 // Server2 sends reply.
416 rv
= SendToSocket(&server2
, foreign_message
,
418 EXPECT_EQ(foreign_message
.length(), static_cast<size_t>(rv
));
420 // Server1 sends reply.
421 rv
= SendToSocket(&server1
, simple_message
,
423 EXPECT_EQ(simple_message
.length(), static_cast<size_t>(rv
));
425 // Client waits for response.
426 str
= ReadSocket(&client
);
427 DCHECK(simple_message
== str
);
430 TEST_F(UDPSocketTest
, ClientGetLocalPeerAddresses
) {
432 std::string remote_address
;
433 std::string local_address
;
436 { "127.0.00.1", "127.0.0.1", false },
437 { "::1", "::1", true },
438 #if !defined(OS_ANDROID)
439 // Addresses below are disabled on Android. See crbug.com/161248
440 { "192.168.1.1", "127.0.0.1", false },
441 { "2001:db8:0::42", "::1", true },
444 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); i
++) {
445 SCOPED_TRACE(std::string("Connecting from ") + tests
[i
].local_address
+
446 std::string(" to ") + tests
[i
].remote_address
);
448 IPAddressNumber ip_number
;
449 ParseIPLiteralToNumber(tests
[i
].remote_address
, &ip_number
);
450 IPEndPoint
remote_address(ip_number
, 80);
451 ParseIPLiteralToNumber(tests
[i
].local_address
, &ip_number
);
452 IPEndPoint
local_address(ip_number
, 80);
454 UDPClientSocket
client(DatagramSocket::DEFAULT_BIND
,
458 int rv
= client
.Connect(remote_address
);
459 if (tests
[i
].may_fail
&& rv
== ERR_ADDRESS_UNREACHABLE
) {
460 // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
461 // addresses if IPv6 is not configured.
465 EXPECT_LE(ERR_IO_PENDING
, rv
);
467 IPEndPoint fetched_local_address
;
468 rv
= client
.GetLocalAddress(&fetched_local_address
);
471 // TODO(mbelshe): figure out how to verify the IP and port.
472 // The port is dynamically generated by the udp stack.
473 // The IP is the real IP of the client, not necessarily
475 //EXPECT_EQ(local_address.address(), fetched_local_address.address());
477 IPEndPoint fetched_remote_address
;
478 rv
= client
.GetPeerAddress(&fetched_remote_address
);
481 EXPECT_EQ(remote_address
, fetched_remote_address
);
485 TEST_F(UDPSocketTest
, ServerGetLocalAddress
) {
486 IPEndPoint bind_address
;
487 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
488 UDPServerSocket
server(NULL
, NetLog::Source());
489 int rv
= server
.Listen(bind_address
);
492 IPEndPoint local_address
;
493 rv
= server
.GetLocalAddress(&local_address
);
496 // Verify that port was allocated.
497 EXPECT_GT(local_address
.port(), 0);
498 EXPECT_EQ(local_address
.address(), bind_address
.address());
501 TEST_F(UDPSocketTest
, ServerGetPeerAddress
) {
502 IPEndPoint bind_address
;
503 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
504 UDPServerSocket
server(NULL
, NetLog::Source());
505 int rv
= server
.Listen(bind_address
);
508 IPEndPoint peer_address
;
509 rv
= server
.GetPeerAddress(&peer_address
);
510 EXPECT_EQ(rv
, ERR_SOCKET_NOT_CONNECTED
);
513 // Close the socket while read is pending.
514 TEST_F(UDPSocketTest
, CloseWithPendingRead
) {
515 IPEndPoint bind_address
;
516 CreateUDPAddress("127.0.0.1", 0, &bind_address
);
517 UDPServerSocket
server(NULL
, NetLog::Source());
518 int rv
= server
.Listen(bind_address
);
521 TestCompletionCallback callback
;
523 rv
= server
.RecvFrom(buffer_
.get(), kMaxRead
, &from
, callback
.callback());
524 EXPECT_EQ(rv
, ERR_IO_PENDING
);
528 EXPECT_FALSE(callback
.have_result());
531 #if defined(OS_ANDROID)
532 // Some Android devices do not support multicast socket.
533 // The ones supporting multicast need WifiManager.MulitcastLock to enable it.
534 // http://goo.gl/jjAk9
535 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup
537 #define MAYBE_JoinMulticastGroup JoinMulticastGroup
538 #endif // defined(OS_ANDROID)
540 TEST_F(UDPSocketTest
, MAYBE_JoinMulticastGroup
) {
541 const int kPort
= 9999;
542 const char* const kGroup
= "237.132.100.17";
544 IPEndPoint bind_address
;
545 CreateUDPAddress("0.0.0.0", kPort
, &bind_address
);
546 IPAddressNumber group_ip
;
547 EXPECT_TRUE(ParseIPLiteralToNumber(kGroup
, &group_ip
));
549 UDPSocket
socket(DatagramSocket::DEFAULT_BIND
,
553 EXPECT_EQ(OK
, socket
.Bind(bind_address
));
554 EXPECT_EQ(OK
, socket
.JoinGroup(group_ip
));
555 // Joining group multiple times.
556 EXPECT_NE(OK
, socket
.JoinGroup(group_ip
));
557 EXPECT_EQ(OK
, socket
.LeaveGroup(group_ip
));
558 // Leaving group multiple times.
559 EXPECT_NE(OK
, socket
.LeaveGroup(group_ip
));
564 TEST_F(UDPSocketTest
, MulticastOptions
) {
565 const int kPort
= 9999;
566 IPEndPoint bind_address
;
567 CreateUDPAddress("0.0.0.0", kPort
, &bind_address
);
569 UDPSocket
socket(DatagramSocket::DEFAULT_BIND
,
574 EXPECT_EQ(OK
, socket
.SetMulticastLoopbackMode(false));
575 EXPECT_EQ(OK
, socket
.SetMulticastLoopbackMode(true));
576 EXPECT_EQ(OK
, socket
.SetMulticastTimeToLive(0));
577 EXPECT_EQ(OK
, socket
.SetMulticastTimeToLive(3));
578 EXPECT_NE(OK
, socket
.SetMulticastTimeToLive(-1));
579 EXPECT_EQ(OK
, socket
.SetMulticastInterface(0));
581 EXPECT_EQ(OK
, socket
.Bind(bind_address
));
583 EXPECT_NE(OK
, socket
.SetMulticastLoopbackMode(false));
584 EXPECT_NE(OK
, socket
.SetMulticastTimeToLive(0));
585 EXPECT_NE(OK
, socket
.SetMulticastInterface(0));
590 // Checking that DSCP bits are set correctly is difficult,
591 // but let's check that the code doesn't crash at least.
592 TEST_F(UDPSocketTest
, SetDSCP
) {
593 // Setup the server to listen.
594 IPEndPoint bind_address
;
595 UDPSocket
client(DatagramSocket::DEFAULT_BIND
,
599 // We need a real IP, but we won't actually send anything to it.
600 CreateUDPAddress("8.8.8.8", 9999, &bind_address
);
601 int rv
= client
.Connect(bind_address
);
603 // Let's try localhost then..
604 CreateUDPAddress("127.0.0.1", 9999, &bind_address
);
605 rv
= client
.Connect(bind_address
);
609 client
.SetDiffServCodePoint(DSCP_NO_CHANGE
);
610 client
.SetDiffServCodePoint(DSCP_AF41
);
611 client
.SetDiffServCodePoint(DSCP_DEFAULT
);
612 client
.SetDiffServCodePoint(DSCP_CS2
);
613 client
.SetDiffServCodePoint(DSCP_NO_CHANGE
);
614 client
.SetDiffServCodePoint(DSCP_DEFAULT
);
624 const HANDLE kFakeHandle
= (HANDLE
)19;
625 const QOS_FLOWID kFakeFlowId
= (QOS_FLOWID
)27;
627 BOOL WINAPI
FakeQOSCreateHandleFAIL(PQOS_VERSION version
, PHANDLE handle
) {
628 EXPECT_EQ(0, version
->MinorVersion
);
629 EXPECT_EQ(1, version
->MajorVersion
);
630 SetLastError(ERROR_OPEN_FAILED
);
634 BOOL WINAPI
FakeQOSCreateHandle(PQOS_VERSION version
, PHANDLE handle
) {
635 EXPECT_EQ(0, version
->MinorVersion
);
636 EXPECT_EQ(1, version
->MajorVersion
);
637 *handle
= kFakeHandle
;
641 BOOL WINAPI
FakeQOSCloseHandle(HANDLE handle
) {
642 EXPECT_EQ(kFakeHandle
, handle
);
646 QOS_TRAFFIC_TYPE g_expected_traffic_type
;
648 BOOL WINAPI
FakeQOSAddSocketToFlow(HANDLE handle
,
651 QOS_TRAFFIC_TYPE traffic_type
,
653 PQOS_FLOWID flow_id
) {
654 EXPECT_EQ(kFakeHandle
, handle
);
655 EXPECT_EQ(NULL
, addr
);
656 EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW
, flags
);
657 EXPECT_EQ(0, *flow_id
);
658 *flow_id
= kFakeFlowId
;
662 BOOL WINAPI
FakeQOSRemoveSocketFromFlow(HANDLE handle
,
666 EXPECT_EQ(kFakeHandle
, handle
);
667 EXPECT_EQ(NULL
, socket
);
668 EXPECT_EQ(kFakeFlowId
, flowid
);
669 EXPECT_EQ(0, reserved
);
673 DWORD g_expected_dscp
;
675 BOOL WINAPI
FakeQOSSetFlow(HANDLE handle
,
681 LPOVERLAPPED overlapped
) {
682 EXPECT_EQ(kFakeHandle
, handle
);
683 EXPECT_EQ(QOSSetOutgoingDSCPValue
, op
);
684 EXPECT_EQ(sizeof(DWORD
), size
);
685 EXPECT_EQ(g_expected_dscp
, *reinterpret_cast<DWORD
*>(data
));
686 EXPECT_EQ(kFakeFlowId
, flow_id
);
687 EXPECT_EQ(0, reserved
);
688 EXPECT_EQ(NULL
, overlapped
);
694 // Mock out the Qwave functions and make sure they are
695 // called correctly. Must be in net namespace for friendship
697 TEST_F(UDPSocketTest
, SetDSCPFake
) {
698 // Setup the server to listen.
699 IPEndPoint bind_address
;
700 // We need a real IP, but we won't actually send anything to it.
701 CreateUDPAddress("8.8.8.8", 9999, &bind_address
);
702 UDPSocket
client(DatagramSocket::DEFAULT_BIND
,
706 int rv
= client
.SetDiffServCodePoint(DSCP_AF41
);
707 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, rv
);
708 rv
= client
.Connect(bind_address
);
711 QwaveAPI
& qos(QwaveAPI::Get());
712 qos
.create_handle_func_
= FakeQOSCreateHandleFAIL
;
713 qos
.close_handle_func_
= FakeQOSCloseHandle
;
714 qos
.add_socket_to_flow_func_
= FakeQOSAddSocketToFlow
;
715 qos
.remove_socket_from_flow_func_
= FakeQOSRemoveSocketFromFlow
;
716 qos
.set_flow_func_
= FakeQOSSetFlow
;
717 qos
.qwave_supported_
= true;
719 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_NO_CHANGE
));
720 EXPECT_EQ(ERROR_NOT_SUPPORTED
, client
.SetDiffServCodePoint(DSCP_AF41
));
721 qos
.create_handle_func_
= FakeQOSCreateHandle
;
722 g_expected_dscp
= DSCP_AF41
;
723 g_expected_traffic_type
= QOSTrafficTypeAudioVideo
;
724 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_AF41
));
725 g_expected_dscp
= DSCP_DEFAULT
;
726 g_expected_traffic_type
= QOSTrafficTypeBestEffort
;
727 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_DEFAULT
));
728 g_expected_dscp
= DSCP_CS2
;
729 g_expected_traffic_type
= QOSTrafficTypeExcellentEffort
;
730 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_CS2
));
731 g_expected_dscp
= DSCP_CS3
;
732 g_expected_traffic_type
= QOSTrafficTypeExcellentEffort
;
733 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_NO_CHANGE
));
734 g_expected_dscp
= DSCP_DEFAULT
;
735 g_expected_traffic_type
= QOSTrafficTypeBestEffort
;
736 EXPECT_EQ(OK
, client
.SetDiffServCodePoint(DSCP_DEFAULT
));