1 // Copyright 2019 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 DISCOVERY_DNSSD_PUBLIC_DNS_SD_INSTANCE_ENDPOINT_H_ 6 #define DISCOVERY_DNSSD_PUBLIC_DNS_SD_INSTANCE_ENDPOINT_H_ 7 8 #include <string> 9 #include <utility> 10 #include <vector> 11 12 #include "discovery/dnssd/public/dns_sd_instance.h" 13 #include "discovery/dnssd/public/dns_sd_txt_record.h" 14 #include "platform/base/interface_info.h" 15 #include "platform/base/ip_address.h" 16 17 namespace openscreen { 18 namespace discovery { 19 20 // Represents the data stored in DNS records of types SRV, TXT, A, and AAAA 21 class DnsSdInstanceEndpoint : public DnsSdInstance { 22 public: 23 using DnsSdInstance::Subtype; 24 25 // These ctors expect valid input, and will cause a crash if they are not. 26 // Additionally, these ctors expect at least one IPAddress will be provided. 27 DnsSdInstanceEndpoint(DnsSdInstance record, 28 NetworkInterfaceIndex network_interface, 29 std::vector<IPEndpoint> address); 30 31 DnsSdInstanceEndpoint(std::string instance_id, 32 std::string service_id, 33 std::string domain_id, 34 DnsSdTxtRecord txt, 35 NetworkInterfaceIndex network_interface, 36 std::vector<IPEndpoint> endpoint); 37 DnsSdInstanceEndpoint(std::string instance_id, 38 std::string service_id, 39 std::string domain_id, 40 DnsSdTxtRecord txt, 41 NetworkInterfaceIndex network_interface, 42 std::vector<IPEndpoint> endpoint, 43 std::vector<Subtype> subtypes); 44 45 // Overloads of the above ctors to allow for simpler creation. The same 46 // expectations as above apply. 47 template <typename... TEndpoints> DnsSdInstanceEndpoint(DnsSdInstance record,NetworkInterfaceIndex network_interface,TEndpoints...endpoints)48 DnsSdInstanceEndpoint(DnsSdInstance record, 49 NetworkInterfaceIndex network_interface, 50 TEndpoints... endpoints) 51 : DnsSdInstanceEndpoint( 52 std::move(record), 53 network_interface, 54 std::vector<IPEndpoint>{std::move(endpoints)...}) {} 55 56 // NOTE: All subtypes must follow all IPEndpoints. 57 template <typename... Types> DnsSdInstanceEndpoint(std::string instance_id,std::string service_id,std::string domain_id,DnsSdTxtRecord txt,NetworkInterfaceIndex network_interface,IPEndpoint endpoint,Types...types)58 DnsSdInstanceEndpoint(std::string instance_id, 59 std::string service_id, 60 std::string domain_id, 61 DnsSdTxtRecord txt, 62 NetworkInterfaceIndex network_interface, 63 IPEndpoint endpoint, 64 Types... types) 65 : DnsSdInstanceEndpoint( 66 std::move(instance_id), 67 std::move(service_id), 68 std::move(domain_id), 69 std::move(txt), 70 network_interface, 71 GetVectorWithCapacity<IPEndpoint>(sizeof...(Types) + 1), 72 GetVectorWithCapacity<Subtype>(sizeof...(Types)), 73 std::move(endpoint), 74 std::move(types)...) {} 75 76 DnsSdInstanceEndpoint(const DnsSdInstanceEndpoint& other); 77 DnsSdInstanceEndpoint(DnsSdInstanceEndpoint&& other); 78 79 ~DnsSdInstanceEndpoint() override; 80 81 DnsSdInstanceEndpoint& operator=(const DnsSdInstanceEndpoint& rhs); 82 DnsSdInstanceEndpoint& operator=(DnsSdInstanceEndpoint&& rhs); 83 84 // Returns the address associated with this DNS-SD record. In any valid 85 // record, at least one will be set. addresses()86 const std::vector<IPAddress>& addresses() const { return addresses_; } endpoints()87 const std::vector<IPEndpoint>& endpoints() const { return endpoints_; } 88 89 // Network Interface associated with this endpoint. network_interface()90 NetworkInterfaceIndex network_interface() const { return network_interface_; } 91 92 private: 93 // Pick off the first IPEndpoint then call again recursively. 94 template <typename... Types> DnsSdInstanceEndpoint(std::string instance_id,std::string service_id,std::string domain_id,DnsSdTxtRecord txt,NetworkInterfaceIndex network_interface,std::vector<IPEndpoint> endpoints,std::vector<Subtype> subtypes,IPEndpoint endpoint,Types...types)95 DnsSdInstanceEndpoint(std::string instance_id, 96 std::string service_id, 97 std::string domain_id, 98 DnsSdTxtRecord txt, 99 NetworkInterfaceIndex network_interface, 100 std::vector<IPEndpoint> endpoints, 101 std::vector<Subtype> subtypes, 102 IPEndpoint endpoint, 103 Types... types) 104 : DnsSdInstanceEndpoint(std::move(instance_id), 105 std::move(service_id), 106 std::move(domain_id), 107 std::move(txt), 108 network_interface, 109 Append(std::move(endpoints), std::move(endpoint)), 110 std::move(subtypes), 111 std::move(types)...) {} 112 113 // All following arguments must be Subtypes, so pull them all off and recurse 114 // to a non-templated ctor. 115 template <typename... Types> DnsSdInstanceEndpoint(std::string instance_id,std::string service_id,std::string domain_id,DnsSdTxtRecord txt,NetworkInterfaceIndex network_interface,std::vector<IPEndpoint> endpoints,std::vector<Subtype> subtypes,Subtype subtype,Types...types)116 DnsSdInstanceEndpoint(std::string instance_id, 117 std::string service_id, 118 std::string domain_id, 119 DnsSdTxtRecord txt, 120 NetworkInterfaceIndex network_interface, 121 std::vector<IPEndpoint> endpoints, 122 std::vector<Subtype> subtypes, 123 Subtype subtype, 124 Types... types) 125 : DnsSdInstanceEndpoint(std::move(instance_id), 126 std::move(service_id), 127 std::move(domain_id), 128 std::move(txt), 129 network_interface, 130 std::move(endpoints), 131 Append(std::move(subtypes), 132 std::move(subtype), 133 std::move(types)...)) {} 134 135 // Lazy Initializes the |addresses_| vector. 136 const std::vector<IPAddress>& CalculateAddresses() const; 137 138 // Initialized the |endpoints_| vector after construction. 139 void InitializeEndpoints(); 140 141 // NOTE: The below vector is stored in sorted order to make comparison 142 // simpler. 143 std::vector<IPEndpoint> endpoints_; 144 std::vector<IPAddress> addresses_; 145 146 NetworkInterfaceIndex network_interface_; 147 148 friend bool operator<(const DnsSdInstanceEndpoint& lhs, 149 const DnsSdInstanceEndpoint& rhs); 150 }; 151 152 bool operator<(const DnsSdInstanceEndpoint& lhs, 153 const DnsSdInstanceEndpoint& rhs); 154 155 inline bool operator>(const DnsSdInstanceEndpoint& lhs, 156 const DnsSdInstanceEndpoint& rhs) { 157 return rhs < lhs; 158 } 159 160 inline bool operator<=(const DnsSdInstanceEndpoint& lhs, 161 const DnsSdInstanceEndpoint& rhs) { 162 return !(lhs > rhs); 163 } 164 165 inline bool operator>=(const DnsSdInstanceEndpoint& lhs, 166 const DnsSdInstanceEndpoint& rhs) { 167 return !(lhs < rhs); 168 } 169 170 inline bool operator==(const DnsSdInstanceEndpoint& lhs, 171 const DnsSdInstanceEndpoint& rhs) { 172 return lhs <= rhs && lhs >= rhs; 173 } 174 175 inline bool operator!=(const DnsSdInstanceEndpoint& lhs, 176 const DnsSdInstanceEndpoint& rhs) { 177 return !(lhs == rhs); 178 } 179 180 } // namespace discovery 181 } // namespace openscreen 182 183 #endif // DISCOVERY_DNSSD_PUBLIC_DNS_SD_INSTANCE_ENDPOINT_H_ 184