// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_ #define OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_ #include #include #include #include #include "absl/strings/string_view.h" #include "platform/base/error.h" #include "util/osp_logging.h" namespace openscreen { namespace osp { struct DomainName { static ErrorOr Append(const DomainName& first, const DomainName& second); template static ErrorOr FromLabels(It first, It last) { size_t total_length = 1; for (auto label = first; label != last; ++label) { if (label->size() > kDomainNameMaxLabelLength) return Error::Code::kDomainNameLabelTooLong; total_length += label->size() + 1; } if (total_length > kDomainNameMaxLength) return Error::Code::kDomainNameTooLong; DomainName result; result.domain_name_.resize(total_length); auto result_it = result.domain_name_.begin(); for (auto label = first; label != last; ++label) { *result_it++ = static_cast(label->size()); result_it = std::copy(label->begin(), label->end(), result_it); } *result_it = 0; return std::move(result); } static DomainName GetLocalDomain(); static constexpr uint8_t kDomainNameMaxLabelLength = 63u; static constexpr uint16_t kDomainNameMaxLength = 256u; DomainName(); explicit DomainName(std::vector&& domain_name); DomainName(const DomainName&); DomainName(DomainName&&) noexcept; ~DomainName(); DomainName& operator=(const DomainName&); DomainName& operator=(DomainName&&) noexcept; bool operator==(const DomainName& other) const; bool operator!=(const DomainName& other) const; bool EndsWithLocalDomain() const; bool IsEmpty() const { return domain_name_.size() == 1 && !domain_name_[0]; } Error Append(const DomainName& after); std::vector GetLabels() const; const std::vector& domain_name() const { return domain_name_; } private: // RFC 1035 domain name format: sequence of 1 octet label length followed by // label data, ending with a 0 octet. May not exceed 256 bytes (including // terminating 0). // For example, openscreen.org would be encoded as: // {10, 'o', 'p', 'e', 'n', 's', 'c', 'r', 'e', 'e', 'n', // 3, 'o', 'r', 'g', 0} std::vector domain_name_; }; class DomainNameComparator { public: bool operator()(const DomainName& a, const DomainName& b) const; }; std::ostream& operator<<(std::ostream& os, const DomainName& domain_name); } // namespace osp } // namespace openscreen #endif // OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_