xref: /aosp_15_r20/external/cronet/net/dns/dns_response_result_extractor.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 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 #ifndef NET_DNS_DNS_RESPONSE_RESULT_EXTRACTOR_H_
6 #define NET_DNS_DNS_RESPONSE_RESULT_EXTRACTOR_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <set>
12 #include <string_view>
13 
14 #include "base/memory/raw_ptr.h"
15 #include "base/time/clock.h"
16 #include "base/time/default_clock.h"
17 #include "base/time/default_tick_clock.h"
18 #include "base/types/expected.h"
19 #include "net/base/net_export.h"
20 #include "net/dns/host_cache.h"
21 #include "net/dns/public/dns_query_type.h"
22 
23 namespace net {
24 
25 class DnsResponse;
26 class HostResolverInternalResult;
27 
28 // Higher-level parser to take a DnsResponse and extract results.
29 class NET_EXPORT_PRIVATE DnsResponseResultExtractor {
30  public:
31   enum class ExtractionError {
32     kOk = 0,
33     // Record failed to parse.
34     kMalformedRecord,
35     // Malformed CNAME
36     kMalformedCname,
37     // Found CNAME or result record with an unexpected name.
38     kNameMismatch,
39     // Malformed result record
40     kMalformedResult,
41     // CNAME record after a result record
42     kCnameAfterResult,
43     // Multiple CNAME records for the same owner name.
44     kMultipleCnames,
45     // Invalid alias chain, e.g. contains loops or disjoint aliases.
46     kBadAliasChain,
47     // Not expected. Used for DCHECKs.
48     kUnexpected,
49   };
50 
51   using ResultsOrError =
52       base::expected<std::set<std::unique_ptr<HostResolverInternalResult>>,
53                      ExtractionError>;
54 
55   // References must stay alive for the life of the created extractor.
56   explicit DnsResponseResultExtractor(
57       const DnsResponse& response,
58       const base::Clock& clock = *base::DefaultClock::GetInstance(),
59       const base::TickClock& tick_clock =
60           *base::DefaultTickClock::GetInstance());
61   ~DnsResponseResultExtractor();
62 
63   DnsResponseResultExtractor(const DnsResponseResultExtractor&) = delete;
64   DnsResponseResultExtractor& operator=(const DnsResponseResultExtractor&) =
65       delete;
66 
67   // Extract results from the response. `query_type` must match the qtype from
68   // the DNS query, and it must have already been validated (expected to be done
69   // by DnsTransaction) that the response matches the query.
70   //
71   // `original_domain_name` is the query name (in dotted form) before any
72   // aliasing or prepending port/scheme. It is expected to be the name under
73   // which any basic query types, e.g. A or AAAA, are queried.
74   //
75   // May have the side effect of recording metrics about DnsResponses as they
76   // are parsed, so while not an absolute requirement, any given DnsResponse
77   // should only be used and extracted from at most once.
78   ResultsOrError ExtractDnsResults(DnsQueryType query_type,
79                                    std::string_view original_domain_name,
80                                    uint16_t request_port) const;
81 
82  private:
83   const raw_ref<const DnsResponse> response_;
84   const raw_ref<const base::Clock> clock_;
85   const raw_ref<const base::TickClock> tick_clock_;
86 };
87 
88 }  // namespace net
89 
90 #endif  // NET_DNS_DNS_RESPONSE_RESULT_EXTRACTOR_H_
91