| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/proxy_resolution/pac_library.h" |
| |
| #include "net/base/address_list.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/network_interfaces.h" |
| #include "net/log/net_log_with_source.h" |
| #include "net/socket/client_socket_factory.h" |
| #include "net/socket/client_socket_handle.h" |
| #include "net/socket/datagram_client_socket.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| namespace { |
| |
| // Helper for verifying whether the address list returned by myIpAddress() / |
| // myIpAddressEx() looks correct. |
| void VerifyActualMyIpAddresses(const IPAddressList& test_list) { |
| // Enumerate all of the IP addresses for the system (skipping loopback and |
| // link-local ones). This is used as a reference implementation to check |
| // whether |test_list| (which was obtained using a different strategy) looks |
| // correct. |
| std::set<IPAddress> candidates; |
| NetworkInterfaceList networks; |
| GetNetworkList(&networks, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); |
| for (const auto& network : networks) { |
| if (network.address.IsLinkLocal() || network.address.IsLoopback()) |
| continue; |
| candidates.insert(network.address); |
| } |
| |
| // Ordinarily the machine running this test will have an IP address. However |
| // for some bot configurations (notably Android) that may not be the case. |
| EXPECT_EQ(candidates.empty(), test_list.empty()); |
| |
| // |test_list| should be a subset of |candidates|. |
| for (const auto& ip : test_list) |
| EXPECT_EQ(1u, candidates.count(ip)); |
| } |
| |
| // Tests for PacMyIpAddress() and PacMyIpAddressEx(). |
| TEST(PacLibraryTest, ActualPacMyIpAddress) { |
| auto my_ip_addresses = PacMyIpAddress(); |
| |
| VerifyActualMyIpAddresses(my_ip_addresses); |
| } |
| |
| TEST(PacLibraryTest, ActualPacMyIpAddressEx) { |
| VerifyActualMyIpAddresses(PacMyIpAddressEx()); |
| } |
| |
| IPAddress CreateIPAddress(base::StringPiece literal) { |
| IPAddress result; |
| if (!result.AssignFromIPLiteral(literal)) { |
| ADD_FAILURE() << "Failed parsing IP: " << literal; |
| return IPAddress(); |
| } |
| return result; |
| } |
| |
| AddressList CreateAddressList( |
| const std::vector<base::StringPiece>& ip_literals) { |
| AddressList result; |
| for (const auto& ip : ip_literals) |
| result.push_back(IPEndPoint(CreateIPAddress(ip), 8080)); |
| return result; |
| } |
| |
| class MockUDPSocket : public DatagramClientSocket { |
| public: |
| MockUDPSocket(const IPAddress& peer_ip, |
| const IPAddress& local_ip, |
| Error connect_error) |
| : peer_ip_(peer_ip), local_ip_(local_ip), connect_error_(connect_error) {} |
| |
| ~MockUDPSocket() override = default; |
| |
| // Socket implementation. |
| int Read(IOBuffer* buf, |
| int buf_len, |
| CompletionOnceCallback callback) override { |
| ADD_FAILURE() << "Called Read()"; |
| return ERR_UNEXPECTED; |
| } |
| int Write(IOBuffer* buf, |
| int buf_len, |
| CompletionOnceCallback callback, |
| const NetworkTrafficAnnotationTag& traffic_annotation) override { |
| ADD_FAILURE() << "Called Read()"; |
| return ERR_UNEXPECTED; |
| } |
| int SetReceiveBufferSize(int32_t size) override { |
| ADD_FAILURE() << "Called SetReceiveBufferSize()"; |
| return ERR_UNEXPECTED; |
| } |
| int SetSendBufferSize(int32_t size) override { |
| ADD_FAILURE() << "Called SetSendBufferSize()"; |
| return ERR_UNEXPECTED; |
| } |
| |
| // DatagramSocket implementation. |
| void Close() override { ADD_FAILURE() << "Called Close()"; } |
| int GetPeerAddress(IPEndPoint* address) const override { |
| ADD_FAILURE() << "Called GetPeerAddress()"; |
| return ERR_UNEXPECTED; |
| } |
| int GetLocalAddress(IPEndPoint* address) const override { |
| if (connect_error_ != OK) |
| return connect_error_; |
| |
| *address = IPEndPoint(local_ip_, 8080); |
| return OK; |
| } |
| void UseNonBlockingIO() override { |
| ADD_FAILURE() << "Called UseNonBlockingIO()"; |
| } |
| int SetDoNotFragment() override { |
| ADD_FAILURE() << "Called SetDoNotFragment()"; |
| return ERR_UNEXPECTED; |
| } |
| void SetMsgConfirm(bool confirm) override { |
| ADD_FAILURE() << "Called SetMsgConfirm()"; |
| } |
| const NetLogWithSource& NetLog() const override { |
| ADD_FAILURE() << "Called NetLog()"; |
| return net_log_; |
| } |
| |
| // DatagramClientSocket implementation. |
| int Connect(const IPEndPoint& address) override { |
| EXPECT_EQ(peer_ip_.ToString(), address.address().ToString()); |
| return connect_error_; |
| } |
| int ConnectUsingNetwork(NetworkChangeNotifier::NetworkHandle network, |
| const IPEndPoint& address) override { |
| ADD_FAILURE() << "Called ConnectUsingNetwork()"; |
| return ERR_UNEXPECTED; |
| } |
| int ConnectUsingDefaultNetwork(const IPEndPoint& address) override { |
| ADD_FAILURE() << "Called ConnectUsingDefaultNetwork()"; |
| return ERR_UNEXPECTED; |
| } |
| NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override { |
| ADD_FAILURE() << "Called GetBoundNetwork()"; |
| return network_; |
| } |
| void ApplySocketTag(const SocketTag& tag) override { |
| ADD_FAILURE() << "Called ApplySocketTag()"; |
| } |
| int WriteAsync( |
| DatagramBuffers buffers, |
| CompletionOnceCallback callback, |
| const NetworkTrafficAnnotationTag& traffic_annotation) override { |
| ADD_FAILURE() << "Called WriteAsync()"; |
| return ERR_UNEXPECTED; |
| } |
| int WriteAsync( |
| const char* buffer, |
| size_t buf_len, |
| CompletionOnceCallback callback, |
| const NetworkTrafficAnnotationTag& traffic_annotation) override { |
| ADD_FAILURE() << "Called WriteAsync()"; |
| return ERR_UNEXPECTED; |
| } |
| DatagramBuffers GetUnwrittenBuffers() override { |
| ADD_FAILURE() << "Called GetUnwrittenBuffers()"; |
| return DatagramBuffers(); |
| } |
| void SetWriteAsyncEnabled(bool enabled) override { |
| ADD_FAILURE() << "Called SetWriteAsyncEnabled()"; |
| } |
| void SetMaxPacketSize(size_t max_packet_size) override { |
| ADD_FAILURE() << "Called SetWriteAsyncEnabled()"; |
| } |
| bool WriteAsyncEnabled() override { |
| ADD_FAILURE() << "Called WriteAsyncEnabled()"; |
| return false; |
| } |
| void SetWriteMultiCoreEnabled(bool enabled) override { |
| ADD_FAILURE() << "Called SetWriteMultiCoreEnabled()"; |
| } |
| void SetSendmmsgEnabled(bool enabled) override { |
| ADD_FAILURE() << "Called SetSendmmsgEnabled()"; |
| } |
| void SetWriteBatchingActive(bool active) override { |
| ADD_FAILURE() << "Called SetWriteBatchingActive()"; |
| } |
| int SetMulticastInterface(uint32_t interface_index) override { |
| ADD_FAILURE() << "Called SetMulticastInterface()"; |
| return ERR_UNEXPECTED; |
| } |
| |
| private: |
| NetLogWithSource net_log_; |
| NetworkChangeNotifier::NetworkHandle network_; |
| |
| IPAddress peer_ip_; |
| IPAddress local_ip_; |
| Error connect_error_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockUDPSocket); |
| }; |
| |
| class MockSocketFactory : public ClientSocketFactory { |
| public: |
| MockSocketFactory() = default; |
| |
| void AddUDPConnectSuccess(base::StringPiece peer_ip_literal, |
| base::StringPiece local_ip_literal) { |
| auto peer_ip = CreateIPAddress(peer_ip_literal); |
| auto local_ip = CreateIPAddress(local_ip_literal); |
| |
| // The address family of local and peer IP must match. |
| ASSERT_EQ(peer_ip.size(), local_ip.size()); |
| |
| udp_sockets_.push_back(std::make_unique<MockUDPSocket>( |
| peer_ip, local_ip, OK)); |
| } |
| |
| void AddUDPConnectFailure(base::StringPiece peer_ip) { |
| udp_sockets_.push_back(std::make_unique<MockUDPSocket>( |
| CreateIPAddress(peer_ip), IPAddress(), ERR_ADDRESS_UNREACHABLE)); |
| } |
| |
| ~MockSocketFactory() override { |
| EXPECT_EQ(0u, udp_sockets_.size()) |
| << "Not all of the mock sockets were consumed."; |
| } |
| |
| // ClientSocketFactory |
| std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket( |
| DatagramSocket::BindType bind_type, |
| NetLog* net_log, |
| const NetLogSource& source) override { |
| if (udp_sockets_.empty()) { |
| ADD_FAILURE() << "Not enough mock UDP sockets"; |
| return nullptr; |
| } |
| |
| auto result = std::move(udp_sockets_.front()); |
| udp_sockets_.erase(udp_sockets_.begin()); |
| return result; |
| } |
| std::unique_ptr<TransportClientSocket> CreateTransportClientSocket( |
| const AddressList& addresses, |
| std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
| NetLog* net_log, |
| const NetLogSource& source) override { |
| ADD_FAILURE() << "Called CreateTransportClientSocket()"; |
| return nullptr; |
| } |
| std::unique_ptr<SSLClientSocket> CreateSSLClientSocket( |
| std::unique_ptr<ClientSocketHandle> transport_socket, |
| const HostPortPair& host_and_port, |
| const SSLConfig& ssl_config, |
| const SSLClientSocketContext& context) override { |
| ADD_FAILURE() << "Called CreateSSLClientSocket()"; |
| return nullptr; |
| } |
| std::unique_ptr<SSLClientSocket> CreateSSLClientSocket( |
| std::unique_ptr<StreamSocket> nested_socket, |
| const HostPortPair& host_and_port, |
| const SSLConfig& ssl_config, |
| const SSLClientSocketContext& context) override { |
| ADD_FAILURE() << "Called CreateSSLClientSocket()"; |
| return nullptr; |
| } |
| std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket( |
| std::unique_ptr<ClientSocketHandle> transport_socket, |
| const std::string& user_agent, |
| const HostPortPair& endpoint, |
| const ProxyServer& proxy_server, |
| HttpAuthController* http_auth_controller, |
| bool tunnel, |
| bool using_spdy, |
| NextProto negotiated_protocol, |
| ProxyDelegate* proxy_delegate, |
| bool is_https_proxy, |
| const NetworkTrafficAnnotationTag& traffic_annotation) override { |
| ADD_FAILURE() << "Called CreateProxyClientSocket()"; |
| return nullptr; |
| } |
| std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket( |
| std::unique_ptr<StreamSocket> stream_socket, |
| const std::string& user_agent, |
| const HostPortPair& endpoint, |
| const ProxyServer& proxy_server, |
| HttpAuthController* http_auth_controller, |
| bool tunnel, |
| bool using_spdy, |
| NextProto negotiated_protocol, |
| ProxyDelegate* proxy_delegate, |
| bool is_https_proxy, |
| const NetworkTrafficAnnotationTag& traffic_annotation) override { |
| ADD_FAILURE() << "Called CreateProxyClientSocket()"; |
| return nullptr; |
| } |
| |
| private: |
| std::vector<std::unique_ptr<MockUDPSocket>> udp_sockets_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockSocketFactory); |
| }; |
| |
| // Tests myIpAddress() when there is a route to 8.8.8.8. |
| TEST(PacLibraryTest, PacMyIpAddress8888) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectSuccess("8.8.8.8", "192.168.1.1"); |
| |
| auto result = PacMyIpAddressForTest(&factory, {}); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("192.168.1.1", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there is no route to 8.8.8.8, but there is one to |
| // 2001:4860:4860::8888. |
| TEST(PacLibraryTest, PacMyIpAddress2001) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::beef"); |
| |
| AddressList dns_result; |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("2001::beef", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there is no route to 8.8.8.8, no route to |
| // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds results. Most |
| // of those results are skipped over, and the IPv4 one is favored. |
| TEST(PacLibraryTest, PacMyIpAddressHostname) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = CreateAddressList({ |
| "169.254.13.16", "127.0.0.1", "::1", "fe89::beef", "2001::f001", |
| "178.1.99.3", "192.168.1.3", |
| }); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("178.1.99.3", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there is no route to 8.8.8.8, no route to |
| // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds multiple IPv6 |
| // results. |
| TEST(PacLibraryTest, PacMyIpAddressHostnameAllIPv6) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = |
| CreateAddressList({"::1", "2001::f001", "2001::f00d", "169.254.0.6"}); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("2001::f001", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there is no route to 8.8.8.8, no route to |
| // 2001:4860:4860::8888, no acceptable result in getaddrinfo(gethostname()), |
| // however there is a route for private address. |
| TEST(PacLibraryTest, PacMyIpAddressPrivateIPv4) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = CreateAddressList({ |
| "169.254.13.16", "127.0.0.1", "::1", "fe89::beef", |
| }); |
| |
| factory.AddUDPConnectSuccess("10.0.0.0", "127.0.0.1"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectSuccess("192.168.0.0", "63.31.9.8"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("63.31.9.8", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there is no route to 8.8.8.8, no route to |
| // 2001:4860:4860::8888, no acceptable result in getaddrinfo(gethostname()), |
| // however there is a route for private address. |
| TEST(PacLibraryTest, PacMyIpAddressPrivateIPv6) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result; |
| |
| factory.AddUDPConnectSuccess("10.0.0.0", "127.0.0.1"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectSuccess("FC00::", "2001::7777"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("2001::7777", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there are no routes, and getaddrinfo(gethostname()) |
| // fails. |
| TEST(PacLibraryTest, PacMyIpAddressAllFail) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result; |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| EXPECT_EQ(0u, result.size()); |
| } |
| |
| // Tests myIpAddress() when there are no routes, and |
| // getaddrinfo(gethostname()) only returns loopback. |
| TEST(PacLibraryTest, PacMyIpAddressAllFailOrLoopback) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = CreateAddressList({"127.0.0.1", "::1"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| EXPECT_EQ(0u, result.size()); |
| } |
| |
| // Tests myIpAddress() when there is only an IPv6 link-local address. |
| TEST(PacLibraryTest, PacMyIpAddressAllFailHasLinkLocal) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = |
| CreateAddressList({"127.0.0.1", "::1", "fe81::8881"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("fe81::8881", result.front().ToString()); |
| } |
| |
| // Tests myIpAddress() when there are only link-local addresses. The IPv4 |
| // link-local address is favored. |
| TEST(PacLibraryTest, PacMyIpAddressAllFailHasLinkLocalFavorIPv4) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = |
| CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "169.254.89.133"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("169.254.89.133", result.front().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there is a route to 8.8.8.8 but not one to |
| // 2001:4860:4860::8888 |
| TEST(PacLibraryTest, PacMyIpAddressEx8888) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectSuccess("8.8.8.8", "192.168.1.1"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, {}); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("192.168.1.1", result.front().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there is a route to 2001:4860:4860::8888 but |
| // not 8.8.8.8. |
| TEST(PacLibraryTest, PacMyIpAddressEx2001) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::3333"); |
| |
| AddressList dns_result; |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("2001::3333", result.front().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there is a route to both 8.8.8.8 and |
| // 2001:4860:4860::8888. |
| TEST(PacLibraryTest, PacMyIpAddressEx8888And2001) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectSuccess("8.8.8.8", "192.168.17.8"); |
| factory.AddUDPConnectSuccess("2001:4860:4860::8888", "2001::8333"); |
| |
| AddressList dns_result; |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_EQ("192.168.17.8", result.front().ToString()); |
| EXPECT_EQ("2001::8333", result.back().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there is no route to 8.8.8.8, no route to |
| // 2001:4860:4860::8888, however getaddrinfo(gethostname()) finds results. Some |
| // of those results are skipped due to being link-local and loopback. |
| TEST(PacLibraryTest, PacMyIpAddressExHostname) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = CreateAddressList({ |
| "169.254.13.16", "::1", "fe89::beef", "2001::bebe", "178.1.99.3", |
| "127.0.0.1", "192.168.1.3", |
| }); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| ASSERT_EQ(3u, result.size()); |
| EXPECT_EQ("2001::bebe", result[0].ToString()); |
| EXPECT_EQ("178.1.99.3", result[1].ToString()); |
| EXPECT_EQ("192.168.1.3", result[2].ToString()); |
| } |
| |
| // Tests myIpAddressEx() when routes are found for private IP space. |
| TEST(PacLibraryTest, PacMyIpAddressExPrivateDuplicates) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result; |
| |
| factory.AddUDPConnectSuccess("10.0.0.0", "192.168.3.3"); |
| factory.AddUDPConnectSuccess("172.16.0.0", "192.168.3.4"); |
| factory.AddUDPConnectSuccess("192.168.0.0", "192.168.3.3"); |
| factory.AddUDPConnectSuccess("FC00::", "2001::beef"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| |
| // Note that 192.168.3.3. was probed twice, but only added once to the final |
| // result. |
| ASSERT_EQ(3u, result.size()); |
| EXPECT_EQ("192.168.3.3", result[0].ToString()); |
| EXPECT_EQ("192.168.3.4", result[1].ToString()); |
| EXPECT_EQ("2001::beef", result[2].ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there are no routes, and |
| // getaddrinfo(gethostname()) fails. |
| TEST(PacLibraryTest, PacMyIpAddressExAllFail) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result; |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| EXPECT_EQ(0u, result.size()); |
| } |
| |
| // Tests myIpAddressEx() when there are only IPv6 link-local address. |
| TEST(PacLibraryTest, PacMyIpAddressExAllFailHasLinkLocal) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = |
| CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "fe80::8899"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectSuccess("FC00::", "fe80::1"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| // There were four link-local addresses found, but only the first one is |
| // returned. |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("fe81::8881", result.front().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there are only link-local addresses. The IPv4 |
| // link-local address is favored. |
| TEST(PacLibraryTest, PacMyIpAddressExAllFailHasLinkLocalFavorIPv4) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = |
| CreateAddressList({"127.0.0.1", "::1", "fe81::8881", "169.254.89.133"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ("169.254.89.133", result.front().ToString()); |
| } |
| |
| // Tests myIpAddressEx() when there are no routes, and |
| // getaddrinfo(gethostname()) only returns loopback. |
| TEST(PacLibraryTest, PacMyIpAddressExAllFailOrLoopback) { |
| MockSocketFactory factory; |
| factory.AddUDPConnectFailure("8.8.8.8"); |
| factory.AddUDPConnectFailure("2001:4860:4860::8888"); |
| |
| AddressList dns_result = CreateAddressList({"127.0.0.1", "::1"}); |
| |
| factory.AddUDPConnectFailure("10.0.0.0"); |
| factory.AddUDPConnectFailure("172.16.0.0"); |
| factory.AddUDPConnectFailure("192.168.0.0"); |
| factory.AddUDPConnectFailure("FC00::"); |
| |
| auto result = PacMyIpAddressExForTest(&factory, dns_result); |
| EXPECT_EQ(0u, result.size()); |
| } |
| |
| } // namespace |
| } // namespace net |