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 }; 48 49 using ResultsOrError = 50 base::expected<std::set<std::unique_ptr<HostResolverInternalResult>>, 51 ExtractionError>; 52 53 // References must stay alive for the life of the created extractor. 54 explicit DnsResponseResultExtractor( 55 const DnsResponse& response, 56 const base::Clock& clock = *base::DefaultClock::GetInstance(), 57 const base::TickClock& tick_clock = 58 *base::DefaultTickClock::GetInstance()); 59 ~DnsResponseResultExtractor(); 60 61 DnsResponseResultExtractor(const DnsResponseResultExtractor&) = delete; 62 DnsResponseResultExtractor& operator=(const DnsResponseResultExtractor&) = 63 delete; 64 65 // Extract results from the response. `query_type` must match the qtype from 66 // the DNS query, and it must have already been validated (expected to be done 67 // by DnsTransaction) that the response matches the query. 68 // 69 // `original_domain_name` is the query name (in dotted form) before any 70 // aliasing or prepending port/scheme. It is expected to be the name under 71 // which any basic query types, e.g. A or AAAA, are queried. 72 // 73 // May have the side effect of recording metrics about DnsResponses as they 74 // are parsed, so while not an absolute requirement, any given DnsResponse 75 // should only be used and extracted from at most once. 76 ResultsOrError ExtractDnsResults(DnsQueryType query_type, 77 std::string_view original_domain_name, 78 uint16_t request_port) const; 79 80 private: 81 const raw_ref<const DnsResponse> response_; 82 const raw_ref<const base::Clock> clock_; 83 const raw_ref<const base::TickClock> tick_clock_; 84 }; 85 86 } // namespace net 87 88 #endif // NET_DNS_DNS_RESPONSE_RESULT_EXTRACTOR_H_ 89