1 // Copyright 2018 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 "services/network/proxy_auto_config_library.h"
6
7 #include "net/base/address_list.h"
8 #include "net/base/net_errors.h"
9 #include "net/base/network_interfaces.h"
10 #include "net/log/net_log_with_source.h"
11 #include "net/socket/client_socket_factory.h"
12 #include "net/socket/client_socket_handle.h"
13 #include "net/socket/datagram_client_socket.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace network {
18 namespace {
19
20 // Helper for verifying whether the address list returned by myIpAddress() /
21 // myIpAddressEx() looks correct.
VerifyActualMyIpAddresses(const net::IPAddressList & test_list)22 void VerifyActualMyIpAddresses(const net::IPAddressList& test_list) {
23 // Enumerate all of the IP addresses for the system (skipping loopback and
24 // link-local ones). This is used as a reference implementation to check
25 // whether |test_list| (which was obtained using a different strategy) looks
26 // correct.
27 std::set<net::IPAddress> candidates;
28 net::NetworkInterfaceList networks;
29 net::GetNetworkList(&networks, net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
30 for (const auto& network : networks) {
31 if (network.address.IsLinkLocal() || network.address.IsLoopback())
32 continue;
33 candidates.insert(network.address);
34 }
35
36 // Ordinarily the machine running this test will have an IP address. However
37 // for some bot configurations (notably Android) that may not be the case.
38 EXPECT_EQ(candidates.empty(), test_list.empty());
39
40 // |test_list| should be a subset of |candidates|.
41 for (const auto& ip : test_list)
42 EXPECT_EQ(1u, candidates.count(ip));
43 }
44
45 // Tests for PacMyIpAddress() and PacMyIpAddressEx().
TEST(PacLibraryTest,ActualPacMyIpAddress)46 TEST(PacLibraryTest, ActualPacMyIpAddress) {
47 auto my_ip_addresses = PacMyIpAddress();
48
49 VerifyActualMyIpAddresses(my_ip_addresses);
50 }
51
TEST(PacLibraryTest,ActualPacMyIpAddressEx)52 TEST(PacLibraryTest, ActualPacMyIpAddressEx) {
53 VerifyActualMyIpAddresses(PacMyIpAddressEx());
54 }
55
CreateIPAddress(base::StringPiece literal)56 net::IPAddress CreateIPAddress(base::StringPiece literal) {
57 net::IPAddress result;
58 if (!result.AssignFromIPLiteral(literal)) {
59 ADD_FAILURE() << "Failed parsing IP: " << literal;
60 return net::IPAddress();
61 }
62 return result;
63 }
64
CreateAddressList(const std::vector<base::StringPiece> & ip_literals)65 net::AddressList CreateAddressList(
66 const std::vector<base::StringPiece>& ip_literals) {
67 net::AddressList result;
68 for (const auto& ip : ip_literals)
69 result.push_back(net::IPEndPoint(CreateIPAddress(ip), 8080));
70 return result;
71 }
72
73 class MockUDPSocket : public net::DatagramClientSocket {
74 public:
MockUDPSocket(const net::IPAddress & peer_ip,const net::IPAddress & local_ip,net::Error connect_error)75 MockUDPSocket(const net::IPAddress& peer_ip,
76 const net::IPAddress& local_ip,
77 net::Error connect_error)
78 : peer_ip_(peer_ip), local_ip_(local_ip), connect_error_(connect_error) {}
79
80 ~MockUDPSocket() override = default;
81
82 // Socket implementation.
Read(net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)83 int Read(net::IOBuffer* buf,
84 int buf_len,
85 net::CompletionOnceCallback callback) override {
86 ADD_FAILURE() << "Called Read()";
87 return net::ERR_UNEXPECTED;
88 }
Write(net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback,const net::NetworkTrafficAnnotationTag & traffic_annotation)89 int Write(
90 net::IOBuffer* buf,
91 int buf_len,
92 net::CompletionOnceCallback callback,
93 const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
94 ADD_FAILURE() << "Called Read()";
95 return net::ERR_UNEXPECTED;
96 }
SetReceiveBufferSize(int32_t size)97 int SetReceiveBufferSize(int32_t size) override {
98 ADD_FAILURE() << "Called SetReceiveBufferSize()";
99 return net::ERR_UNEXPECTED;
100 }
SetSendBufferSize(int32_t size)101 int SetSendBufferSize(int32_t size) override {
102 ADD_FAILURE() << "Called SetSendBufferSize()";
103 return net::ERR_UNEXPECTED;
104 }
105
106 // net::DatagramSocket implementation.
Close()107 void Close() override { ADD_FAILURE() << "Called Close()"; }
GetPeerAddress(net::IPEndPoint * address) const108 int GetPeerAddress(net::IPEndPoint* address) const override {
109 ADD_FAILURE() << "Called GetPeerAddress()";
110 return net::ERR_UNEXPECTED;
111 }
GetLocalAddress(net::IPEndPoint * address) const112 int GetLocalAddress(net::IPEndPoint* address) const override {
113 if (connect_error_ != net::OK)
114 return connect_error_;
115
116 *address = net::IPEndPoint(local_ip_, 8080);
117 return net::OK;
118 }
UseNonBlockingIO()119 void UseNonBlockingIO() override {
120 ADD_FAILURE() << "Called UseNonBlockingIO()";
121 }
SetDoNotFragment()122 int SetDoNotFragment() override {
123 ADD_FAILURE() << "Called SetDoNotFragment()";
124 return net::ERR_UNEXPECTED;
125 }
SetMsgConfirm(bool confirm)126 void SetMsgConfirm(bool confirm) override {
127 ADD_FAILURE() << "Called SetMsgConfirm()";
128 }
NetLog() const129 const net::NetLogWithSource& NetLog() const override {
130 ADD_FAILURE() << "Called net::NetLog()";
131 return net_log_;
132 }
133
134 // net::DatagramClientSocket implementation.
Connect(const net::IPEndPoint & address)135 int Connect(const net::IPEndPoint& address) override {
136 EXPECT_EQ(peer_ip_.ToString(), address.address().ToString());
137 return connect_error_;
138 }
ConnectUsingNetwork(net::NetworkChangeNotifier::NetworkHandle network,const net::IPEndPoint & address)139 int ConnectUsingNetwork(net::NetworkChangeNotifier::NetworkHandle network,
140 const net::IPEndPoint& address) override {
141 ADD_FAILURE() << "Called ConnectUsingNetwork()";
142 return net::ERR_UNEXPECTED;
143 }
ConnectUsingDefaultNetwork(const net::IPEndPoint & address)144 int ConnectUsingDefaultNetwork(const net::IPEndPoint& address) override {
145 ADD_FAILURE() << "Called ConnectUsingDefaultNetwork()";
146 return net::ERR_UNEXPECTED;
147 }
GetBoundNetwork() const148 net::NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override {
149 ADD_FAILURE() << "Called GetBoundNetwork()";
150 return network_;
151 }
ApplySocketTag(const net::SocketTag & tag)152 void ApplySocketTag(const net::SocketTag& tag) override {
153 ADD_FAILURE() << "Called ApplySocketTag()";
154 }
WriteAsync(net::DatagramBuffers buffers,net::CompletionOnceCallback callback,const net::NetworkTrafficAnnotationTag & traffic_annotation)155 int WriteAsync(
156 net::DatagramBuffers buffers,
157 net::CompletionOnceCallback callback,
158 const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
159 ADD_FAILURE() << "Called WriteAsync()";
160 return net::ERR_UNEXPECTED;
161 }
WriteAsync(const char * buffer,size_t buf_len,net::CompletionOnceCallback callback,const net::NetworkTrafficAnnotationTag & traffic_annotation)162 int WriteAsync(
163 const char* buffer,
164 size_t buf_len,
165 net::CompletionOnceCallback callback,
166 const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
167 ADD_FAILURE() << "Called WriteAsync()";
168 return net::ERR_UNEXPECTED;
169 }
GetUnwrittenBuffers()170 net::DatagramBuffers GetUnwrittenBuffers() override {
171 ADD_FAILURE() << "Called GetUnwrittenBuffers()";
172 return net::DatagramBuffers();
173 }
SetWriteAsyncEnabled(bool enabled)174 void SetWriteAsyncEnabled(bool enabled) override {
175 ADD_FAILURE() << "Called SetWriteAsyncEnabled()";
176 }
SetMaxPacketSize(size_t max_packet_size)177 void SetMaxPacketSize(size_t max_packet_size) override {
178 ADD_FAILURE() << "Called SetWriteAsyncEnabled()";
179 }
WriteAsyncEnabled()180 bool WriteAsyncEnabled() override {
181 ADD_FAILURE() << "Called WriteAsyncEnabled()";
182 return false;
183 }
SetWriteMultiCoreEnabled(bool enabled)184 void SetWriteMultiCoreEnabled(bool enabled) override {
185 ADD_FAILURE() << "Called SetWriteMultiCoreEnabled()";
186 }
SetSendmmsgEnabled(bool enabled)187 void SetSendmmsgEnabled(bool enabled) override {
188 ADD_FAILURE() << "Called SetSendmmsgEnabled()";
189 }
SetWriteBatchingActive(bool active)190 void SetWriteBatchingActive(bool active) override {
191 ADD_FAILURE() << "Called SetWriteBatchingActive()";
192 }
SetMulticastInterface(uint32_t interface_index)193 int SetMulticastInterface(uint32_t interface_index) override {
194 ADD_FAILURE() << "Called SetMulticastInterface()";
195 return net::ERR_UNEXPECTED;
196 }
197
198 private:
199 net::NetLogWithSource net_log_;
200 net::NetworkChangeNotifier::NetworkHandle network_;
201
202 net::IPAddress peer_ip_;
203 net::IPAddress local_ip_;
204 net::Error connect_error_;
205
206 DISALLOW_COPY_AND_ASSIGN(MockUDPSocket);
207 };
208
209 class MockSocketFactory : public net::ClientSocketFactory {
210 public:
211 MockSocketFactory() = default;
212
AddUDPConnectSuccess(base::StringPiece peer_ip_literal,base::StringPiece local_ip_literal)213 void AddUDPConnectSuccess(base::StringPiece peer_ip_literal,
214 base::StringPiece local_ip_literal) {
215 auto peer_ip = CreateIPAddress(peer_ip_literal);
216 auto local_ip = CreateIPAddress(local_ip_literal);
217
218 // The address family of local and peer IP must match.
219 ASSERT_EQ(peer_ip.size(), local_ip.size());
220
221 udp_sockets_.push_back(
222 std::make_unique<MockUDPSocket>(peer_ip, local_ip, net::OK));
223 }
224
AddUDPConnectFailure(base::StringPiece peer_ip)225 void AddUDPConnectFailure(base::StringPiece peer_ip) {
226 udp_sockets_.push_back(std::make_unique<MockUDPSocket>(
227 CreateIPAddress(peer_ip), net::IPAddress(),
228 net::ERR_ADDRESS_UNREACHABLE));
229 }
230
~MockSocketFactory()231 ~MockSocketFactory() override {
232 EXPECT_EQ(0u, udp_sockets_.size())
233 << "Not all of the mock sockets were consumed.";
234 }
235
236 // net::ClientSocketFactory
CreateDatagramClientSocket(net::DatagramSocket::BindType bind_type,net::NetLog * net_log,const net::NetLogSource & source)237 std::unique_ptr<net::DatagramClientSocket> CreateDatagramClientSocket(
238 net::DatagramSocket::BindType bind_type,
239 net::NetLog* net_log,
240 const net::NetLogSource& source) override {
241 if (udp_sockets_.empty()) {
242 ADD_FAILURE() << "Not enough mock UDP sockets";
243 return nullptr;
244 }
245
246 auto result = std::move(udp_sockets_.front());
247 udp_sockets_.erase(udp_sockets_.begin());
248 return result;
249 }
CreateTransportClientSocket(const net::AddressList & addresses,std::unique_ptr<net::SocketPerformanceWatcher> socket_performance_watcher,net::NetLog * net_log,const net::NetLogSource & source)250 std::unique_ptr<net::TransportClientSocket> CreateTransportClientSocket(
251 const net::AddressList& addresses,
252 std::unique_ptr<net::SocketPerformanceWatcher> socket_performance_watcher,
253 net::NetLog* net_log,
254 const net::NetLogSource& source) override {
255 ADD_FAILURE() << "Called CreateTransportClientSocket()";
256 return nullptr;
257 }
CreateSSLClientSocket(net::SSLClientContext * context,std::unique_ptr<net::StreamSocket> stream_socket,const net::HostPortPair & host_and_port,const net::SSLConfig & ssl_config)258 std::unique_ptr<net::SSLClientSocket> CreateSSLClientSocket(
259 net::SSLClientContext* context,
260 std::unique_ptr<net::StreamSocket> stream_socket,
261 const net::HostPortPair& host_and_port,
262 const net::SSLConfig& ssl_config) override {
263 ADD_FAILURE() << "Called CreateSSLClientSocket()";
264 return nullptr;
265 }
CreateProxyClientSocket(std::unique_ptr<net::StreamSocket> stream_socket,const std::string & user_agent,const net::HostPortPair & endpoint,const net::ProxyServer & proxy_server,net::HttpAuthController * http_auth_controller,bool tunnel,bool using_spdy,net::NextProto negotiated_protocol,net::ProxyDelegate * proxy_delegate,const net::NetworkTrafficAnnotationTag & traffic_annotation)266 std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket(
267 std::unique_ptr<net::StreamSocket> stream_socket,
268 const std::string& user_agent,
269 const net::HostPortPair& endpoint,
270 const net::ProxyServer& proxy_server,
271 net::HttpAuthController* http_auth_controller,
272 bool tunnel,
273 bool using_spdy,
274 net::NextProto negotiated_protocol,
275 net::ProxyDelegate* proxy_delegate,
276 const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
277 ADD_FAILURE() << "Called CreateProxyClientSocket()";
278 return nullptr;
279 }
280
281 private:
282 std::vector<std::unique_ptr<MockUDPSocket>> udp_sockets_;
283
284 DISALLOW_COPY_AND_ASSIGN(MockSocketFactory);
285 };
286
287 // Tests myIpAddress() when there is a route to 8.8.8.8.
TEST(PacLibraryTest,PacMyIpAddress8888)288 TEST(PacLibraryTest, PacMyIpAddress8888) {
289 MockSocketFactory factory;
290 factory.AddUDPConnectSuccess("8.8.8.8", "192.168.1.1");
291
292 auto result = PacMyIpAddressForTest(&factory, {});
293 ASSERT_EQ(1u, result.size());
294 EXPECT_EQ("192.168.1.1", result.front().ToString());
295 }
296
297 // Tests myIpAddress() when there is no route to 8.8.8.8, but there is one to
298 // 2001:4860:4860::8888.
TEST(PacLibraryTest,PacMyIpAddress2001)299 TEST(PacLibraryTest, PacMyIpAddress2001) {
300 MockSocketFactory factory;
301 factory.AddUDPConnectFailure("8.8.8.8");
302 factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::beef");
303
304 net::AddressList dns_result;
305
306 auto result = PacMyIpAddressForTest(&factory, dns_result);
307 ASSERT_EQ(1u, result.size());
308 EXPECT_EQ("2001::beef", result.front().ToString());
309 }
310
311 // Tests myIpAddress() when there is no route to 8.8.8.8, no route to
312 // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds results. Most
313 // of those results are skipped over, and the IPv4 one is favored.
TEST(PacLibraryTest,PacMyIpAddressHostname)314 TEST(PacLibraryTest, PacMyIpAddressHostname) {
315 MockSocketFactory factory;
316 factory.AddUDPConnectFailure("8.8.8.8");
317 factory.AddUDPConnectFailure("2001:4860:4860::8888");
318
319 net::AddressList dns_result = CreateAddressList({
320 "169.254.13.16",
321 "127.0.0.1",
322 "::1",
323 "fe89::beef",
324 "2001::f001",
325 "178.1.99.3",
326 "192.168.1.3",
327 });
328
329 auto result = PacMyIpAddressForTest(&factory, dns_result);
330 ASSERT_EQ(1u, result.size());
331 EXPECT_EQ("178.1.99.3", result.front().ToString());
332 }
333
334 // Tests myIpAddress() when there is no route to 8.8.8.8, no route to
335 // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds multiple IPv6
336 // results.
TEST(PacLibraryTest,PacMyIpAddressHostnameAllIPv6)337 TEST(PacLibraryTest, PacMyIpAddressHostnameAllIPv6) {
338 MockSocketFactory factory;
339 factory.AddUDPConnectFailure("8.8.8.8");
340 factory.AddUDPConnectFailure("2001:4860:4860::8888");
341
342 net::AddressList dns_result =
343 CreateAddressList({"::1", "2001::f001", "2001::f00d", "169.254.0.6"});
344
345 auto result = PacMyIpAddressForTest(&factory, dns_result);
346 ASSERT_EQ(1u, result.size());
347 EXPECT_EQ("2001::f001", result.front().ToString());
348 }
349
350 // Tests myIpAddress() when there is no route to 8.8.8.8, no route to
351 // 2001:4860:4860::8888, no acceptable result in getaddrinfo(gethostname()),
352 // however there is a route for private address.
TEST(PacLibraryTest,PacMyIpAddressPrivateIPv4)353 TEST(PacLibraryTest, PacMyIpAddressPrivateIPv4) {
354 MockSocketFactory factory;
355 factory.AddUDPConnectFailure("8.8.8.8");
356 factory.AddUDPConnectFailure("2001:4860:4860::8888");
357
358 net::AddressList dns_result = CreateAddressList({
359 "169.254.13.16",
360 "127.0.0.1",
361 "::1",
362 "fe89::beef",
363 });
364
365 factory.AddUDPConnectSuccess("10.0.0.0", "127.0.0.1");
366 factory.AddUDPConnectFailure("172.16.0.0");
367 factory.AddUDPConnectSuccess("192.168.0.0", "63.31.9.8");
368
369 auto result = PacMyIpAddressForTest(&factory, dns_result);
370 ASSERT_EQ(1u, result.size());
371 EXPECT_EQ("63.31.9.8", result.front().ToString());
372 }
373
374 // Tests myIpAddress() when there is no route to 8.8.8.8, no route to
375 // 2001:4860:4860::8888, no acceptable result in getaddrinfo(gethostname()),
376 // however there is a route for private address.
TEST(PacLibraryTest,PacMyIpAddressPrivateIPv6)377 TEST(PacLibraryTest, PacMyIpAddressPrivateIPv6) {
378 MockSocketFactory factory;
379 factory.AddUDPConnectFailure("8.8.8.8");
380 factory.AddUDPConnectFailure("2001:4860:4860::8888");
381
382 net::AddressList dns_result;
383
384 factory.AddUDPConnectSuccess("10.0.0.0", "127.0.0.1");
385 factory.AddUDPConnectFailure("172.16.0.0");
386 factory.AddUDPConnectFailure("192.168.0.0");
387 factory.AddUDPConnectSuccess("FC00::", "2001::7777");
388
389 auto result = PacMyIpAddressForTest(&factory, dns_result);
390 ASSERT_EQ(1u, result.size());
391 EXPECT_EQ("2001::7777", result.front().ToString());
392 }
393
394 // Tests myIpAddress() when there are no routes, and getaddrinfo(gethostname())
395 // fails.
TEST(PacLibraryTest,PacMyIpAddressAllFail)396 TEST(PacLibraryTest, PacMyIpAddressAllFail) {
397 MockSocketFactory factory;
398 factory.AddUDPConnectFailure("8.8.8.8");
399 factory.AddUDPConnectFailure("2001:4860:4860::8888");
400
401 net::AddressList dns_result;
402
403 factory.AddUDPConnectFailure("10.0.0.0");
404 factory.AddUDPConnectFailure("172.16.0.0");
405 factory.AddUDPConnectFailure("192.168.0.0");
406 factory.AddUDPConnectFailure("FC00::");
407
408 auto result = PacMyIpAddressForTest(&factory, dns_result);
409 EXPECT_EQ(0u, result.size());
410 }
411
412 // Tests myIpAddress() when there are no routes, and
413 // getaddrinfo(gethostname()) only returns loopback.
TEST(PacLibraryTest,PacMyIpAddressAllFailOrLoopback)414 TEST(PacLibraryTest, PacMyIpAddressAllFailOrLoopback) {
415 MockSocketFactory factory;
416 factory.AddUDPConnectFailure("8.8.8.8");
417 factory.AddUDPConnectFailure("2001:4860:4860::8888");
418
419 net::AddressList dns_result = CreateAddressList({"127.0.0.1", "::1"});
420
421 factory.AddUDPConnectFailure("10.0.0.0");
422 factory.AddUDPConnectFailure("172.16.0.0");
423 factory.AddUDPConnectFailure("192.168.0.0");
424 factory.AddUDPConnectFailure("FC00::");
425
426 auto result = PacMyIpAddressForTest(&factory, dns_result);
427 EXPECT_EQ(0u, result.size());
428 }
429
430 // Tests myIpAddress() when there is only an IPv6 link-local address.
TEST(PacLibraryTest,PacMyIpAddressAllFailHasLinkLocal)431 TEST(PacLibraryTest, PacMyIpAddressAllFailHasLinkLocal) {
432 MockSocketFactory factory;
433 factory.AddUDPConnectFailure("8.8.8.8");
434 factory.AddUDPConnectFailure("2001:4860:4860::8888");
435
436 net::AddressList dns_result =
437 CreateAddressList({"127.0.0.1", "::1", "fe81::8881"});
438
439 factory.AddUDPConnectFailure("10.0.0.0");
440 factory.AddUDPConnectFailure("172.16.0.0");
441 factory.AddUDPConnectFailure("192.168.0.0");
442 factory.AddUDPConnectFailure("FC00::");
443
444 auto result = PacMyIpAddressForTest(&factory, dns_result);
445 ASSERT_EQ(1u, result.size());
446 EXPECT_EQ("fe81::8881", result.front().ToString());
447 }
448
449 // Tests myIpAddress() when there are only link-local addresses. The IPv4
450 // link-local address is favored.
TEST(PacLibraryTest,PacMyIpAddressAllFailHasLinkLocalFavorIPv4)451 TEST(PacLibraryTest, PacMyIpAddressAllFailHasLinkLocalFavorIPv4) {
452 MockSocketFactory factory;
453 factory.AddUDPConnectFailure("8.8.8.8");
454 factory.AddUDPConnectFailure("2001:4860:4860::8888");
455
456 net::AddressList dns_result =
457 CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "169.254.89.133"});
458
459 factory.AddUDPConnectFailure("10.0.0.0");
460 factory.AddUDPConnectFailure("172.16.0.0");
461 factory.AddUDPConnectFailure("192.168.0.0");
462 factory.AddUDPConnectFailure("FC00::");
463
464 auto result = PacMyIpAddressForTest(&factory, dns_result);
465 ASSERT_EQ(1u, result.size());
466 EXPECT_EQ("169.254.89.133", result.front().ToString());
467 }
468
469 // Tests myIpAddressEx() when there is a route to 8.8.8.8 but not one to
470 // 2001:4860:4860::8888
TEST(PacLibraryTest,PacMyIpAddressEx8888)471 TEST(PacLibraryTest, PacMyIpAddressEx8888) {
472 MockSocketFactory factory;
473 factory.AddUDPConnectSuccess("8.8.8.8", "192.168.1.1");
474 factory.AddUDPConnectFailure("2001:4860:4860::8888");
475
476 auto result = PacMyIpAddressExForTest(&factory, {});
477 ASSERT_EQ(1u, result.size());
478 EXPECT_EQ("192.168.1.1", result.front().ToString());
479 }
480
481 // Tests myIpAddressEx() when there is a route to 2001:4860:4860::8888 but
482 // not 8.8.8.8.
TEST(PacLibraryTest,PacMyIpAddressEx2001)483 TEST(PacLibraryTest, PacMyIpAddressEx2001) {
484 MockSocketFactory factory;
485 factory.AddUDPConnectFailure("8.8.8.8");
486 factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::3333");
487
488 net::AddressList dns_result;
489
490 auto result = PacMyIpAddressExForTest(&factory, dns_result);
491 ASSERT_EQ(1u, result.size());
492 EXPECT_EQ("2001::3333", result.front().ToString());
493 }
494
495 // Tests myIpAddressEx() when there is a route to both 8.8.8.8 and
496 // 2001:4860:4860::8888.
TEST(PacLibraryTest,PacMyIpAddressEx8888And2001)497 TEST(PacLibraryTest, PacMyIpAddressEx8888And2001) {
498 MockSocketFactory factory;
499 factory.AddUDPConnectSuccess("8.8.8.8", "192.168.17.8");
500 factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::8333");
501
502 net::AddressList dns_result;
503
504 auto result = PacMyIpAddressExForTest(&factory, dns_result);
505 ASSERT_EQ(2u, result.size());
506 EXPECT_EQ("192.168.17.8", result.front().ToString());
507 EXPECT_EQ("2001::8333", result.back().ToString());
508 }
509
510 // Tests myIpAddressEx() when there is no route to 8.8.8.8, no route to
511 // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds results. Some
512 // of those results are skipped due to being link-local and loopback.
TEST(PacLibraryTest,PacMyIpAddressExHostname)513 TEST(PacLibraryTest, PacMyIpAddressExHostname) {
514 MockSocketFactory factory;
515 factory.AddUDPConnectFailure("8.8.8.8");
516 factory.AddUDPConnectFailure("2001:4860:4860::8888");
517
518 net::AddressList dns_result = CreateAddressList({
519 "169.254.13.16",
520 "::1",
521 "fe89::beef",
522 "2001::bebe",
523 "178.1.99.3",
524 "127.0.0.1",
525 "192.168.1.3",
526 });
527
528 auto result = PacMyIpAddressExForTest(&factory, dns_result);
529 ASSERT_EQ(3u, result.size());
530 EXPECT_EQ("2001::bebe", result[0].ToString());
531 EXPECT_EQ("178.1.99.3", result[1].ToString());
532 EXPECT_EQ("192.168.1.3", result[2].ToString());
533 }
534
535 // Tests myIpAddressEx() when routes are found for private IP space.
TEST(PacLibraryTest,PacMyIpAddressExPrivateDuplicates)536 TEST(PacLibraryTest, PacMyIpAddressExPrivateDuplicates) {
537 MockSocketFactory factory;
538 factory.AddUDPConnectFailure("8.8.8.8");
539 factory.AddUDPConnectFailure("2001:4860:4860::8888");
540
541 net::AddressList dns_result;
542
543 factory.AddUDPConnectSuccess("10.0.0.0", "192.168.3.3");
544 factory.AddUDPConnectSuccess("172.16.0.0", "192.168.3.4");
545 factory.AddUDPConnectSuccess("192.168.0.0", "192.168.3.3");
546 factory.AddUDPConnectSuccess("FC00::", "2001::beef");
547
548 auto result = PacMyIpAddressExForTest(&factory, dns_result);
549
550 // Note that 192.168.3.3. was probed twice, but only added once to the final
551 // result.
552 ASSERT_EQ(3u, result.size());
553 EXPECT_EQ("192.168.3.3", result[0].ToString());
554 EXPECT_EQ("192.168.3.4", result[1].ToString());
555 EXPECT_EQ("2001::beef", result[2].ToString());
556 }
557
558 // Tests myIpAddressEx() when there are no routes, and
559 // getaddrinfo(gethostname()) fails.
TEST(PacLibraryTest,PacMyIpAddressExAllFail)560 TEST(PacLibraryTest, PacMyIpAddressExAllFail) {
561 MockSocketFactory factory;
562 factory.AddUDPConnectFailure("8.8.8.8");
563 factory.AddUDPConnectFailure("2001:4860:4860::8888");
564
565 net::AddressList dns_result;
566
567 factory.AddUDPConnectFailure("10.0.0.0");
568 factory.AddUDPConnectFailure("172.16.0.0");
569 factory.AddUDPConnectFailure("192.168.0.0");
570 factory.AddUDPConnectFailure("FC00::");
571
572 auto result = PacMyIpAddressExForTest(&factory, dns_result);
573 EXPECT_EQ(0u, result.size());
574 }
575
576 // Tests myIpAddressEx() when there are only IPv6 link-local address.
TEST(PacLibraryTest,PacMyIpAddressExAllFailHasLinkLocal)577 TEST(PacLibraryTest, PacMyIpAddressExAllFailHasLinkLocal) {
578 MockSocketFactory factory;
579 factory.AddUDPConnectFailure("8.8.8.8");
580 factory.AddUDPConnectFailure("2001:4860:4860::8888");
581
582 net::AddressList dns_result =
583 CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "fe80::8899"});
584
585 factory.AddUDPConnectFailure("10.0.0.0");
586 factory.AddUDPConnectFailure("172.16.0.0");
587 factory.AddUDPConnectFailure("192.168.0.0");
588 factory.AddUDPConnectSuccess("FC00::", "fe80::1");
589
590 auto result = PacMyIpAddressExForTest(&factory, dns_result);
591 // There were four link-local addresses found, but only the first one is
592 // returned.
593 ASSERT_EQ(1u, result.size());
594 EXPECT_EQ("fe81::8881", result.front().ToString());
595 }
596
597 // Tests myIpAddressEx() when there are only link-local addresses. The IPv4
598 // link-local address is favored.
TEST(PacLibraryTest,PacMyIpAddressExAllFailHasLinkLocalFavorIPv4)599 TEST(PacLibraryTest, PacMyIpAddressExAllFailHasLinkLocalFavorIPv4) {
600 MockSocketFactory factory;
601 factory.AddUDPConnectFailure("8.8.8.8");
602 factory.AddUDPConnectFailure("2001:4860:4860::8888");
603
604 net::AddressList dns_result =
605 CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "169.254.89.133"});
606
607 factory.AddUDPConnectFailure("10.0.0.0");
608 factory.AddUDPConnectFailure("172.16.0.0");
609 factory.AddUDPConnectFailure("192.168.0.0");
610 factory.AddUDPConnectFailure("FC00::");
611
612 auto result = PacMyIpAddressExForTest(&factory, dns_result);
613 ASSERT_EQ(1u, result.size());
614 EXPECT_EQ("169.254.89.133", result.front().ToString());
615 }
616
617 // Tests myIpAddressEx() when there are no routes, and
618 // getaddrinfo(gethostname()) only returns loopback.
TEST(PacLibraryTest,PacMyIpAddressExAllFailOrLoopback)619 TEST(PacLibraryTest, PacMyIpAddressExAllFailOrLoopback) {
620 MockSocketFactory factory;
621 factory.AddUDPConnectFailure("8.8.8.8");
622 factory.AddUDPConnectFailure("2001:4860:4860::8888");
623
624 net::AddressList dns_result = CreateAddressList({"127.0.0.1", "::1"});
625
626 factory.AddUDPConnectFailure("10.0.0.0");
627 factory.AddUDPConnectFailure("172.16.0.0");
628 factory.AddUDPConnectFailure("192.168.0.0");
629 factory.AddUDPConnectFailure("FC00::");
630
631 auto result = PacMyIpAddressExForTest(&factory, dns_result);
632 EXPECT_EQ(0u, result.size());
633 }
634
635 } // namespace
636 } // namespace network
637