• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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