• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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/dns/dns_task_results_manager.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <optional>
10 #include <string_view>
11 
12 #include "base/check.h"
13 #include "base/functional/callback_forward.h"
14 #include "base/test/task_environment.h"
15 #include "base/time/time.h"
16 #include "net/base/connection_endpoint_metadata.h"
17 #include "net/base/net_errors.h"
18 #include "net/dns/host_resolver_internal_result.h"
19 #include "net/dns/host_resolver_results_test_util.h"
20 #include "net/dns/https_record_rdata.h"
21 #include "net/test/test_with_task_environment.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "url/gurl.h"
25 #include "url/scheme_host_port.h"
26 
27 using ::testing::ElementsAre;
28 using ::testing::IsEmpty;
29 using ::testing::UnorderedElementsAre;
30 
31 namespace net {
32 
33 namespace {
34 
35 class FakeDelegate : public DnsTaskResultsManager::Delegate {
36  public:
37   FakeDelegate() = default;
38   ~FakeDelegate() override = default;
39 
40  private:
OnServiceEndpointsUpdated()41   void OnServiceEndpointsUpdated() override {
42     // Do nothing for now.
43   }
44 };
45 
MakeIPEndPoint(std::string_view ip_literal,uint16_t port=0)46 IPEndPoint MakeIPEndPoint(std::string_view ip_literal, uint16_t port = 0) {
47   std::optional<IPAddress> ip = IPAddress::FromIPLiteral(std::move(ip_literal));
48   return IPEndPoint(*ip, port);
49 }
50 
CreateDataResult(std::string_view domain_name,std::vector<IPEndPoint> ip_endpoints,DnsQueryType query_type)51 std::unique_ptr<HostResolverInternalDataResult> CreateDataResult(
52     std::string_view domain_name,
53     std::vector<IPEndPoint> ip_endpoints,
54     DnsQueryType query_type) {
55   return std::make_unique<HostResolverInternalDataResult>(
56       std::string(domain_name), query_type, /*expiration=*/base::TimeTicks(),
57       /*timed_expiration=*/base::Time(),
58       HostResolverInternalResult::Source::kDns, std::move(ip_endpoints),
59       std::vector<std::string>(), std::vector<HostPortPair>());
60 }
61 
CreateNoData(std::string_view domain_name,DnsQueryType query_type)62 std::unique_ptr<HostResolverInternalErrorResult> CreateNoData(
63     std::string_view domain_name,
64     DnsQueryType query_type) {
65   return std::make_unique<HostResolverInternalErrorResult>(
66       std::string(domain_name), query_type, /*expiration=*/base::TimeTicks(),
67       /*timed_expiration=*/base::Time(),
68       HostResolverInternalResult::Source::kDns, ERR_NAME_NOT_RESOLVED);
69 }
70 
CreateMetadata(std::string_view domain_name,std::multimap<HttpsRecordPriority,ConnectionEndpointMetadata> metadatas)71 std::unique_ptr<HostResolverInternalMetadataResult> CreateMetadata(
72     std::string_view domain_name,
73     std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas) {
74   return std::make_unique<HostResolverInternalMetadataResult>(
75       std::string(domain_name), DnsQueryType::HTTPS,
76       /*expiration=*/base::TimeTicks(), /*timed_expiration=*/base::Time(),
77       HostResolverInternalResult::Source::kDns, std::move(metadatas));
78 }
79 
CreateAlias(std::string_view domain_name,DnsQueryType query_type,std::string_view alias_target)80 std::unique_ptr<HostResolverInternalAliasResult> CreateAlias(
81     std::string_view domain_name,
82     DnsQueryType query_type,
83     std::string_view alias_target) {
84   return std::make_unique<HostResolverInternalAliasResult>(
85       std::string(domain_name), query_type, /*expiration=*/base::TimeTicks(),
86       /*timed_expiration=*/base::Time(),
87       HostResolverInternalResult::Source::kDns, std::string(alias_target));
88 }
89 
WithPort(const std::vector<IPEndPoint> & endpoints,uint16_t port)90 std::vector<IPEndPoint> WithPort(const std::vector<IPEndPoint>& endpoints,
91                                  uint16_t port) {
92   std::vector<IPEndPoint> out_endpoints;
93   for (const auto& endpoint : endpoints) {
94     out_endpoints.emplace_back(endpoint.address(), port);
95   }
96   return out_endpoints;
97 }
98 
99 static constexpr std::string_view kHostName = "www.example.com";
100 static constexpr std::string_view kAliasTarget1 = "alias1.example.net";
101 static constexpr std::string_view kAliasTarget2 = "alias2.example.net";
102 
103 static const ConnectionEndpointMetadata kMetadata1(
104     /*supported_protocol_alpns=*/{"h3"},
105     /*ech_config_list=*/{},
106     std::string(kHostName));
107 
108 static const ConnectionEndpointMetadata kMetadata2(
109     /*supported_protocol_alpns=*/{"h2", "http/1.1"},
110     /*ech_config_list=*/{},
111     std::string(kHostName));
112 
113 static const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
114     kMetadatas{{1, kMetadata1}, {2, kMetadata2}};
115 
116 // A helper class to create a DnsTaskResultsManager.
117 class ManagerFactory {
118  public:
ManagerFactory(DnsTaskResultsManager::Delegate * delegate)119   explicit ManagerFactory(DnsTaskResultsManager::Delegate* delegate)
120       : delegate_(delegate),
121         host_(
122             HostResolver::Host(url::SchemeHostPort("https", kHostName, 443))) {}
123 
Create()124   std::unique_ptr<DnsTaskResultsManager> Create() {
125     return std::make_unique<DnsTaskResultsManager>(
126         delegate_, host_, query_types_, NetLogWithSource());
127   }
128 
query_types(DnsQueryTypeSet query_types)129   ManagerFactory& query_types(DnsQueryTypeSet query_types) {
130     query_types_ = query_types;
131     return *this;
132   }
133 
134  private:
135   raw_ptr<DnsTaskResultsManager::Delegate> delegate_;
136   HostResolver::Host host_;
137   DnsQueryTypeSet query_types_ = {DnsQueryType::A, DnsQueryType::AAAA,
138                                   DnsQueryType::HTTPS};
139 };
140 
141 }  // namespace
142 
143 class DnsTaskResultsManagerTest : public TestWithTaskEnvironment {
144  public:
DnsTaskResultsManagerTest()145   DnsTaskResultsManagerTest()
146       : TestWithTaskEnvironment(
147             base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
148 
SetUp()149   void SetUp() override { delegate_ = std::make_unique<FakeDelegate>(); }
150 
151  protected:
factory()152   ManagerFactory factory() { return ManagerFactory(delegate_.get()); }
153 
154  private:
155   std::unique_ptr<FakeDelegate> delegate_;
156 };
157 
TEST_F(DnsTaskResultsManagerTest,IsMetadataReady)158 TEST_F(DnsTaskResultsManagerTest, IsMetadataReady) {
159   // HTTPS RR is not queried.
160   std::unique_ptr<DnsTaskResultsManager> manager =
161       factory().query_types({DnsQueryType::A, DnsQueryType::AAAA}).Create();
162   ASSERT_TRUE(manager->IsMetadataReady());
163 
164   // HTTPS RR is queried.
165   manager = factory()
166                 .query_types(
167                     {DnsQueryType::A, DnsQueryType::AAAA, DnsQueryType::HTTPS})
168                 .Create();
169   ASSERT_FALSE(manager->IsMetadataReady());
170 
171   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, /*results=*/{});
172   ASSERT_TRUE(manager->IsMetadataReady());
173 }
174 
TEST_F(DnsTaskResultsManagerTest,IPv6NotQueried)175 TEST_F(DnsTaskResultsManagerTest, IPv6NotQueried) {
176   std::unique_ptr<DnsTaskResultsManager> manager =
177       factory().query_types({DnsQueryType::A, DnsQueryType::HTTPS}).Create();
178 
179   std::unique_ptr<HostResolverInternalResult> result = CreateDataResult(
180       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
181   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result.get()});
182 
183   EXPECT_THAT(manager->GetCurrentEndpoints(),
184               ElementsAre(ExpectServiceEndpoint(
185                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)))));
186   EXPECT_THAT(manager->GetAliases(), UnorderedElementsAre(kHostName));
187 }
188 
TEST_F(DnsTaskResultsManagerTest,IPv4First)189 TEST_F(DnsTaskResultsManagerTest, IPv4First) {
190   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
191 
192   // A comes first. Service endpoints creation should be delayed.
193   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
194       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
195   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
196 
197   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
198 
199   // AAAA is responded. Service endpoints should be available.
200   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
201       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
202   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result2.get()});
203 
204   EXPECT_THAT(manager->GetCurrentEndpoints(),
205               ElementsAre(ExpectServiceEndpoint(
206                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
207                   ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
208 }
209 
TEST_F(DnsTaskResultsManagerTest,IPv6First)210 TEST_F(DnsTaskResultsManagerTest, IPv6First) {
211   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
212 
213   // AAAA comes first. Service endpoints should be available immediately.
214   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
215       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
216   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result1.get()});
217 
218   EXPECT_THAT(manager->GetCurrentEndpoints(),
219               ElementsAre(ExpectServiceEndpoint(
220                   IsEmpty(), ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
221 
222   // A is responded. Service endpoints should be updated.
223   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
224       kHostName, {MakeIPEndPoint("192.0.2.1"), MakeIPEndPoint("192.0.2.2")},
225       DnsQueryType::A);
226   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result2.get()});
227 
228   EXPECT_THAT(manager->GetCurrentEndpoints(),
229               ElementsAre(ExpectServiceEndpoint(
230                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443),
231                               MakeIPEndPoint("192.0.2.2", 443)),
232                   ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
233 }
234 
TEST_F(DnsTaskResultsManagerTest,IPv6Timedout)235 TEST_F(DnsTaskResultsManagerTest, IPv6Timedout) {
236   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
237 
238   // A comes first. Service endpoints creation should be delayed.
239   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
240       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
241   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
242 
243   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
244 
245   // AAAA is timed out. Service endpoints should be available after timeout.
246   FastForwardBy(DnsTaskResultsManager::kResolutionDelay +
247                 base::Milliseconds(1));
248 
249   EXPECT_THAT(manager->GetCurrentEndpoints(),
250               ElementsAre(ExpectServiceEndpoint(
251                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)))));
252 
253   // AAAA is responded after timeout. Service endpoints should be updated.
254   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
255       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
256   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result2.get()});
257 
258   EXPECT_THAT(manager->GetCurrentEndpoints(),
259               ElementsAre(ExpectServiceEndpoint(
260                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
261                   ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
262 }
263 
TEST_F(DnsTaskResultsManagerTest,IPv6NoDataBeforeIPv4)264 TEST_F(DnsTaskResultsManagerTest, IPv6NoDataBeforeIPv4) {
265   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
266 
267   // AAAA is responded with no data. Service endpoints should not be available.
268   std::unique_ptr<HostResolverInternalResult> result1 =
269       CreateNoData(kHostName, DnsQueryType::AAAA);
270   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result1.get()});
271 
272   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
273 
274   // A is responded. Service endpoints creation should happen without resolution
275   // delay.
276   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
277       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
278   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result2.get()});
279 
280   EXPECT_THAT(manager->GetCurrentEndpoints(),
281               ElementsAre(ExpectServiceEndpoint(
282                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)))));
283 }
284 
TEST_F(DnsTaskResultsManagerTest,IPv6NoDataAfterIPv4)285 TEST_F(DnsTaskResultsManagerTest, IPv6NoDataAfterIPv4) {
286   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
287 
288   // A is responded. Service endpoints creation should be delayed.
289   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
290       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
291   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
292 
293   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
294 
295   // AAAA is responded with no data before the resolution delay timer. Service
296   // endpoints should be available without waiting for the timeout.
297   std::unique_ptr<HostResolverInternalResult> result2 =
298       CreateNoData(kHostName, DnsQueryType::AAAA);
299   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result2.get()});
300 
301   EXPECT_THAT(manager->GetCurrentEndpoints(),
302               ElementsAre(ExpectServiceEndpoint(
303                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)))));
304 }
305 
TEST_F(DnsTaskResultsManagerTest,IPv6EmptyDataAfterIPv4)306 TEST_F(DnsTaskResultsManagerTest, IPv6EmptyDataAfterIPv4) {
307   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
308 
309   // A is responded. Service endpoints creation should be delayed.
310   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
311       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
312   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
313 
314   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
315 
316   // AAAA is responded with a non-cacheable result (an empty result) before the
317   // resolution delay timer. Service endpoints should be available without
318   // waiting for the timeout.
319   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {});
320 
321   EXPECT_THAT(manager->GetCurrentEndpoints(),
322               ElementsAre(ExpectServiceEndpoint(
323                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)))));
324 }
325 
TEST_F(DnsTaskResultsManagerTest,IPv4AndIPv6NoData)326 TEST_F(DnsTaskResultsManagerTest, IPv4AndIPv6NoData) {
327   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
328 
329   // AAAA is responded with no data. Service endpoints should not be available.
330   std::unique_ptr<HostResolverInternalResult> result1 =
331       CreateNoData(kHostName, DnsQueryType::AAAA);
332   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result1.get()});
333 
334   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
335 
336   // A is responded with no data. Service endpoints should not be available.
337   std::unique_ptr<HostResolverInternalResult> result2 =
338       CreateNoData(kHostName, DnsQueryType::A);
339   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result2.get()});
340 
341   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
342 }
343 
TEST_F(DnsTaskResultsManagerTest,IPv4NoDataIPv6AfterResolutionDelay)344 TEST_F(DnsTaskResultsManagerTest, IPv4NoDataIPv6AfterResolutionDelay) {
345   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
346 
347   // A comes first with no data. Service endpoints creation should be delayed
348   // and the resolution delay timer should not start.
349   std::unique_ptr<HostResolverInternalResult> result1 =
350       CreateNoData(kHostName, DnsQueryType::A);
351   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
352 
353   ASSERT_FALSE(manager->IsResolutionDelayTimerRunningForTest());
354   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
355 
356   // The resolution delay passed. Service endpoints should not be available yet.
357   FastForwardBy(DnsTaskResultsManager::kResolutionDelay +
358                 base::Milliseconds(1));
359 
360   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
361 
362   // AAAA is responded. Service endpoints should be updated.
363   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
364       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
365   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result2.get()});
366 
367   EXPECT_THAT(manager->GetCurrentEndpoints(),
368               ElementsAre(ExpectServiceEndpoint(
369                   IsEmpty(), ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
370 }
371 
TEST_F(DnsTaskResultsManagerTest,MetadataFirst)372 TEST_F(DnsTaskResultsManagerTest, MetadataFirst) {
373   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
374 
375   // HTTPS comes first. Service endpoints should not be available yet since
376   // Chrome doesn't support ipv{4,6}hint yet.
377   std::unique_ptr<HostResolverInternalResult> result1 =
378       CreateMetadata(kHostName, kMetadatas);
379   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, {result1.get()});
380 
381   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
382   ASSERT_TRUE(manager->IsMetadataReady());
383 
384   // A is responded. Service endpoints creation should be delayed.
385   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
386       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
387   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result2.get()});
388 
389   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
390 
391   // AAAA is responded. Service endpoints should be available with metadatas.
392   std::unique_ptr<HostResolverInternalResult> result3 = CreateDataResult(
393       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
394   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result3.get()});
395 
396   EXPECT_THAT(
397       manager->GetCurrentEndpoints(),
398       ElementsAre(
399           ExpectServiceEndpoint(ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
400                                 ElementsAre(MakeIPEndPoint("2001:db8::1", 443)),
401                                 kMetadata1),
402           ExpectServiceEndpoint(ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
403                                 ElementsAre(MakeIPEndPoint("2001:db8::1", 443)),
404                                 kMetadata2)));
405 }
406 
TEST_F(DnsTaskResultsManagerTest,MetadataDifferentTargetName)407 TEST_F(DnsTaskResultsManagerTest, MetadataDifferentTargetName) {
408   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
409 
410   // HTTPS is responded and the target name is different from QNAME.
411   const ConnectionEndpointMetadata kMetadataDifferentTargetName(
412       /*supported_protocol_alpns=*/{"h2", "http/1.1"},
413       /*ech_config_list=*/{},
414       /*target_name=*/"other.example.net.");
415   std::unique_ptr<HostResolverInternalResult> result1 =
416       CreateMetadata(kHostName, {{1, kMetadataDifferentTargetName}});
417   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, {result1.get()});
418 
419   ASSERT_TRUE(manager->IsMetadataReady());
420 
421   // AAAA is responded. Service endpoints should be available without metadatas
422   // since the target name is different.
423   std::unique_ptr<HostResolverInternalResult> result2 = CreateDataResult(
424       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
425   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result2.get()});
426 
427   ASSERT_TRUE(manager->IsMetadataReady());
428   EXPECT_THAT(manager->GetCurrentEndpoints(),
429               ElementsAre(ExpectServiceEndpoint(
430                   IsEmpty(), ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
431 }
432 
TEST_F(DnsTaskResultsManagerTest,MetadataAfterIPv6)433 TEST_F(DnsTaskResultsManagerTest, MetadataAfterIPv6) {
434   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
435 
436   // AAAA comes first. Service endpoints should be available without metadatas.
437   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
438       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
439   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result1.get()});
440 
441   ASSERT_FALSE(manager->IsMetadataReady());
442   EXPECT_THAT(manager->GetCurrentEndpoints(),
443               ElementsAre(ExpectServiceEndpoint(
444                   IsEmpty(), ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
445 
446   // HTTPS is responded. Metadata should be available.
447   std::unique_ptr<HostResolverInternalResult> result2 =
448       CreateMetadata(kHostName, kMetadatas);
449   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, {result2.get()});
450 
451   ASSERT_TRUE(manager->IsMetadataReady());
452   EXPECT_THAT(
453       manager->GetCurrentEndpoints(),
454       ElementsAre(
455           ExpectServiceEndpoint(IsEmpty(),
456                                 ElementsAre(MakeIPEndPoint("2001:db8::1", 443)),
457                                 kMetadata1),
458           ExpectServiceEndpoint(IsEmpty(),
459                                 ElementsAre(MakeIPEndPoint("2001:db8::1", 443)),
460                                 kMetadata2)));
461 }
462 
TEST_F(DnsTaskResultsManagerTest,IPv6TimedoutAfterMetadata)463 TEST_F(DnsTaskResultsManagerTest, IPv6TimedoutAfterMetadata) {
464   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
465 
466   // A comes first. Service endpoints creation should be delayed.
467   std::unique_ptr<HostResolverInternalResult> result1 = CreateDataResult(
468       kHostName, {MakeIPEndPoint("192.0.2.1")}, DnsQueryType::A);
469   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result1.get()});
470 
471   ASSERT_FALSE(manager->IsMetadataReady());
472   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
473 
474   // HTTPS is responded. Service endpoints should not be available because
475   // the manager is waiting for the resolution delay and Chrome doesn't support
476   // ipv6hint yet.
477   std::unique_ptr<HostResolverInternalResult> result2 =
478       CreateMetadata(kHostName, kMetadatas);
479   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, {result2.get()});
480 
481   ASSERT_TRUE(manager->IsMetadataReady());
482   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
483 
484   // AAAA is timed out. Service endpoints should be available with metadatas.
485   FastForwardBy(DnsTaskResultsManager::kResolutionDelay +
486                 base::Milliseconds(1));
487 
488   ASSERT_TRUE(manager->IsMetadataReady());
489   EXPECT_THAT(
490       manager->GetCurrentEndpoints(),
491       ElementsAre(
492           ExpectServiceEndpoint(ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
493                                 IsEmpty(), kMetadata1),
494           ExpectServiceEndpoint(ElementsAre(MakeIPEndPoint("192.0.2.1", 443)),
495                                 IsEmpty(), kMetadata2)));
496 }
497 
TEST_F(DnsTaskResultsManagerTest,IPv4NoDataIPv6TimedoutAfterMetadata)498 TEST_F(DnsTaskResultsManagerTest, IPv4NoDataIPv6TimedoutAfterMetadata) {
499   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
500 
501   // HTTPS is responded. Service endpoints should not be available because
502   // the manager is waiting for the resolution delay and Chrome doesn't support
503   // address hints yet.
504   std::unique_ptr<HostResolverInternalResult> result1 =
505       CreateMetadata(kHostName, kMetadatas);
506   manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS, {result1.get()});
507 
508   ASSERT_TRUE(manager->IsMetadataReady());
509   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
510 
511   // A is responded with no address. Service endpoints should not be available
512   // since there are no addresses.
513   std::unique_ptr<HostResolverInternalResult> result2 =
514       CreateNoData(kHostName, DnsQueryType::A);
515   manager->ProcessDnsTransactionResults(DnsQueryType::A, {result2.get()});
516 
517   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
518 
519   // AAAA is timed out. Service endpoints should not be available since there
520   // are no addresses.
521   FastForwardBy(DnsTaskResultsManager::kResolutionDelay +
522                 base::Milliseconds(1));
523 
524   ASSERT_TRUE(manager->GetCurrentEndpoints().empty());
525 }
526 
TEST_F(DnsTaskResultsManagerTest,EndpointOrdering)527 TEST_F(DnsTaskResultsManagerTest, EndpointOrdering) {
528   // Has both IPv4/v6 addresses and metadata.
529   constexpr static const std::string_view kSvcbHost1 = "svc1.example.com";
530   // Has both IPv4/v6 addresses but no metadata.
531   constexpr static const std::string_view kSvcbHost2 = "svc2.example.com";
532   // Only has IPv4 addresses.
533   constexpr static const std::string_view kSvcbHost3 = "svc3.example.com";
534 
535   const std::vector<IPEndPoint> kSvcbHost1IPv4s = {MakeIPEndPoint("192.0.2.1")};
536   const std::vector<IPEndPoint> kSvcbHost2IPv4s = {MakeIPEndPoint("192.0.2.2")};
537   const std::vector<IPEndPoint> kSvcbHost3IPv4s = {MakeIPEndPoint("192.0.2.3")};
538 
539   const std::vector<IPEndPoint> kSvcbHost1IPv6s = {
540       MakeIPEndPoint("2001:db8::1")};
541   const std::vector<IPEndPoint> kSvcbHost2IPv6s = {
542       MakeIPEndPoint("2001:db8::2")};
543 
544   const ConnectionEndpointMetadata kSvcbHost1Metadata1(
545       /*supported_protocol_alpns=*/{"h2", "http/1.1"},
546       /*ech_config_list=*/{},
547       /*target_name=*/std::string(kSvcbHost1));
548   const ConnectionEndpointMetadata kSvcbHost1Metadata2(
549       /*supported_protocol_alpns=*/{"h3"},
550       /*ech_config_list=*/{},
551       /*target_name=*/std::string(kSvcbHost1));
552 
553   const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
554       kSvcbHost1Metadatas{{1, kSvcbHost1Metadata1}, {2, kSvcbHost1Metadata2}};
555 
556   struct TestData {
557     std::string_view host;
558     std::vector<IPEndPoint> ipv4_endpoints;
559     std::vector<IPEndPoint> ipv6_endpoints;
560     std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas;
561   };
562   const TestData kTestDatas[] = {
563       {kSvcbHost1,
564        /*ipv4_addresses=*/kSvcbHost1IPv4s,
565        /*ipv6_addresses=*/kSvcbHost1IPv6s,
566        /*metadatas=*/kSvcbHost1Metadatas},
567       {kSvcbHost2,
568        /*ipv4_addresses=*/kSvcbHost2IPv4s,
569        /*ipv6_addresses=*/kSvcbHost2IPv6s,
570        /*metadatas=*/{}},
571       {kSvcbHost3, /*ipv4_addresses=*/kSvcbHost3IPv4s,
572        /*ipv6_addresses=*/{}, /*metadatas=*/{}},
573   };
574 
575   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
576 
577   for (const auto& testdata : kTestDatas) {
578     if (!testdata.ipv4_endpoints.empty()) {
579       std::unique_ptr<HostResolverInternalResult> result = CreateDataResult(
580           testdata.host, testdata.ipv4_endpoints, DnsQueryType::A);
581       manager->ProcessDnsTransactionResults(DnsQueryType::A, {result.get()});
582     }
583     if (!testdata.ipv6_endpoints.empty()) {
584       std::unique_ptr<HostResolverInternalResult> result = CreateDataResult(
585           testdata.host, testdata.ipv6_endpoints, DnsQueryType::AAAA);
586       manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result.get()});
587     }
588     if (!testdata.metadatas.empty()) {
589       std::unique_ptr<HostResolverInternalResult> result =
590           CreateMetadata(testdata.host, testdata.metadatas);
591       manager->ProcessDnsTransactionResults(DnsQueryType::HTTPS,
592                                             {result.get()});
593     }
594   }
595 
596   const std::vector<ServiceEndpoint> kExpects = {
597       ServiceEndpoint(WithPort(kSvcbHost1IPv4s, 443),
598                       WithPort(kSvcbHost1IPv6s, 443), kSvcbHost1Metadata1),
599       ServiceEndpoint(WithPort(kSvcbHost1IPv4s, 443),
600                       WithPort(kSvcbHost1IPv6s, 443), kSvcbHost1Metadata2),
601       ServiceEndpoint(WithPort(kSvcbHost2IPv4s, 443),
602                       WithPort(kSvcbHost2IPv6s, 443),
603                       ConnectionEndpointMetadata()),
604       ServiceEndpoint(WithPort(kSvcbHost3IPv4s, 443), {},
605                       ConnectionEndpointMetadata()),
606   };
607 
608   ASSERT_EQ(manager->GetCurrentEndpoints().size(), kExpects.size());
609   for (size_t i = 0; i < manager->GetCurrentEndpoints().size(); ++i) {
610     SCOPED_TRACE(i);
611     EXPECT_THAT(manager->GetCurrentEndpoints()[i], kExpects[i]);
612   }
613 }
614 
TEST_F(DnsTaskResultsManagerTest,Aliases)615 TEST_F(DnsTaskResultsManagerTest, Aliases) {
616   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
617 
618   // AAAA is responded with aliases.
619   std::unique_ptr<HostResolverInternalResult> result1 =
620       CreateAlias(kHostName, DnsQueryType::AAAA, kAliasTarget1);
621   std::unique_ptr<HostResolverInternalResult> result2 =
622       CreateAlias(kAliasTarget1, DnsQueryType::AAAA, kAliasTarget2);
623   std::unique_ptr<HostResolverInternalResult> result3 = CreateDataResult(
624       kHostName, {MakeIPEndPoint("2001:db8::1")}, DnsQueryType::AAAA);
625   manager->ProcessDnsTransactionResults(
626       DnsQueryType::AAAA, {result1.get(), result2.get(), result3.get()});
627 
628   EXPECT_THAT(manager->GetCurrentEndpoints(),
629               ElementsAre(ExpectServiceEndpoint(
630                   IsEmpty(), ElementsAre(MakeIPEndPoint("2001:db8::1", 443)))));
631   EXPECT_THAT(manager->GetAliases(),
632               UnorderedElementsAre(kHostName, kAliasTarget1, kAliasTarget2));
633 }
634 
635 // Regression test for crbug.com/369232963. An IPv4 mapped IPv6 address should
636 // be handled without crashing.
TEST_F(DnsTaskResultsManagerTest,Ipv4MappedIpv6)637 TEST_F(DnsTaskResultsManagerTest, Ipv4MappedIpv6) {
638   std::unique_ptr<DnsTaskResultsManager> manager = factory().Create();
639 
640   auto ip_address = *IPAddress::FromIPLiteral("::ffff:192.0.2.1");
641   IPEndPoint endpoint(ConvertIPv4MappedIPv6ToIPv4(ip_address), /*port=*/0);
642   std::unique_ptr<HostResolverInternalResult> result =
643       CreateDataResult(kHostName, {endpoint}, DnsQueryType::AAAA);
644   manager->ProcessDnsTransactionResults(DnsQueryType::AAAA, {result.get()});
645   EXPECT_THAT(manager->GetCurrentEndpoints(),
646               ElementsAre(ExpectServiceEndpoint(
647                   ElementsAre(MakeIPEndPoint("192.0.2.1", 443)), IsEmpty())));
648 }
649 
650 }  // namespace net
651