1 // Copyright 2017 The Chromium Authors
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/nqe/network_quality_estimator_util.h"
6
7 #include <memory>
8 #include <optional>
9
10 #include "base/test/scoped_feature_list.h"
11 #include "base/test/task_environment.h"
12 #include "build/build_config.h"
13 #include "net/base/features.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/network_isolation_key.h"
17 #include "net/base/schemeful_site.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/dns/context_host_resolver.h"
20 #include "net/dns/host_resolver.h"
21 #include "net/dns/mock_host_resolver.h"
22 #include "net/log/net_log.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "url/gurl.h"
25
26 namespace net::nqe::internal {
27
28 namespace {
29
30 #if BUILDFLAG(IS_IOS)
31 // Flaky on iOS: crbug.com/672917.
32 #define MAYBE_ReservedHost DISABLED_ReservedHost
33 #else
34 #define MAYBE_ReservedHost ReservedHost
35 #endif
36 // Verify that the cached network qualities from the prefs are not used if the
37 // reading of the network quality prefs is not enabled..
TEST(NetworkQualityEstimatorUtilTest,MAYBE_ReservedHost)38 TEST(NetworkQualityEstimatorUtilTest, MAYBE_ReservedHost) {
39 base::test::TaskEnvironment task_environment;
40
41 MockCachingHostResolver mock_host_resolver;
42
43 // example1.com resolves to a private IP address.
44 mock_host_resolver.rules()->AddRule("example1.com", "127.0.0.3");
45
46 // example2.com resolves to a public IP address.
47 mock_host_resolver.rules()->AddRule("example2.com", "27.0.0.3");
48
49 EXPECT_EQ(0u, mock_host_resolver.num_resolve());
50
51 // Load hostnames into HostResolver cache.
52 int rv = mock_host_resolver.LoadIntoCache(
53 url::SchemeHostPort("https", "example1.com", 443),
54 NetworkAnonymizationKey(), std::nullopt);
55 EXPECT_EQ(OK, rv);
56 rv = mock_host_resolver.LoadIntoCache(
57 url::SchemeHostPort("https", "example2.com", 443),
58 NetworkAnonymizationKey(), std::nullopt);
59 EXPECT_EQ(OK, rv);
60
61 EXPECT_EQ(2u, mock_host_resolver.num_non_local_resolves());
62
63 EXPECT_FALSE(IsPrivateHostForTesting(
64 &mock_host_resolver,
65 url::SchemeHostPort("http", "[2607:f8b0:4006:819::200e]", 80),
66 NetworkAnonymizationKey()));
67
68 EXPECT_TRUE(IsPrivateHostForTesting(
69 &mock_host_resolver, url::SchemeHostPort("https", "192.168.0.1", 443),
70 NetworkAnonymizationKey()));
71
72 EXPECT_FALSE(IsPrivateHostForTesting(
73 &mock_host_resolver, url::SchemeHostPort("https", "92.168.0.1", 443),
74 NetworkAnonymizationKey()));
75
76 EXPECT_TRUE(IsPrivateHostForTesting(
77 &mock_host_resolver, url::SchemeHostPort("https", "example1.com", 443),
78 NetworkAnonymizationKey()));
79
80 EXPECT_FALSE(IsPrivateHostForTesting(
81 &mock_host_resolver, url::SchemeHostPort("https", "example2.com", 443),
82 NetworkAnonymizationKey()));
83
84 // IsPrivateHostForTesting() should have queried only the resolver's cache.
85 EXPECT_EQ(2u, mock_host_resolver.num_non_local_resolves());
86 }
87
88 #if BUILDFLAG(IS_IOS)
89 // Flaky on iOS: crbug.com/672917.
90 #define MAYBE_ReservedHostUncached DISABLED_ReservedHostUncached
91 #else
92 #define MAYBE_ReservedHostUncached ReservedHostUncached
93 #endif
94 // Verify that IsPrivateHostForTesting() returns false for a hostname whose DNS
95 // resolution is not cached. Further, once the resolution is cached, verify that
96 // the cached entry is used.
TEST(NetworkQualityEstimatorUtilTest,MAYBE_ReservedHostUncached)97 TEST(NetworkQualityEstimatorUtilTest, MAYBE_ReservedHostUncached) {
98 base::test::TaskEnvironment task_environment;
99
100 MockCachingHostResolver mock_host_resolver;
101
102 auto rules = base::MakeRefCounted<net::RuleBasedHostResolverProc>(nullptr);
103
104 // Add example3.com resolution to the DNS cache.
105 mock_host_resolver.rules()->AddRule("example3.com", "127.0.0.3");
106
107 // Not in DNS host cache, so should not be marked as private.
108 EXPECT_FALSE(IsPrivateHostForTesting(
109 &mock_host_resolver, url::SchemeHostPort("https", "example3.com", 443),
110 NetworkAnonymizationKey()));
111 EXPECT_EQ(0u, mock_host_resolver.num_non_local_resolves());
112
113 int rv = mock_host_resolver.LoadIntoCache(
114 url::SchemeHostPort("https", "example3.com", 443),
115 NetworkAnonymizationKey(), std::nullopt);
116 EXPECT_EQ(OK, rv);
117 EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
118
119 EXPECT_TRUE(IsPrivateHostForTesting(
120 &mock_host_resolver, url::SchemeHostPort("https", "example3.com", 443),
121 NetworkAnonymizationKey()));
122
123 // IsPrivateHostForTesting() should have queried only the resolver's cache.
124 EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
125 }
126
127 #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
128 // Flaky on iOS: crbug.com/672917.
129 // Flaky on Android: crbug.com/1223950
130 #define MAYBE_ReservedHostUncachedWithNetworkIsolationKey \
131 DISABLED_ReservedHostUncachedWithNetworkIsolationKey
132 #else
133 #define MAYBE_ReservedHostUncachedWithNetworkIsolationKey \
134 ReservedHostUncachedWithNetworkIsolationKey
135 #endif
136 // Make sure that IsPrivateHostForTesting() uses the NetworkAnonymizationKey
137 // provided to it.
TEST(NetworkQualityEstimatorUtilTest,MAYBE_ReservedHostUncachedWithNetworkIsolationKey)138 TEST(NetworkQualityEstimatorUtilTest,
139 MAYBE_ReservedHostUncachedWithNetworkIsolationKey) {
140 const SchemefulSite kSite(GURL("https://foo.test/"));
141 const auto kNetworkAnonymizationKey =
142 NetworkAnonymizationKey::CreateSameSite(kSite);
143
144 base::test::ScopedFeatureList feature_list;
145 feature_list.InitAndEnableFeature(
146 features::kSplitHostCacheByNetworkIsolationKey);
147
148 base::test::TaskEnvironment task_environment;
149
150 MockCachingHostResolver mock_host_resolver;
151
152 // Add example3.com resolution to the DNS cache.
153 mock_host_resolver.rules()->AddRule("example3.com", "127.0.0.3");
154
155 // Not in DNS host cache, so should not be marked as private.
156 EXPECT_FALSE(IsPrivateHostForTesting(
157 &mock_host_resolver, url::SchemeHostPort("https", "example3.com", 443),
158 kNetworkAnonymizationKey));
159 EXPECT_EQ(0u, mock_host_resolver.num_non_local_resolves());
160
161 int rv = mock_host_resolver.LoadIntoCache(
162 url::SchemeHostPort("https", "example3.com", 443),
163 kNetworkAnonymizationKey, std::nullopt);
164 EXPECT_EQ(OK, rv);
165 EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
166
167 EXPECT_TRUE(IsPrivateHostForTesting(
168 &mock_host_resolver, url::SchemeHostPort("https", "example3.com", 443),
169 kNetworkAnonymizationKey));
170
171 // IsPrivateHostForTesting() should have queried only the resolver's cache.
172 EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
173
174 // IsPrivateHostForTesting should return false when using a different
175 // NetworkAnonymizationKey (in this case, any empty one).
176 EXPECT_FALSE(IsPrivateHostForTesting(
177 &mock_host_resolver, url::SchemeHostPort("https", "example3.com", 443),
178 NetworkAnonymizationKey()));
179 }
180
181 #if BUILDFLAG(IS_IOS)
182 // Flaky on iOS: crbug.com/672917.
183 #define MAYBE_Localhost DISABLED_Localhost
184 #else
185 #define MAYBE_Localhost Localhost
186 #endif
187
188 // Verify that IsPrivateHostForTesting() returns correct results for local
189 // hosts.
TEST(NetworkQualityEstimatorUtilTest,MAYBE_Localhost)190 TEST(NetworkQualityEstimatorUtilTest, MAYBE_Localhost) {
191 base::test::TaskEnvironment task_environment;
192
193 // Use actual HostResolver since MockCachingHostResolver does not determine
194 // the correct answer for localhosts.
195 std::unique_ptr<ContextHostResolver> resolver =
196 HostResolver::CreateStandaloneContextResolver(NetLog::Get());
197
198 auto rules = base::MakeRefCounted<net::RuleBasedHostResolverProc>(nullptr);
199
200 EXPECT_TRUE(IsPrivateHostForTesting(
201 resolver.get(), url::SchemeHostPort("https", "localhost", 443),
202 NetworkAnonymizationKey()));
203 EXPECT_TRUE(IsPrivateHostForTesting(
204 resolver.get(), url::SchemeHostPort("http", "127.0.0.1", 80),
205 NetworkAnonymizationKey()));
206 EXPECT_TRUE(IsPrivateHostForTesting(
207 resolver.get(), url::SchemeHostPort("http", "0.0.0.0", 80),
208 NetworkAnonymizationKey()));
209 EXPECT_TRUE(IsPrivateHostForTesting(resolver.get(),
210 url::SchemeHostPort("http", "[::1]", 80),
211 NetworkAnonymizationKey()));
212 EXPECT_FALSE(IsPrivateHostForTesting(
213 resolver.get(), url::SchemeHostPort("http", "google.com", 80),
214 NetworkAnonymizationKey()));
215
216 // Legacy localhost names.
217 EXPECT_FALSE(IsPrivateHostForTesting(
218 resolver.get(), url::SchemeHostPort("https", "localhost6", 443),
219 NetworkAnonymizationKey()));
220 EXPECT_FALSE(IsPrivateHostForTesting(
221 resolver.get(),
222 url::SchemeHostPort("https", "localhost6.localdomain6", 443),
223 NetworkAnonymizationKey()));
224 }
225
226 } // namespace
227
228 } // namespace net::nqe::internal
229