OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/udp/udp_socket.h" | |
6 | |
7 #include "net/udp/udp_client_socket.h" | |
8 #include "net/udp/udp_server_socket.h" | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/location.h" | |
12 #include "base/macros.h" | |
13 #include "base/memory/ptr_util.h" | |
14 #include "base/memory/weak_ptr.h" | |
15 #include "base/run_loop.h" | |
16 #include "base/single_thread_task_runner.h" | |
17 #include "base/threading/thread_task_runner_handle.h" | |
18 #include "net/base/io_buffer.h" | |
19 #include "net/base/ip_address.h" | |
20 #include "net/base/ip_endpoint.h" | |
21 #include "net/base/net_errors.h" | |
22 #include "net/base/test_completion_callback.h" | |
23 #include "net/log/net_log_event_type.h" | |
24 #include "net/log/net_log_source.h" | |
25 #include "net/log/test_net_log.h" | |
26 #include "net/log/test_net_log_entry.h" | |
27 #include "net/log/test_net_log_util.h" | |
28 #include "net/test/gtest_util.h" | |
29 #include "net/test/net_test_suite.h" | |
30 #include "testing/gmock/include/gmock/gmock.h" | |
31 #include "testing/gtest/include/gtest/gtest.h" | |
32 #include "testing/platform_test.h" | |
33 | |
34 #if defined(OS_ANDROID) | |
35 #include "base/android/build_info.h" | |
36 #endif | |
37 | |
38 #if defined(OS_IOS) | |
39 #include <TargetConditionals.h> | |
40 #endif | |
41 | |
42 using net::test::IsError; | |
43 using net::test::IsOk; | |
44 | |
45 namespace net { | |
46 | |
47 namespace { | |
48 | |
49 class UDPSocketTest : public PlatformTest { | |
50 public: | |
51 UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {} | |
52 | |
53 // Blocks until data is read from the socket. | |
54 std::string RecvFromSocket(UDPServerSocket* socket) { | |
55 TestCompletionCallback callback; | |
56 | |
57 int rv = socket->RecvFrom( | |
58 buffer_.get(), kMaxRead, &recv_from_address_, callback.callback()); | |
59 if (rv == ERR_IO_PENDING) | |
60 rv = callback.WaitForResult(); | |
61 if (rv < 0) | |
62 return std::string(); // error! | |
63 return std::string(buffer_->data(), rv); | |
64 } | |
65 | |
66 // Loop until |msg| has been written to the socket or until an | |
67 // error occurs. | |
68 // If |address| is specified, then it is used for the destination | |
69 // to send to. Otherwise, will send to the last socket this server | |
70 // received from. | |
71 int SendToSocket(UDPServerSocket* socket, const std::string& msg) { | |
72 return SendToSocket(socket, msg, recv_from_address_); | |
73 } | |
74 | |
75 int SendToSocket(UDPServerSocket* socket, | |
76 std::string msg, | |
77 const IPEndPoint& address) { | |
78 TestCompletionCallback callback; | |
79 | |
80 int length = msg.length(); | |
81 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg)); | |
82 scoped_refptr<DrainableIOBuffer> buffer( | |
83 new DrainableIOBuffer(io_buffer.get(), length)); | |
84 | |
85 int bytes_sent = 0; | |
86 while (buffer->BytesRemaining()) { | |
87 int rv = socket->SendTo( | |
88 buffer.get(), buffer->BytesRemaining(), address, callback.callback()); | |
89 if (rv == ERR_IO_PENDING) | |
90 rv = callback.WaitForResult(); | |
91 if (rv <= 0) | |
92 return bytes_sent > 0 ? bytes_sent : rv; | |
93 bytes_sent += rv; | |
94 buffer->DidConsume(rv); | |
95 } | |
96 return bytes_sent; | |
97 } | |
98 | |
99 std::string ReadSocket(UDPClientSocket* socket) { | |
100 TestCompletionCallback callback; | |
101 | |
102 int rv = socket->Read(buffer_.get(), kMaxRead, callback.callback()); | |
103 if (rv == ERR_IO_PENDING) | |
104 rv = callback.WaitForResult(); | |
105 if (rv < 0) | |
106 return std::string(); // error! | |
107 return std::string(buffer_->data(), rv); | |
108 } | |
109 | |
110 // Loop until |msg| has been written to the socket or until an | |
111 // error occurs. | |
112 int WriteSocket(UDPClientSocket* socket, const std::string& msg) { | |
113 TestCompletionCallback callback; | |
114 | |
115 int length = msg.length(); | |
116 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg)); | |
117 scoped_refptr<DrainableIOBuffer> buffer( | |
118 new DrainableIOBuffer(io_buffer.get(), length)); | |
119 | |
120 int bytes_sent = 0; | |
121 while (buffer->BytesRemaining()) { | |
122 int rv = socket->Write( | |
123 buffer.get(), buffer->BytesRemaining(), callback.callback()); | |
124 if (rv == ERR_IO_PENDING) | |
125 rv = callback.WaitForResult(); | |
126 if (rv <= 0) | |
127 return bytes_sent > 0 ? bytes_sent : rv; | |
128 bytes_sent += rv; | |
129 buffer->DidConsume(rv); | |
130 } | |
131 return bytes_sent; | |
132 } | |
133 | |
134 void WriteSocketIgnoreResult(UDPClientSocket* socket, | |
135 const std::string& msg) { | |
136 WriteSocket(socket, msg); | |
137 } | |
138 | |
139 // Creates an address from ip address and port and writes it to |*address|. | |
140 void CreateUDPAddress(const std::string& ip_str, | |
141 uint16_t port, | |
142 IPEndPoint* address) { | |
143 IPAddress ip_address; | |
144 if (!ip_address.AssignFromIPLiteral(ip_str)) | |
145 return; | |
146 *address = IPEndPoint(ip_address, port); | |
147 } | |
148 | |
149 // Run unit test for a connection test. | |
150 // |use_nonblocking_io| is used to switch between overlapped and non-blocking | |
151 // IO on Windows. It has no effect in other ports. | |
152 void ConnectTest(bool use_nonblocking_io); | |
153 | |
154 protected: | |
155 static const int kMaxRead = 1024; | |
156 scoped_refptr<IOBufferWithSize> buffer_; | |
157 IPEndPoint recv_from_address_; | |
158 }; | |
159 | |
160 void ReadCompleteCallback(int* result_out, base::Closure callback, int result) { | |
161 *result_out = result; | |
162 callback.Run(); | |
163 } | |
164 | |
165 void UDPSocketTest::ConnectTest(bool use_nonblocking_io) { | |
166 const uint16_t kPort = 9999; | |
167 std::string simple_message("hello world!"); | |
168 | |
169 // Setup the server to listen. | |
170 IPEndPoint bind_address; | |
171 CreateUDPAddress("127.0.0.1", kPort, &bind_address); | |
172 TestNetLog server_log; | |
173 std::unique_ptr<UDPServerSocket> server( | |
174 new UDPServerSocket(&server_log, NetLogSource())); | |
175 if (use_nonblocking_io) | |
176 server->UseNonBlockingIO(); | |
177 server->AllowAddressReuse(); | |
178 int rv = server->Listen(bind_address); | |
179 ASSERT_THAT(rv, IsOk()); | |
180 | |
181 // Setup the client. | |
182 IPEndPoint server_address; | |
183 CreateUDPAddress("127.0.0.1", kPort, &server_address); | |
184 TestNetLog client_log; | |
185 std::unique_ptr<UDPClientSocket> client( | |
186 new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), | |
187 &client_log, NetLogSource())); | |
188 if (use_nonblocking_io) | |
189 client->UseNonBlockingIO(); | |
190 | |
191 rv = client->Connect(server_address); | |
192 EXPECT_THAT(rv, IsOk()); | |
193 | |
194 // Client sends to the server. | |
195 rv = WriteSocket(client.get(), simple_message); | |
196 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
197 | |
198 // Server waits for message. | |
199 std::string str = RecvFromSocket(server.get()); | |
200 DCHECK(simple_message == str); | |
201 | |
202 // Server echoes reply. | |
203 rv = SendToSocket(server.get(), simple_message); | |
204 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
205 | |
206 // Client waits for response. | |
207 str = ReadSocket(client.get()); | |
208 DCHECK(simple_message == str); | |
209 | |
210 // Test asynchronous read. Server waits for message. | |
211 base::RunLoop run_loop; | |
212 int read_result = 0; | |
213 rv = server->RecvFrom( | |
214 buffer_.get(), kMaxRead, &recv_from_address_, | |
215 base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure())); | |
216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
217 | |
218 // Client sends to the server. | |
219 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
220 FROM_HERE, | |
221 base::Bind(&UDPSocketTest::WriteSocketIgnoreResult, | |
222 base::Unretained(this), client.get(), simple_message)); | |
223 run_loop.Run(); | |
224 EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result)); | |
225 EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result)); | |
226 | |
227 // Delete sockets so they log their final events. | |
228 server.reset(); | |
229 client.reset(); | |
230 | |
231 // Check the server's log. | |
232 TestNetLogEntry::List server_entries; | |
233 server_log.GetEntries(&server_entries); | |
234 EXPECT_EQ(5u, server_entries.size()); | |
235 EXPECT_TRUE( | |
236 LogContainsBeginEvent(server_entries, 0, NetLogEventType::SOCKET_ALIVE)); | |
237 EXPECT_TRUE(LogContainsEvent(server_entries, 1, | |
238 NetLogEventType::UDP_BYTES_RECEIVED, | |
239 NetLogEventPhase::NONE)); | |
240 EXPECT_TRUE(LogContainsEvent(server_entries, 2, | |
241 NetLogEventType::UDP_BYTES_SENT, | |
242 NetLogEventPhase::NONE)); | |
243 EXPECT_TRUE(LogContainsEvent(server_entries, 3, | |
244 NetLogEventType::UDP_BYTES_RECEIVED, | |
245 NetLogEventPhase::NONE)); | |
246 EXPECT_TRUE( | |
247 LogContainsEndEvent(server_entries, 4, NetLogEventType::SOCKET_ALIVE)); | |
248 | |
249 // Check the client's log. | |
250 TestNetLogEntry::List client_entries; | |
251 client_log.GetEntries(&client_entries); | |
252 EXPECT_EQ(7u, client_entries.size()); | |
253 EXPECT_TRUE( | |
254 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); | |
255 EXPECT_TRUE( | |
256 LogContainsBeginEvent(client_entries, 1, NetLogEventType::UDP_CONNECT)); | |
257 EXPECT_TRUE( | |
258 LogContainsEndEvent(client_entries, 2, NetLogEventType::UDP_CONNECT)); | |
259 EXPECT_TRUE(LogContainsEvent(client_entries, 3, | |
260 NetLogEventType::UDP_BYTES_SENT, | |
261 NetLogEventPhase::NONE)); | |
262 EXPECT_TRUE(LogContainsEvent(client_entries, 4, | |
263 NetLogEventType::UDP_BYTES_RECEIVED, | |
264 NetLogEventPhase::NONE)); | |
265 EXPECT_TRUE(LogContainsEvent(client_entries, 5, | |
266 NetLogEventType::UDP_BYTES_SENT, | |
267 NetLogEventPhase::NONE)); | |
268 EXPECT_TRUE( | |
269 LogContainsEndEvent(client_entries, 6, NetLogEventType::SOCKET_ALIVE)); | |
270 } | |
271 | |
272 TEST_F(UDPSocketTest, Connect) { | |
273 // The variable |use_nonblocking_io| has no effect in non-Windows ports. | |
274 ConnectTest(false); | |
275 } | |
276 | |
277 #if defined(OS_WIN) | |
278 TEST_F(UDPSocketTest, ConnectNonBlocking) { | |
279 ConnectTest(true); | |
280 } | |
281 #endif | |
282 | |
283 #if defined(OS_MACOSX) | |
284 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires | |
285 // root permissions on OSX 10.7+. | |
286 TEST_F(UDPSocketTest, DISABLED_Broadcast) { | |
287 #elif defined(OS_ANDROID) | |
288 // Disabled for Android because devices attached to testbots don't have default | |
289 // network, so broadcasting to 255.255.255.255 returns error -109 (Address not | |
290 // reachable). crbug.com/139144. | |
291 TEST_F(UDPSocketTest, DISABLED_Broadcast) { | |
292 #else | |
293 TEST_F(UDPSocketTest, Broadcast) { | |
294 #endif | |
295 const uint16_t kPort = 9999; | |
296 std::string first_message("first message"), second_message("second message"); | |
297 | |
298 IPEndPoint broadcast_address; | |
299 CreateUDPAddress("255.255.255.255", kPort, &broadcast_address); | |
300 IPEndPoint listen_address; | |
301 CreateUDPAddress("0.0.0.0", kPort, &listen_address); | |
302 | |
303 TestNetLog server1_log, server2_log; | |
304 std::unique_ptr<UDPServerSocket> server1( | |
305 new UDPServerSocket(&server1_log, NetLogSource())); | |
306 std::unique_ptr<UDPServerSocket> server2( | |
307 new UDPServerSocket(&server2_log, NetLogSource())); | |
308 server1->AllowAddressReuse(); | |
309 server1->AllowBroadcast(); | |
310 server2->AllowAddressReuse(); | |
311 server2->AllowBroadcast(); | |
312 | |
313 int rv = server1->Listen(listen_address); | |
314 EXPECT_THAT(rv, IsOk()); | |
315 rv = server2->Listen(listen_address); | |
316 EXPECT_THAT(rv, IsOk()); | |
317 | |
318 rv = SendToSocket(server1.get(), first_message, broadcast_address); | |
319 ASSERT_EQ(static_cast<int>(first_message.size()), rv); | |
320 std::string str = RecvFromSocket(server1.get()); | |
321 ASSERT_EQ(first_message, str); | |
322 str = RecvFromSocket(server2.get()); | |
323 ASSERT_EQ(first_message, str); | |
324 | |
325 rv = SendToSocket(server2.get(), second_message, broadcast_address); | |
326 ASSERT_EQ(static_cast<int>(second_message.size()), rv); | |
327 str = RecvFromSocket(server1.get()); | |
328 ASSERT_EQ(second_message, str); | |
329 str = RecvFromSocket(server2.get()); | |
330 ASSERT_EQ(second_message, str); | |
331 } | |
332 | |
333 // In this test, we verify that random binding logic works, which attempts | |
334 // to bind to a random port and returns if succeeds, otherwise retries for | |
335 // |kBindRetries| number of times. | |
336 | |
337 // To generate the scenario, we first create |kBindRetries| number of | |
338 // UDPClientSockets with default binding policy and connect to the same | |
339 // peer and save the used port numbers. Then we get rid of the last | |
340 // socket, making sure that the local port it was bound to is available. | |
341 // Finally, we create a socket with random binding policy, passing it a | |
342 // test PRNG that would serve used port numbers in the array, one after | |
343 // another. At the end, we make sure that the test socket was bound to the | |
344 // port that became available after deleting the last socket with default | |
345 // binding policy. | |
346 | |
347 // We do not test the randomness of bound ports, but that we are using | |
348 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong | |
349 // random numbers. | |
350 static const int kBindRetries = 10; | |
351 | |
352 class TestPrng { | |
353 public: | |
354 explicit TestPrng(const std::deque<int>& numbers) : numbers_(numbers) {} | |
355 int GetNext(int /* min */, int /* max */) { | |
356 DCHECK(!numbers_.empty()); | |
357 int rv = numbers_.front(); | |
358 numbers_.pop_front(); | |
359 return rv; | |
360 } | |
361 private: | |
362 std::deque<int> numbers_; | |
363 | |
364 DISALLOW_COPY_AND_ASSIGN(TestPrng); | |
365 }; | |
366 | |
367 TEST_F(UDPSocketTest, ConnectRandomBind) { | |
368 std::vector<std::unique_ptr<UDPClientSocket>> sockets; | |
369 IPEndPoint peer_address; | |
370 CreateUDPAddress("127.0.0.1", 53, &peer_address); | |
371 | |
372 // Create and connect sockets and save port numbers. | |
373 std::deque<int> used_ports; | |
374 for (int i = 0; i < kBindRetries; ++i) { | |
375 UDPClientSocket* socket = new UDPClientSocket( | |
376 DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, NetLogSource()); | |
377 sockets.push_back(base::WrapUnique(socket)); | |
378 EXPECT_THAT(socket->Connect(peer_address), IsOk()); | |
379 | |
380 IPEndPoint client_address; | |
381 EXPECT_THAT(socket->GetLocalAddress(&client_address), IsOk()); | |
382 used_ports.push_back(client_address.port()); | |
383 } | |
384 | |
385 // Free the last socket, its local port is still in |used_ports|. | |
386 sockets.pop_back(); | |
387 | |
388 TestPrng test_prng(used_ports); | |
389 RandIntCallback rand_int_cb = | |
390 base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); | |
391 | |
392 // Create a socket with random binding policy and connect. | |
393 std::unique_ptr<UDPClientSocket> test_socket(new UDPClientSocket( | |
394 DatagramSocket::RANDOM_BIND, rand_int_cb, NULL, NetLogSource())); | |
395 EXPECT_THAT(test_socket->Connect(peer_address), IsOk()); | |
396 | |
397 // Make sure that the last port number in the |used_ports| was used. | |
398 IPEndPoint client_address; | |
399 EXPECT_THAT(test_socket->GetLocalAddress(&client_address), IsOk()); | |
400 EXPECT_EQ(used_ports.back(), client_address.port()); | |
401 } | |
402 | |
403 // Return a privileged port (under 1024) so binding will fail. | |
404 int PrivilegedRand(int min, int max) { | |
405 // Chosen by fair dice roll. Guaranteed to be random. | |
406 return 4; | |
407 } | |
408 | |
409 #if defined(OS_IOS) && !TARGET_IPHONE_SIMULATOR | |
410 // TODO(droger): On iOS this test fails on device (but passes on simulator). | |
411 // See http://crbug.com/227760. | |
412 #define MAYBE_ConnectFail DISABLED_ConnectFail | |
413 #else | |
414 #define MAYBE_ConnectFail ConnectFail | |
415 #endif | |
416 TEST_F(UDPSocketTest, MAYBE_ConnectFail) { | |
417 IPEndPoint peer_address; | |
418 CreateUDPAddress("0.0.0.0", 53, &peer_address); | |
419 | |
420 std::unique_ptr<UDPSocket> socket(new UDPSocket(DatagramSocket::RANDOM_BIND, | |
421 base::Bind(&PrivilegedRand), | |
422 NULL, NetLogSource())); | |
423 int rv = socket->Open(peer_address.GetFamily()); | |
424 EXPECT_THAT(rv, IsOk()); | |
425 rv = socket->Connect(peer_address); | |
426 // Connect should have failed since we couldn't bind to that port, | |
427 EXPECT_NE(OK, rv); | |
428 // Make sure that UDPSocket actually closed the socket. | |
429 EXPECT_FALSE(socket->is_connected()); | |
430 } | |
431 | |
432 // In this test, we verify that connect() on a socket will have the effect | |
433 // of filtering reads on this socket only to data read from the destination | |
434 // we connected to. | |
435 // | |
436 // The purpose of this test is that some documentation indicates that connect | |
437 // binds the client's sends to send to a particular server endpoint, but does | |
438 // not bind the client's reads to only be from that endpoint, and that we need | |
439 // to always use recvfrom() to disambiguate. | |
440 TEST_F(UDPSocketTest, VerifyConnectBindsAddr) { | |
441 const uint16_t kPort1 = 9999; | |
442 const uint16_t kPort2 = 10000; | |
443 std::string simple_message("hello world!"); | |
444 std::string foreign_message("BAD MESSAGE TO GET!!"); | |
445 | |
446 // Setup the first server to listen. | |
447 IPEndPoint bind_address; | |
448 CreateUDPAddress("127.0.0.1", kPort1, &bind_address); | |
449 UDPServerSocket server1(NULL, NetLogSource()); | |
450 server1.AllowAddressReuse(); | |
451 int rv = server1.Listen(bind_address); | |
452 ASSERT_THAT(rv, IsOk()); | |
453 | |
454 // Setup the second server to listen. | |
455 CreateUDPAddress("127.0.0.1", kPort2, &bind_address); | |
456 UDPServerSocket server2(NULL, NetLogSource()); | |
457 server2.AllowAddressReuse(); | |
458 rv = server2.Listen(bind_address); | |
459 ASSERT_THAT(rv, IsOk()); | |
460 | |
461 // Setup the client, connected to server 1. | |
462 IPEndPoint server_address; | |
463 CreateUDPAddress("127.0.0.1", kPort1, &server_address); | |
464 UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, | |
465 NetLogSource()); | |
466 rv = client.Connect(server_address); | |
467 EXPECT_THAT(rv, IsOk()); | |
468 | |
469 // Client sends to server1. | |
470 rv = WriteSocket(&client, simple_message); | |
471 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
472 | |
473 // Server1 waits for message. | |
474 std::string str = RecvFromSocket(&server1); | |
475 DCHECK(simple_message == str); | |
476 | |
477 // Get the client's address. | |
478 IPEndPoint client_address; | |
479 rv = client.GetLocalAddress(&client_address); | |
480 EXPECT_THAT(rv, IsOk()); | |
481 | |
482 // Server2 sends reply. | |
483 rv = SendToSocket(&server2, foreign_message, | |
484 client_address); | |
485 EXPECT_EQ(foreign_message.length(), static_cast<size_t>(rv)); | |
486 | |
487 // Server1 sends reply. | |
488 rv = SendToSocket(&server1, simple_message, | |
489 client_address); | |
490 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv)); | |
491 | |
492 // Client waits for response. | |
493 str = ReadSocket(&client); | |
494 DCHECK(simple_message == str); | |
495 } | |
496 | |
497 TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) { | |
498 struct TestData { | |
499 std::string remote_address; | |
500 std::string local_address; | |
501 bool may_fail; | |
502 } tests[] = { | |
503 { "127.0.00.1", "127.0.0.1", false }, | |
504 { "::1", "::1", true }, | |
505 #if !defined(OS_ANDROID) && !defined(OS_IOS) | |
506 // Addresses below are disabled on Android. See crbug.com/161248 | |
507 // They are also disabled on iOS. See https://crbug.com/523225 | |
508 { "192.168.1.1", "127.0.0.1", false }, | |
509 { "2001:db8:0::42", "::1", true }, | |
510 #endif | |
511 }; | |
512 for (size_t i = 0; i < arraysize(tests); i++) { | |
513 SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address + | |
514 std::string(" to ") + tests[i].remote_address); | |
515 | |
516 IPAddress ip_address; | |
517 EXPECT_TRUE(ip_address.AssignFromIPLiteral(tests[i].remote_address)); | |
518 IPEndPoint remote_address(ip_address, 80); | |
519 EXPECT_TRUE(ip_address.AssignFromIPLiteral(tests[i].local_address)); | |
520 IPEndPoint local_address(ip_address, 80); | |
521 | |
522 UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), | |
523 NULL, NetLogSource()); | |
524 int rv = client.Connect(remote_address); | |
525 if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) { | |
526 // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6 | |
527 // addresses if IPv6 is not configured. | |
528 continue; | |
529 } | |
530 | |
531 EXPECT_LE(ERR_IO_PENDING, rv); | |
532 | |
533 IPEndPoint fetched_local_address; | |
534 rv = client.GetLocalAddress(&fetched_local_address); | |
535 EXPECT_THAT(rv, IsOk()); | |
536 | |
537 // TODO(mbelshe): figure out how to verify the IP and port. | |
538 // The port is dynamically generated by the udp stack. | |
539 // The IP is the real IP of the client, not necessarily | |
540 // loopback. | |
541 //EXPECT_EQ(local_address.address(), fetched_local_address.address()); | |
542 | |
543 IPEndPoint fetched_remote_address; | |
544 rv = client.GetPeerAddress(&fetched_remote_address); | |
545 EXPECT_THAT(rv, IsOk()); | |
546 | |
547 EXPECT_EQ(remote_address, fetched_remote_address); | |
548 } | |
549 } | |
550 | |
551 TEST_F(UDPSocketTest, ServerGetLocalAddress) { | |
552 IPEndPoint bind_address; | |
553 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
554 UDPServerSocket server(NULL, NetLogSource()); | |
555 int rv = server.Listen(bind_address); | |
556 EXPECT_THAT(rv, IsOk()); | |
557 | |
558 IPEndPoint local_address; | |
559 rv = server.GetLocalAddress(&local_address); | |
560 EXPECT_EQ(rv, 0); | |
561 | |
562 // Verify that port was allocated. | |
563 EXPECT_GT(local_address.port(), 0); | |
564 EXPECT_EQ(local_address.address(), bind_address.address()); | |
565 } | |
566 | |
567 TEST_F(UDPSocketTest, ServerGetPeerAddress) { | |
568 IPEndPoint bind_address; | |
569 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
570 UDPServerSocket server(NULL, NetLogSource()); | |
571 int rv = server.Listen(bind_address); | |
572 EXPECT_THAT(rv, IsOk()); | |
573 | |
574 IPEndPoint peer_address; | |
575 rv = server.GetPeerAddress(&peer_address); | |
576 EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED); | |
577 } | |
578 | |
579 TEST_F(UDPSocketTest, ClientSetDoNotFragment) { | |
580 for (std::string ip : {"127.0.0.1", "::1"}) { | |
581 LOG(INFO) << "ip: " << ip; | |
582 UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), | |
583 nullptr, NetLogSource()); | |
584 IPAddress ip_address; | |
585 EXPECT_TRUE(ip_address.AssignFromIPLiteral(ip)); | |
586 IPEndPoint remote_address(ip_address, 80); | |
587 int rv = client.Connect(remote_address); | |
588 // May fail on IPv6 is IPv6 is not configured. | |
589 if (ip_address.IsIPv6() && rv == ERR_ADDRESS_UNREACHABLE) | |
590 return; | |
591 EXPECT_THAT(rv, IsOk()); | |
592 | |
593 #if defined(OS_MACOSX) | |
594 EXPECT_EQ(ERR_NOT_IMPLEMENTED, client.SetDoNotFragment()); | |
595 #else | |
596 rv = client.SetDoNotFragment(); | |
597 EXPECT_THAT(rv, IsOk()); | |
598 #endif | |
599 } | |
600 } | |
601 | |
602 TEST_F(UDPSocketTest, ServerSetDoNotFragment) { | |
603 for (std::string ip : {"127.0.0.1", "::1"}) { | |
604 LOG(INFO) << "ip: " << ip; | |
605 IPEndPoint bind_address; | |
606 CreateUDPAddress(ip, 0, &bind_address); | |
607 UDPServerSocket server(nullptr, NetLogSource()); | |
608 int rv = server.Listen(bind_address); | |
609 // May fail on IPv6 is IPv6 is not configure | |
610 if (bind_address.address().IsIPv6() && rv == ERR_ADDRESS_INVALID) | |
611 return; | |
612 EXPECT_THAT(rv, IsOk()); | |
613 | |
614 #if defined(OS_MACOSX) | |
615 EXPECT_EQ(ERR_NOT_IMPLEMENTED, server.SetDoNotFragment()); | |
616 #else | |
617 rv = server.SetDoNotFragment(); | |
618 EXPECT_THAT(rv, IsOk()); | |
619 #endif | |
620 } | |
621 } | |
622 | |
623 // Close the socket while read is pending. | |
624 TEST_F(UDPSocketTest, CloseWithPendingRead) { | |
625 IPEndPoint bind_address; | |
626 CreateUDPAddress("127.0.0.1", 0, &bind_address); | |
627 UDPServerSocket server(NULL, NetLogSource()); | |
628 int rv = server.Listen(bind_address); | |
629 EXPECT_THAT(rv, IsOk()); | |
630 | |
631 TestCompletionCallback callback; | |
632 IPEndPoint from; | |
633 rv = server.RecvFrom(buffer_.get(), kMaxRead, &from, callback.callback()); | |
634 EXPECT_EQ(rv, ERR_IO_PENDING); | |
635 | |
636 server.Close(); | |
637 | |
638 EXPECT_FALSE(callback.have_result()); | |
639 } | |
640 | |
641 #if defined(OS_ANDROID) | |
642 // Some Android devices do not support multicast socket. | |
643 // The ones supporting multicast need WifiManager.MulitcastLock to enable it. | |
644 // http://goo.gl/jjAk9 | |
645 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup | |
646 #else | |
647 #define MAYBE_JoinMulticastGroup JoinMulticastGroup | |
648 #endif // defined(OS_ANDROID) | |
649 | |
650 TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) { | |
651 const uint16_t kPort = 9999; | |
652 const char kGroup[] = "237.132.100.17"; | |
653 | |
654 IPEndPoint bind_address; | |
655 CreateUDPAddress("0.0.0.0", kPort, &bind_address); | |
656 IPAddress group_ip; | |
657 EXPECT_TRUE(group_ip.AssignFromIPLiteral(kGroup)); | |
658 | |
659 UDPSocket socket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, | |
660 NetLogSource()); | |
661 EXPECT_THAT(socket.Open(bind_address.GetFamily()), IsOk()); | |
662 EXPECT_THAT(socket.Bind(bind_address), IsOk()); | |
663 EXPECT_THAT(socket.JoinGroup(group_ip), IsOk()); | |
664 // Joining group multiple times. | |
665 EXPECT_NE(OK, socket.JoinGroup(group_ip)); | |
666 EXPECT_THAT(socket.LeaveGroup(group_ip), IsOk()); | |
667 // Leaving group multiple times. | |
668 EXPECT_NE(OK, socket.LeaveGroup(group_ip)); | |
669 | |
670 socket.Close(); | |
671 } | |
672 | |
673 TEST_F(UDPSocketTest, MulticastOptions) { | |
674 const uint16_t kPort = 9999; | |
675 IPEndPoint bind_address; | |
676 CreateUDPAddress("0.0.0.0", kPort, &bind_address); | |
677 | |
678 UDPSocket socket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, | |
679 NetLogSource()); | |
680 // Before binding. | |
681 EXPECT_THAT(socket.SetMulticastLoopbackMode(false), IsOk()); | |
682 EXPECT_THAT(socket.SetMulticastLoopbackMode(true), IsOk()); | |
683 EXPECT_THAT(socket.SetMulticastTimeToLive(0), IsOk()); | |
684 EXPECT_THAT(socket.SetMulticastTimeToLive(3), IsOk()); | |
685 EXPECT_NE(OK, socket.SetMulticastTimeToLive(-1)); | |
686 EXPECT_THAT(socket.SetMulticastInterface(0), IsOk()); | |
687 | |
688 EXPECT_THAT(socket.Open(bind_address.GetFamily()), IsOk()); | |
689 EXPECT_THAT(socket.Bind(bind_address), IsOk()); | |
690 | |
691 EXPECT_NE(OK, socket.SetMulticastLoopbackMode(false)); | |
692 EXPECT_NE(OK, socket.SetMulticastTimeToLive(0)); | |
693 EXPECT_NE(OK, socket.SetMulticastInterface(0)); | |
694 | |
695 socket.Close(); | |
696 } | |
697 | |
698 // Checking that DSCP bits are set correctly is difficult, | |
699 // but let's check that the code doesn't crash at least. | |
700 TEST_F(UDPSocketTest, SetDSCP) { | |
701 // Setup the server to listen. | |
702 IPEndPoint bind_address; | |
703 UDPSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, | |
704 NetLogSource()); | |
705 // We need a real IP, but we won't actually send anything to it. | |
706 CreateUDPAddress("8.8.8.8", 9999, &bind_address); | |
707 int rv = client.Open(bind_address.GetFamily()); | |
708 EXPECT_THAT(rv, IsOk()); | |
709 | |
710 rv = client.Connect(bind_address); | |
711 if (rv != OK) { | |
712 // Let's try localhost then.. | |
713 CreateUDPAddress("127.0.0.1", 9999, &bind_address); | |
714 rv = client.Connect(bind_address); | |
715 } | |
716 EXPECT_THAT(rv, IsOk()); | |
717 | |
718 client.SetDiffServCodePoint(DSCP_NO_CHANGE); | |
719 client.SetDiffServCodePoint(DSCP_AF41); | |
720 client.SetDiffServCodePoint(DSCP_DEFAULT); | |
721 client.SetDiffServCodePoint(DSCP_CS2); | |
722 client.SetDiffServCodePoint(DSCP_NO_CHANGE); | |
723 client.SetDiffServCodePoint(DSCP_DEFAULT); | |
724 client.Close(); | |
725 } | |
726 | |
727 TEST_F(UDPSocketTest, TestBindToNetwork) { | |
728 UDPSocket socket(DatagramSocket::RANDOM_BIND, base::Bind(&PrivilegedRand), | |
729 NULL, NetLogSource()); | |
730 ASSERT_EQ(OK, socket.Open(ADDRESS_FAMILY_IPV4)); | |
731 // Test unsuccessful binding, by attempting to bind to a bogus NetworkHandle. | |
732 int rv = socket.BindToNetwork(65536); | |
733 #if !defined(OS_ANDROID) | |
734 EXPECT_EQ(ERR_NOT_IMPLEMENTED, rv); | |
735 #else | |
736 if (base::android::BuildInfo::GetInstance()->sdk_int() < | |
737 base::android::SDK_VERSION_LOLLIPOP) { | |
738 EXPECT_EQ(ERR_NOT_IMPLEMENTED, rv); | |
739 } else if (base::android::BuildInfo::GetInstance()->sdk_int() >= | |
740 base::android::SDK_VERSION_LOLLIPOP && | |
741 base::android::BuildInfo::GetInstance()->sdk_int() < | |
742 base::android::SDK_VERSION_MARSHMALLOW) { | |
743 // On Lollipop, we assume if the user has a NetworkHandle that they must | |
744 // have gotten it from a legitimate source, so if binding to the network | |
745 // fails it's assumed to be because the network went away so | |
746 // ERR_NETWORK_CHANGED is returned. In this test the network never existed | |
747 // anyhow. ConnectivityService.MAX_NET_ID is 65535, so 65536 won't be used. | |
748 EXPECT_EQ(ERR_NETWORK_CHANGED, rv); | |
749 } else if (base::android::BuildInfo::GetInstance()->sdk_int() >= | |
750 base::android::SDK_VERSION_MARSHMALLOW) { | |
751 // On Marshmallow and newer releases, the NetworkHandle is munged by | |
752 // Network.getNetworkHandle() and 65536 isn't munged so it's rejected. | |
753 EXPECT_EQ(ERR_INVALID_ARGUMENT, rv); | |
754 } | |
755 | |
756 if (base::android::BuildInfo::GetInstance()->sdk_int() >= | |
757 base::android::SDK_VERSION_LOLLIPOP) { | |
758 EXPECT_EQ( | |
759 ERR_INVALID_ARGUMENT, | |
760 socket.BindToNetwork(NetworkChangeNotifier::kInvalidNetworkHandle)); | |
761 | |
762 // Test successful binding, if possible. | |
763 if (NetworkChangeNotifier::AreNetworkHandlesSupported()) { | |
764 NetworkChangeNotifier::NetworkHandle network_handle = | |
765 NetworkChangeNotifier::GetDefaultNetwork(); | |
766 if (network_handle != NetworkChangeNotifier::kInvalidNetworkHandle) { | |
767 EXPECT_EQ(OK, socket.BindToNetwork(network_handle)); | |
768 } | |
769 } | |
770 } | |
771 #endif | |
772 } | |
773 | |
774 } // namespace | |
775 | |
776 #if defined(OS_WIN) | |
777 | |
778 namespace { | |
779 | |
780 const HANDLE kFakeHandle = (HANDLE)19; | |
781 const QOS_FLOWID kFakeFlowId = (QOS_FLOWID)27; | |
782 | |
783 BOOL WINAPI FakeQOSCreateHandleFAIL(PQOS_VERSION version, PHANDLE handle) { | |
784 EXPECT_EQ(0, version->MinorVersion); | |
785 EXPECT_EQ(1, version->MajorVersion); | |
786 SetLastError(ERROR_OPEN_FAILED); | |
787 return false; | |
788 } | |
789 | |
790 BOOL WINAPI FakeQOSCreateHandle(PQOS_VERSION version, PHANDLE handle) { | |
791 EXPECT_EQ(0, version->MinorVersion); | |
792 EXPECT_EQ(1, version->MajorVersion); | |
793 *handle = kFakeHandle; | |
794 return true; | |
795 } | |
796 | |
797 BOOL WINAPI FakeQOSCloseHandle(HANDLE handle) { | |
798 EXPECT_EQ(kFakeHandle, handle); | |
799 return true; | |
800 } | |
801 | |
802 QOS_TRAFFIC_TYPE g_expected_traffic_type; | |
803 | |
804 BOOL WINAPI FakeQOSAddSocketToFlow(HANDLE handle, | |
805 SOCKET socket, | |
806 PSOCKADDR addr, | |
807 QOS_TRAFFIC_TYPE traffic_type, | |
808 DWORD flags, | |
809 PQOS_FLOWID flow_id) { | |
810 EXPECT_EQ(kFakeHandle, handle); | |
811 EXPECT_EQ(NULL, addr); | |
812 EXPECT_EQ(static_cast<DWORD>(QOS_NON_ADAPTIVE_FLOW), flags); | |
813 EXPECT_EQ(0u, *flow_id); | |
814 *flow_id = kFakeFlowId; | |
815 return true; | |
816 } | |
817 | |
818 BOOL WINAPI FakeQOSRemoveSocketFromFlow(HANDLE handle, | |
819 SOCKET socket, | |
820 QOS_FLOWID flowid, | |
821 DWORD reserved) { | |
822 EXPECT_EQ(kFakeHandle, handle); | |
823 EXPECT_EQ(0u, socket); | |
824 EXPECT_EQ(kFakeFlowId, flowid); | |
825 EXPECT_EQ(0u, reserved); | |
826 return true; | |
827 } | |
828 | |
829 DWORD g_expected_dscp; | |
830 | |
831 BOOL WINAPI FakeQOSSetFlow(HANDLE handle, | |
832 QOS_FLOWID flow_id, | |
833 QOS_SET_FLOW op, | |
834 ULONG size, | |
835 PVOID data, | |
836 DWORD reserved, | |
837 LPOVERLAPPED overlapped) { | |
838 EXPECT_EQ(kFakeHandle, handle); | |
839 EXPECT_EQ(QOSSetOutgoingDSCPValue, op); | |
840 EXPECT_EQ(sizeof(DWORD), size); | |
841 EXPECT_EQ(g_expected_dscp, *reinterpret_cast<DWORD*>(data)); | |
842 EXPECT_EQ(kFakeFlowId, flow_id); | |
843 EXPECT_EQ(0u, reserved); | |
844 EXPECT_EQ(NULL, overlapped); | |
845 return true; | |
846 } | |
847 | |
848 } // namespace | |
849 | |
850 // Mock out the Qwave functions and make sure they are | |
851 // called correctly. Must be in net namespace for friendship | |
852 // reasons. | |
853 TEST_F(UDPSocketTest, SetDSCPFake) { | |
854 // Setup the server to listen. | |
855 IPEndPoint bind_address; | |
856 // We need a real IP, but we won't actually send anything to it. | |
857 CreateUDPAddress("8.8.8.8", 9999, &bind_address); | |
858 UDPSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, | |
859 NetLogSource()); | |
860 int rv = client.SetDiffServCodePoint(DSCP_AF41); | |
861 EXPECT_THAT(rv, IsError(ERR_SOCKET_NOT_CONNECTED)); | |
862 | |
863 rv = client.Open(bind_address.GetFamily()); | |
864 EXPECT_THAT(rv, IsOk()); | |
865 | |
866 rv = client.Connect(bind_address); | |
867 EXPECT_THAT(rv, IsOk()); | |
868 | |
869 QwaveAPI& qos(QwaveAPI::Get()); | |
870 qos.create_handle_func_ = FakeQOSCreateHandleFAIL; | |
871 qos.close_handle_func_ = FakeQOSCloseHandle; | |
872 qos.add_socket_to_flow_func_ = FakeQOSAddSocketToFlow; | |
873 qos.remove_socket_from_flow_func_ = FakeQOSRemoveSocketFromFlow; | |
874 qos.set_flow_func_ = FakeQOSSetFlow; | |
875 qos.qwave_supported_ = true; | |
876 | |
877 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_NO_CHANGE), IsOk()); | |
878 EXPECT_EQ(ERROR_NOT_SUPPORTED, client.SetDiffServCodePoint(DSCP_AF41)); | |
879 qos.create_handle_func_ = FakeQOSCreateHandle; | |
880 g_expected_dscp = DSCP_AF41; | |
881 g_expected_traffic_type = QOSTrafficTypeAudioVideo; | |
882 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_AF41), IsOk()); | |
883 g_expected_dscp = DSCP_DEFAULT; | |
884 g_expected_traffic_type = QOSTrafficTypeBestEffort; | |
885 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_DEFAULT), IsOk()); | |
886 g_expected_dscp = DSCP_CS2; | |
887 g_expected_traffic_type = QOSTrafficTypeExcellentEffort; | |
888 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_CS2), IsOk()); | |
889 g_expected_dscp = DSCP_CS3; | |
890 g_expected_traffic_type = QOSTrafficTypeExcellentEffort; | |
891 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_NO_CHANGE), IsOk()); | |
892 g_expected_dscp = DSCP_DEFAULT; | |
893 g_expected_traffic_type = QOSTrafficTypeBestEffort; | |
894 EXPECT_THAT(client.SetDiffServCodePoint(DSCP_DEFAULT), IsOk()); | |
895 client.Close(); | |
896 } | |
897 #endif | |
898 | |
899 } // namespace net | |
OLD | NEW |