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