96 lines
4.1 KiB
C++
96 lines
4.1 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_DNS_NAMES_UTIL_H_
|
|
#define NET_DNS_DNS_NAMES_UTIL_H_
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/containers/span.h"
|
|
#include "base/strings/string_piece.h"
|
|
#include "base/strings/string_util.h"
|
|
#include "net/base/net_export.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
namespace base {
|
|
class BigEndianReader;
|
|
} // namespace base
|
|
|
|
// Various utilities for converting, validating, and comparing DNS names.
|
|
namespace net::dns_names_util {
|
|
|
|
// Returns true iff `dotted` is acceptable to be encoded as a DNS name. That is
|
|
// that it is non-empty and fits size limitations. Also must match the expected
|
|
// structure of dot-separated labels, each non-empty and fitting within
|
|
// additional size limitations, and an optional dot at the end. See RFCs 1035
|
|
// and 2181.
|
|
//
|
|
// No validation is performed for correctness of characters within a label.
|
|
// As explained by RFC 2181, commonly cited rules for such characters are not
|
|
// DNS restrictions, but actually restrictions for Internet hostnames. For such
|
|
// validation, see IsCanonicalizedHostCompliant().
|
|
NET_EXPORT_PRIVATE bool IsValidDnsName(base::StringPiece dotted_form_name);
|
|
|
|
// Like IsValidDnsName() but further validates `dotted_form_name` is not an IP
|
|
// address (with or without surrounding []) or localhost, as such names would
|
|
// not be suitable for DNS queries or for use as DNS record names or alias
|
|
// target names.
|
|
NET_EXPORT_PRIVATE bool IsValidDnsRecordName(
|
|
base::StringPiece dotted_form_name);
|
|
|
|
// Convert a dotted-form DNS name to network wire format. Returns nullopt if
|
|
// input is not valid for conversion (equivalent validity can be checked using
|
|
// IsValidDnsName()). If `require_valid_internet_hostname` is true, also returns
|
|
// nullopt if input is not a valid internet hostname (equivalent validity can be
|
|
// checked using net::IsCanonicalizedHostCompliant()).
|
|
NET_EXPORT_PRIVATE absl::optional<std::vector<uint8_t>> DottedNameToNetwork(
|
|
base::StringPiece dotted_form_name,
|
|
bool require_valid_internet_hostname = false);
|
|
|
|
// Converts a domain in DNS format to a dotted string. Excludes the dot at the
|
|
// end. Returns nullopt on malformed input.
|
|
//
|
|
// If `require_complete` is true, input will be considered malformed if it does
|
|
// not contain a terminating zero-length label. If false, assumes the standard
|
|
// terminating zero-length label at the end if not included in the input.
|
|
//
|
|
// DNS name compression (see RFC 1035, section 4.1.4) is disallowed and
|
|
// considered malformed. To handle a potentially compressed name, in a
|
|
// DnsResponse object, use DnsRecordParser::ReadName().
|
|
NET_EXPORT_PRIVATE absl::optional<std::string> NetworkToDottedName(
|
|
base::span<const uint8_t> dns_network_wire_name,
|
|
bool require_complete = false);
|
|
NET_EXPORT_PRIVATE absl::optional<std::string> NetworkToDottedName(
|
|
base::StringPiece dns_network_wire_name,
|
|
bool require_complete = false);
|
|
NET_EXPORT_PRIVATE absl::optional<std::string> NetworkToDottedName(
|
|
base::BigEndianReader& reader,
|
|
bool require_complete = false);
|
|
|
|
// Canonicalize `name` as a URL hostname if able. If unable (typically if a name
|
|
// is not a valid URL hostname), returns `name` without change because such a
|
|
// name could still be a valid DNS name.
|
|
NET_EXPORT_PRIVATE std::string UrlCanonicalizeNameIfAble(
|
|
base::StringPiece name);
|
|
|
|
// std::map-compliant Compare for two domain names. Works for any valid
|
|
// dotted-format or network-wire-format names. Returns true iff `lhs` is before
|
|
// `rhs` in strict weak ordering.
|
|
class NET_EXPORT_PRIVATE DomainNameComparator {
|
|
public:
|
|
bool operator()(base::StringPiece lhs, base::StringPiece rhs) const {
|
|
// This works for dotted format or network-wire format as long as the names
|
|
// are valid because valid network-wire names have labels of max 63 bytes
|
|
// and thus will never have label length prefixes high enough to be
|
|
// misinterpreted as capital letters ('A' is 65).
|
|
return base::CompareCaseInsensitiveASCII(lhs, rhs) < 0;
|
|
}
|
|
};
|
|
|
|
} // namespace net::dns_names_util
|
|
|
|
#endif // NET_DNS_DNS_NAMES_UTIL_H_
|