269 lines
10 KiB
C++
269 lines
10 KiB
C++
// Copyright 2022 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
|
|
#define NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
#include "base/time/time.h"
|
|
#include "base/values.h"
|
|
#include "net/base/connection_endpoint_metadata.h"
|
|
#include "net/base/host_port_pair.h"
|
|
#include "net/base/ip_endpoint.h"
|
|
#include "net/base/net_export.h"
|
|
#include "net/dns/https_record_rdata.h"
|
|
#include "net/dns/public/dns_query_type.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
namespace net {
|
|
|
|
class HostResolverInternalDataResult;
|
|
class HostResolverInternalMetadataResult;
|
|
class HostResolverInternalErrorResult;
|
|
class HostResolverInternalAliasResult;
|
|
|
|
// Parsed and extracted result type for use internally to HostResolver code.
|
|
class NET_EXPORT_PRIVATE HostResolverInternalResult {
|
|
public:
|
|
enum class Type { kData, kMetadata, kError, kAlias };
|
|
enum class Source { kDns, kHosts, kUnknown };
|
|
|
|
// Nullptr if `value` is malformed to be deserialized.
|
|
static std::unique_ptr<HostResolverInternalResult> FromValue(
|
|
const base::Value& value);
|
|
|
|
virtual ~HostResolverInternalResult() = default;
|
|
|
|
const std::string& domain_name() const { return domain_name_; }
|
|
DnsQueryType query_type() const { return query_type_; }
|
|
Type type() const { return type_; }
|
|
Source source() const { return source_; }
|
|
absl::optional<base::TimeTicks> expiration() const { return expiration_; }
|
|
absl::optional<base::Time> timed_expiration() const {
|
|
return timed_expiration_;
|
|
}
|
|
|
|
const HostResolverInternalDataResult& AsData() const;
|
|
const HostResolverInternalMetadataResult& AsMetadata() const;
|
|
const HostResolverInternalErrorResult& AsError() const;
|
|
const HostResolverInternalAliasResult& AsAlias() const;
|
|
|
|
virtual base::Value ToValue() const = 0;
|
|
|
|
protected:
|
|
HostResolverInternalResult(std::string domain_name,
|
|
DnsQueryType query_type,
|
|
absl::optional<base::TimeTicks> expiration,
|
|
absl::optional<base::Time> timed_expiration,
|
|
Type type,
|
|
Source source);
|
|
// Expect to only be called with a `dict` well-formed for deserialization. Can
|
|
// be checked via ValidateValueBaseDict().
|
|
explicit HostResolverInternalResult(const base::Value::Dict& dict);
|
|
|
|
bool operator==(const HostResolverInternalResult& other) const {
|
|
return std::tie(domain_name_, query_type_, type_, source_, expiration_,
|
|
timed_expiration_) ==
|
|
std::tie(other.domain_name_, other.query_type_, other.type_,
|
|
other.source_, other.expiration_, other.timed_expiration_);
|
|
}
|
|
|
|
static bool ValidateValueBaseDict(const base::Value::Dict& dict,
|
|
bool require_timed_expiration);
|
|
base::Value::Dict ToValueBaseDict() const;
|
|
|
|
private:
|
|
const std::string domain_name_;
|
|
const DnsQueryType query_type_;
|
|
const Type type_;
|
|
const Source source_;
|
|
|
|
// Expiration logic should prefer to be based on `expiration_` for correctness
|
|
// through system time changes. But if result has been serialized to disk, it
|
|
// may be that only `timed_expiration_` is available.
|
|
const absl::optional<base::TimeTicks> expiration_;
|
|
const absl::optional<base::Time> timed_expiration_;
|
|
};
|
|
|
|
// Parsed and extracted result containing result data.
|
|
class NET_EXPORT_PRIVATE HostResolverInternalDataResult final
|
|
: public HostResolverInternalResult {
|
|
public:
|
|
static std::unique_ptr<HostResolverInternalDataResult> FromValue(
|
|
const base::Value& value);
|
|
|
|
// `domain_name` is dotted form.
|
|
HostResolverInternalDataResult(std::string domain_name,
|
|
DnsQueryType query_type,
|
|
absl::optional<base::TimeTicks> expiration,
|
|
base::Time timed_expiration,
|
|
Source source,
|
|
std::vector<IPEndPoint> endpoints,
|
|
std::vector<std::string> strings,
|
|
std::vector<HostPortPair> hosts);
|
|
~HostResolverInternalDataResult() override;
|
|
|
|
HostResolverInternalDataResult(const HostResolverInternalDataResult&) =
|
|
delete;
|
|
HostResolverInternalDataResult& operator=(
|
|
const HostResolverInternalDataResult&) = delete;
|
|
|
|
bool operator==(const HostResolverInternalDataResult& other) const {
|
|
return HostResolverInternalResult::operator==(other) &&
|
|
std::tie(endpoints_, strings_, hosts_) ==
|
|
std::tie(other.endpoints_, other.strings_, other.hosts_);
|
|
}
|
|
|
|
const std::vector<IPEndPoint>& endpoints() const { return endpoints_; }
|
|
const std::vector<std::string>& strings() const { return strings_; }
|
|
const std::vector<HostPortPair>& hosts() const { return hosts_; }
|
|
|
|
base::Value ToValue() const override;
|
|
|
|
private:
|
|
HostResolverInternalDataResult(const base::Value::Dict& dict,
|
|
std::vector<IPEndPoint> endpoints,
|
|
std::vector<std::string> strings,
|
|
std::vector<HostPortPair> hosts);
|
|
|
|
// Corresponds to the `HostResolverEndpointResult::ip_endpoints` portion of
|
|
// `HostResolver::ResolveHostRequest::GetEndpointResults()`.
|
|
const std::vector<IPEndPoint> endpoints_;
|
|
|
|
// Corresponds to `HostResolver::ResolveHostRequest::GetTextResults()`.
|
|
const std::vector<std::string> strings_;
|
|
|
|
// Corresponds to `HostResolver::ResolveHostRequest::GetHostnameResults()`.
|
|
const std::vector<HostPortPair> hosts_;
|
|
};
|
|
|
|
// Parsed and extracted connection metadata, but not usable on its own without
|
|
// being paired with separate HostResolverInternalDataResult data (for the
|
|
// domain name specified by `ConnectionEndpointMetadata::target_name`). An empty
|
|
// metadata result signifies that compatible HTTPS records were received but
|
|
// with no contained metadata of use to Chrome.
|
|
class NET_EXPORT_PRIVATE HostResolverInternalMetadataResult final
|
|
: public HostResolverInternalResult {
|
|
public:
|
|
static std::unique_ptr<HostResolverInternalMetadataResult> FromValue(
|
|
const base::Value& value);
|
|
|
|
// `domain_name` and `data_domain` are dotted form domain names.
|
|
HostResolverInternalMetadataResult(
|
|
std::string domain_name,
|
|
DnsQueryType query_type,
|
|
absl::optional<base::TimeTicks> expiration,
|
|
base::Time timed_expiration,
|
|
Source source,
|
|
std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas);
|
|
~HostResolverInternalMetadataResult() override;
|
|
|
|
HostResolverInternalMetadataResult(
|
|
const HostResolverInternalMetadataResult&) = delete;
|
|
HostResolverInternalMetadataResult& operator=(
|
|
const HostResolverInternalMetadataResult&) = delete;
|
|
|
|
bool operator==(const HostResolverInternalMetadataResult& other) const {
|
|
return HostResolverInternalResult::operator==(other) &&
|
|
metadatas_ == other.metadatas_;
|
|
}
|
|
|
|
const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>&
|
|
metadatas() const {
|
|
return metadatas_;
|
|
}
|
|
|
|
base::Value ToValue() const override;
|
|
|
|
private:
|
|
HostResolverInternalMetadataResult(
|
|
const base::Value::Dict& dict,
|
|
std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas);
|
|
|
|
std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas_;
|
|
};
|
|
|
|
// Parsed and extracted error.
|
|
class NET_EXPORT_PRIVATE HostResolverInternalErrorResult final
|
|
: public HostResolverInternalResult {
|
|
public:
|
|
static std::unique_ptr<HostResolverInternalErrorResult> FromValue(
|
|
const base::Value& value);
|
|
|
|
// `domain_name` is dotted form. `timed_expiration` may be `nullopt` for
|
|
// non-cacheable errors.
|
|
HostResolverInternalErrorResult(std::string domain_name,
|
|
DnsQueryType query_type,
|
|
absl::optional<base::TimeTicks> expiration,
|
|
absl::optional<base::Time> timed_expiration,
|
|
Source source,
|
|
int error);
|
|
~HostResolverInternalErrorResult() override = default;
|
|
|
|
HostResolverInternalErrorResult(const HostResolverInternalErrorResult&) =
|
|
delete;
|
|
HostResolverInternalErrorResult& operator=(
|
|
const HostResolverInternalErrorResult&) = delete;
|
|
|
|
bool operator==(const HostResolverInternalErrorResult& other) const {
|
|
return HostResolverInternalResult::operator==(other) &&
|
|
error_ == other.error_;
|
|
}
|
|
|
|
int error() const { return error_; }
|
|
|
|
base::Value ToValue() const override;
|
|
|
|
private:
|
|
HostResolverInternalErrorResult(const base::Value::Dict& dict, int error);
|
|
|
|
const int error_;
|
|
};
|
|
|
|
// Parsed and extracted alias (CNAME or alias-type HTTPS).
|
|
class NET_EXPORT_PRIVATE HostResolverInternalAliasResult final
|
|
: public HostResolverInternalResult {
|
|
public:
|
|
static std::unique_ptr<HostResolverInternalAliasResult> FromValue(
|
|
const base::Value& value);
|
|
|
|
// `domain_name` and `alias_target` are dotted form domain names.
|
|
HostResolverInternalAliasResult(std::string domain_name,
|
|
DnsQueryType query_type,
|
|
absl::optional<base::TimeTicks> expiration,
|
|
base::Time timed_expiration,
|
|
Source source,
|
|
std::string alias_target);
|
|
~HostResolverInternalAliasResult() override = default;
|
|
|
|
HostResolverInternalAliasResult(const HostResolverInternalAliasResult&) =
|
|
delete;
|
|
HostResolverInternalAliasResult& operator=(
|
|
const HostResolverInternalAliasResult&) = delete;
|
|
|
|
bool operator==(const HostResolverInternalAliasResult& other) const {
|
|
return HostResolverInternalResult::operator==(other) &&
|
|
alias_target_ == other.alias_target_;
|
|
}
|
|
|
|
const std::string& alias_target() const { return alias_target_; }
|
|
|
|
base::Value ToValue() const override;
|
|
|
|
private:
|
|
HostResolverInternalAliasResult(const base::Value::Dict& dict,
|
|
std::string alias_target);
|
|
|
|
const std::string alias_target_;
|
|
};
|
|
|
|
} // namespace net
|
|
|
|
#endif // NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
|