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