xref: /aosp_15_r20/external/cronet/net/dns/host_resolver_internal_result.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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_HOST_RESOLVER_INTERNAL_RESULT_H_
6 #define NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
7 
8 #include <map>
9 #include <memory>
10 #include <optional>
11 #include <string>
12 #include <tuple>
13 #include <vector>
14 
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "net/base/connection_endpoint_metadata.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/base/net_export.h"
21 #include "net/dns/https_record_rdata.h"
22 #include "net/dns/public/dns_query_type.h"
23 
24 namespace net {
25 
26 class HostResolverInternalDataResult;
27 class HostResolverInternalMetadataResult;
28 class HostResolverInternalErrorResult;
29 class HostResolverInternalAliasResult;
30 
31 // Parsed and extracted result type for use internally to HostResolver code.
32 class NET_EXPORT_PRIVATE HostResolverInternalResult {
33  public:
34   enum class Type { kData, kMetadata, kError, kAlias };
35   enum class Source { kDns, kHosts, kUnknown };
36 
37   // Nullptr if `value` is malformed to be deserialized.
38   static std::unique_ptr<HostResolverInternalResult> FromValue(
39       const base::Value& value);
40 
41   virtual ~HostResolverInternalResult() = default;
42 
domain_name()43   const std::string& domain_name() const { return domain_name_; }
query_type()44   DnsQueryType query_type() const { return query_type_; }
type()45   Type type() const { return type_; }
source()46   Source source() const { return source_; }
expiration()47   std::optional<base::TimeTicks> expiration() const { return expiration_; }
timed_expiration()48   std::optional<base::Time> timed_expiration() const {
49     return timed_expiration_;
50   }
51 
52   const HostResolverInternalDataResult& AsData() const;
53   HostResolverInternalDataResult& AsData();
54   const HostResolverInternalMetadataResult& AsMetadata() const;
55   HostResolverInternalMetadataResult& AsMetadata();
56   const HostResolverInternalErrorResult& AsError() const;
57   HostResolverInternalErrorResult& AsError();
58   const HostResolverInternalAliasResult& AsAlias() const;
59   HostResolverInternalAliasResult& AsAlias();
60 
61   virtual std::unique_ptr<HostResolverInternalResult> Clone() const = 0;
62 
63   virtual base::Value ToValue() const = 0;
64 
65  protected:
66   HostResolverInternalResult(std::string domain_name,
67                              DnsQueryType query_type,
68                              std::optional<base::TimeTicks> expiration,
69                              std::optional<base::Time> timed_expiration,
70                              Type type,
71                              Source source);
72   // Expect to only be called with a `dict` well-formed for deserialization. Can
73   // be checked via ValidateValueBaseDict().
74   explicit HostResolverInternalResult(const base::Value::Dict& dict);
75 
76   bool operator==(const HostResolverInternalResult& other) const {
77     return std::tie(domain_name_, query_type_, type_, source_, expiration_,
78                     timed_expiration_) ==
79            std::tie(other.domain_name_, other.query_type_, other.type_,
80                     other.source_, other.expiration_, other.timed_expiration_);
81   }
82 
83   static bool ValidateValueBaseDict(const base::Value::Dict& dict,
84                                     bool require_timed_expiration);
85   base::Value::Dict ToValueBaseDict() const;
86 
87  private:
88   const std::string domain_name_;
89   const DnsQueryType query_type_;
90   const Type type_;
91   const Source source_;
92 
93   // Expiration logic should prefer to be based on `expiration_` for correctness
94   // through system time changes. But if result has been serialized to disk, it
95   // may be that only `timed_expiration_` is available.
96   const std::optional<base::TimeTicks> expiration_;
97   const std::optional<base::Time> timed_expiration_;
98 };
99 
100 // Parsed and extracted result containing result data.
101 class NET_EXPORT_PRIVATE HostResolverInternalDataResult final
102     : public HostResolverInternalResult {
103  public:
104   static std::unique_ptr<HostResolverInternalDataResult> FromValue(
105       const base::Value& value);
106 
107   // `domain_name` is dotted form.
108   HostResolverInternalDataResult(std::string domain_name,
109                                  DnsQueryType query_type,
110                                  std::optional<base::TimeTicks> expiration,
111                                  base::Time timed_expiration,
112                                  Source source,
113                                  std::vector<IPEndPoint> endpoints,
114                                  std::vector<std::string> strings,
115                                  std::vector<HostPortPair> hosts);
116   ~HostResolverInternalDataResult() override;
117 
118   HostResolverInternalDataResult(const HostResolverInternalDataResult&) =
119       delete;
120   HostResolverInternalDataResult& operator=(
121       const HostResolverInternalDataResult&) = delete;
122 
123   bool operator==(const HostResolverInternalDataResult& other) const {
124     return HostResolverInternalResult::operator==(other) &&
125            std::tie(endpoints_, strings_, hosts_) ==
126                std::tie(other.endpoints_, other.strings_, other.hosts_);
127   }
128 
endpoints()129   const std::vector<IPEndPoint>& endpoints() const { return endpoints_; }
set_endpoints(std::vector<IPEndPoint> endpoints)130   void set_endpoints(std::vector<IPEndPoint> endpoints) {
131     endpoints_ = std::move(endpoints);
132   }
strings()133   const std::vector<std::string>& strings() const { return strings_; }
set_strings(std::vector<std::string> strings)134   void set_strings(std::vector<std::string> strings) {
135     strings_ = std::move(strings);
136   }
hosts()137   const std::vector<HostPortPair>& hosts() const { return hosts_; }
set_hosts(std::vector<HostPortPair> hosts)138   void set_hosts(std::vector<HostPortPair> hosts) { hosts_ = std::move(hosts); }
139 
140   std::unique_ptr<HostResolverInternalResult> Clone() const override;
141 
142   base::Value ToValue() const override;
143 
144  private:
145   HostResolverInternalDataResult(const base::Value::Dict& dict,
146                                  std::vector<IPEndPoint> endpoints,
147                                  std::vector<std::string> strings,
148                                  std::vector<HostPortPair> hosts);
149 
150   // Corresponds to the `HostResolverEndpointResult::ip_endpoints` portion of
151   // `HostResolver::ResolveHostRequest::GetEndpointResults()`.
152   std::vector<IPEndPoint> endpoints_;
153 
154   // Corresponds to `HostResolver::ResolveHostRequest::GetTextResults()`.
155   std::vector<std::string> strings_;
156 
157   // Corresponds to `HostResolver::ResolveHostRequest::GetHostnameResults()`.
158   std::vector<HostPortPair> hosts_;
159 };
160 
161 // Parsed and extracted connection metadata, but not usable on its own without
162 // being paired with separate HostResolverInternalDataResult data (for the
163 // domain name specified by `ConnectionEndpointMetadata::target_name`). An empty
164 // metadata result signifies that compatible HTTPS records were received but
165 // with no contained metadata of use to Chrome.
166 class NET_EXPORT_PRIVATE HostResolverInternalMetadataResult final
167     : public HostResolverInternalResult {
168  public:
169   static std::unique_ptr<HostResolverInternalMetadataResult> FromValue(
170       const base::Value& value);
171 
172   // `domain_name` and `data_domain` are dotted form domain names.
173   HostResolverInternalMetadataResult(
174       std::string domain_name,
175       DnsQueryType query_type,
176       std::optional<base::TimeTicks> expiration,
177       base::Time timed_expiration,
178       Source source,
179       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas);
180   ~HostResolverInternalMetadataResult() override;
181 
182   HostResolverInternalMetadataResult(
183       const HostResolverInternalMetadataResult&) = delete;
184   HostResolverInternalMetadataResult& operator=(
185       const HostResolverInternalMetadataResult&) = delete;
186 
187   bool operator==(const HostResolverInternalMetadataResult& other) const {
188     return HostResolverInternalResult::operator==(other) &&
189            metadatas_ == other.metadatas_;
190   }
191 
192   const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>&
metadatas()193   metadatas() const {
194     return metadatas_;
195   }
196 
197   std::unique_ptr<HostResolverInternalResult> Clone() const override;
198 
199   base::Value ToValue() const override;
200 
201  private:
202   HostResolverInternalMetadataResult(
203       const base::Value::Dict& dict,
204       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas);
205 
206   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas_;
207 };
208 
209 // Parsed and extracted error.
210 class NET_EXPORT_PRIVATE HostResolverInternalErrorResult final
211     : public HostResolverInternalResult {
212  public:
213   static std::unique_ptr<HostResolverInternalErrorResult> FromValue(
214       const base::Value& value);
215 
216   // `domain_name` is dotted form. `timed_expiration` may be `nullopt` for
217   // non-cacheable errors.
218   HostResolverInternalErrorResult(std::string domain_name,
219                                   DnsQueryType query_type,
220                                   std::optional<base::TimeTicks> expiration,
221                                   std::optional<base::Time> timed_expiration,
222                                   Source source,
223                                   int error);
224   ~HostResolverInternalErrorResult() override = default;
225 
226   HostResolverInternalErrorResult(const HostResolverInternalErrorResult&) =
227       delete;
228   HostResolverInternalErrorResult& operator=(
229       const HostResolverInternalErrorResult&) = delete;
230 
231   bool operator==(const HostResolverInternalErrorResult& other) const {
232     return HostResolverInternalResult::operator==(other) &&
233            error_ == other.error_;
234   }
235 
error()236   int error() const { return error_; }
237 
238   std::unique_ptr<HostResolverInternalResult> Clone() const override;
239 
240   base::Value ToValue() const override;
241 
242  private:
243   HostResolverInternalErrorResult(const base::Value::Dict& dict, int error);
244 
245   const int error_;
246 };
247 
248 // Parsed and extracted alias (CNAME or alias-type HTTPS).
249 class NET_EXPORT_PRIVATE HostResolverInternalAliasResult final
250     : public HostResolverInternalResult {
251  public:
252   static std::unique_ptr<HostResolverInternalAliasResult> FromValue(
253       const base::Value& value);
254 
255   // `domain_name` and `alias_target` are dotted form domain names.
256   HostResolverInternalAliasResult(std::string domain_name,
257                                   DnsQueryType query_type,
258                                   std::optional<base::TimeTicks> expiration,
259                                   base::Time timed_expiration,
260                                   Source source,
261                                   std::string alias_target);
262   ~HostResolverInternalAliasResult() override = default;
263 
264   HostResolverInternalAliasResult(const HostResolverInternalAliasResult&) =
265       delete;
266   HostResolverInternalAliasResult& operator=(
267       const HostResolverInternalAliasResult&) = delete;
268 
269   bool operator==(const HostResolverInternalAliasResult& other) const {
270     return HostResolverInternalResult::operator==(other) &&
271            alias_target_ == other.alias_target_;
272   }
273 
alias_target()274   const std::string& alias_target() const { return alias_target_; }
275 
276   std::unique_ptr<HostResolverInternalResult> Clone() const override;
277 
278   base::Value ToValue() const override;
279 
280  private:
281   HostResolverInternalAliasResult(const base::Value::Dict& dict,
282                                   std::string alias_target);
283 
284   const std::string alias_target_;
285 };
286 
287 }  // namespace net
288 
289 #endif  // NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
290