1 // Copyright 2018 The Chromium Authors. All rights reserved. 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 OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_ 6 #define OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_ 7 8 #include <cstdint> 9 #include <ostream> 10 #include <string> 11 #include <vector> 12 13 #include "absl/strings/string_view.h" 14 #include "platform/base/error.h" 15 #include "util/osp_logging.h" 16 17 namespace openscreen { 18 namespace osp { 19 20 struct DomainName { 21 static ErrorOr<DomainName> Append(const DomainName& first, 22 const DomainName& second); 23 24 template <typename It> FromLabelsDomainName25 static ErrorOr<DomainName> FromLabels(It first, It last) { 26 size_t total_length = 1; 27 for (auto label = first; label != last; ++label) { 28 if (label->size() > kDomainNameMaxLabelLength) 29 return Error::Code::kDomainNameLabelTooLong; 30 31 total_length += label->size() + 1; 32 } 33 if (total_length > kDomainNameMaxLength) 34 return Error::Code::kDomainNameTooLong; 35 36 DomainName result; 37 result.domain_name_.resize(total_length); 38 auto result_it = result.domain_name_.begin(); 39 for (auto label = first; label != last; ++label) { 40 *result_it++ = static_cast<uint8_t>(label->size()); 41 result_it = std::copy(label->begin(), label->end(), result_it); 42 } 43 *result_it = 0; 44 return std::move(result); 45 } 46 47 static DomainName GetLocalDomain(); 48 49 static constexpr uint8_t kDomainNameMaxLabelLength = 63u; 50 static constexpr uint16_t kDomainNameMaxLength = 256u; 51 52 DomainName(); 53 explicit DomainName(std::vector<uint8_t>&& domain_name); 54 DomainName(const DomainName&); 55 DomainName(DomainName&&) noexcept; 56 ~DomainName(); 57 DomainName& operator=(const DomainName&); 58 DomainName& operator=(DomainName&&) noexcept; 59 60 bool operator==(const DomainName& other) const; 61 bool operator!=(const DomainName& other) const; 62 63 bool EndsWithLocalDomain() const; IsEmptyDomainName64 bool IsEmpty() const { return domain_name_.size() == 1 && !domain_name_[0]; } 65 66 Error Append(const DomainName& after); 67 std::vector<absl::string_view> GetLabels() const; 68 domain_nameDomainName69 const std::vector<uint8_t>& domain_name() const { return domain_name_; } 70 71 private: 72 // RFC 1035 domain name format: sequence of 1 octet label length followed by 73 // label data, ending with a 0 octet. May not exceed 256 bytes (including 74 // terminating 0). 75 // For example, openscreen.org would be encoded as: 76 // {10, 'o', 'p', 'e', 'n', 's', 'c', 'r', 'e', 'e', 'n', 77 // 3, 'o', 'r', 'g', 0} 78 std::vector<uint8_t> domain_name_; 79 }; 80 81 class DomainNameComparator { 82 public: 83 bool operator()(const DomainName& a, const DomainName& b) const; 84 }; 85 86 std::ostream& operator<<(std::ostream& os, const DomainName& domain_name); 87 88 } // namespace osp 89 } // namespace openscreen 90 91 #endif // OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_ 92