openthread-br  0.3.0-72c0388
mdns_mdnssd.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, The OpenThread Authors.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
34 #ifndef OTBR_AGENT_MDNS_MDNSSD_HPP_
35 #define OTBR_AGENT_MDNS_MDNSSD_HPP_
36 
37 #include <array>
38 #include <map>
39 #include <memory>
40 #include <utility>
41 #include <vector>
42 
43 #include <assert.h>
44 #include <dns_sd.h>
45 
46 #include "common/code_utils.hpp"
47 #include "common/mainloop.hpp"
48 #include "common/types.hpp"
49 #include "mdns/mdns.hpp"
50 
51 namespace otbr {
52 
53 namespace Mdns {
54 
60 {
61 public:
62  explicit PublisherMDnsSd(StateCallback aCallback);
63 
64  ~PublisherMDnsSd(void) override;
65 
66  // Implementation of Mdns::Publisher.
67 
68  void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override;
69 
70  void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override;
71  void SubscribeService(const std::string &aType, const std::string &aInstanceName) override;
72  void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override;
73  void SubscribeHost(const std::string &aHostName) override;
74  void UnsubscribeHost(const std::string &aHostName) override;
75  otbrError Start(void) override;
76  bool IsStarted(void) const override;
77  void Stop(void) override;
78 
79  // Implementation of MainloopProcessor.
80 
81  void Update(MainloopContext &aMainloop) override;
82  void Process(const MainloopContext &aMainloop) override;
83 
84 protected:
85  otbrError PublishServiceImpl(const std::string &aHostName,
86  const std::string &aName,
87  const std::string &aType,
88  const SubTypeList &aSubTypeList,
89  uint16_t aPort,
90  const TxtList & aTxtList,
91  ResultCallback && aCallback) override;
92  otbrError PublishHostImpl(const std::string & aName,
93  const std::vector<Ip6Address> &aAddress,
94  ResultCallback && aCallback) override;
95  void OnServiceResolveFailedImpl(const std::string &aType,
96  const std::string &aInstanceName,
97  int32_t aErrorCode) override;
98  void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override;
99  otbrError DnsErrorToOtbrError(int32_t aErrorCode) override;
100 
101 private:
102  static constexpr uint32_t kDefaultTtl = 10;
103 
104  class DnssdServiceRegistration : public ServiceRegistration
105  {
106  public:
107  DnssdServiceRegistration(const std::string &aHostName,
108  const std::string &aName,
109  const std::string &aType,
110  const SubTypeList &aSubTypeList,
111  uint16_t aPort,
112  const TxtList & aTxtList,
113  ResultCallback && aCallback,
114  DNSServiceRef aServiceRef,
115  PublisherMDnsSd * aPublisher)
116  : ServiceRegistration(aHostName,
117  aName,
118  aType,
119  aSubTypeList,
120  aPort,
121  aTxtList,
122  std::move(aCallback),
123  aPublisher)
124  , mServiceRef(aServiceRef)
125  {
126  }
127 
128  ~DnssdServiceRegistration(void) override;
129  const DNSServiceRef &GetServiceRef() const { return mServiceRef; }
130 
131  private:
132  DNSServiceRef mServiceRef;
133  };
134 
135  class DnssdHostRegistration : public HostRegistration
136  {
137  public:
138  DnssdHostRegistration(const std::string & aName,
139  const std::vector<Ip6Address> &aAddresses,
140  ResultCallback && aCallback,
141  DNSServiceRef aServiceRef,
142  Publisher * aPublisher)
143  : HostRegistration(aName, aAddresses, std::move(aCallback), aPublisher)
144  , mServiceRef(aServiceRef)
145  , mRecordRefMap()
146  , mCallbackCount(aAddresses.size())
147  {
148  }
149 
150  ~DnssdHostRegistration(void) override;
151  const DNSServiceRef & GetServiceRef() const { return mServiceRef; }
152  const std::map<DNSRecordRef, Ip6Address> &GetRecordRefMap() const { return mRecordRefMap; }
153  std::map<DNSRecordRef, Ip6Address> & GetRecordRefMap() { return mRecordRefMap; }
154 
155  private:
156  DNSServiceRef mServiceRef;
157 
158  public:
159  std::map<DNSRecordRef, Ip6Address> mRecordRefMap;
160  uint32_t mCallbackCount;
161  };
162 
163  struct ServiceRef : private ::NonCopyable
164  {
165  DNSServiceRef mServiceRef;
166 
167  explicit ServiceRef(void)
168  : mServiceRef(nullptr)
169  {
170  }
171 
172  ~ServiceRef() { Release(); }
173 
174  void Update(MainloopContext &aMainloop) const;
175  void Process(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
176  void Release(void);
177  void DeallocateServiceRef(void);
178  };
179 
180  struct ServiceSubscription;
181 
182  struct ServiceInstanceResolution : public ServiceRef
183  {
184  explicit ServiceInstanceResolution(ServiceSubscription &aSubscription,
185  std::string aInstanceName,
186  std::string aType,
187  std::string aDomain,
188  uint32_t aNetifIndex)
189  : ServiceRef()
190  , mSubscription(&aSubscription)
191  , mInstanceName(std::move(aInstanceName))
192  , mTypeEndWithDot(std::move(aType))
193  , mDomain(std::move(aDomain))
194  , mNetifIndex(aNetifIndex)
195  {
196  }
197 
198  void Resolve(void);
199  otbrError GetAddrInfo(uint32_t aInterfaceIndex);
200  void FinishResolution(void);
201 
202  static void HandleResolveResult(DNSServiceRef aServiceRef,
203  DNSServiceFlags aFlags,
204  uint32_t aInterfaceIndex,
205  DNSServiceErrorType aErrorCode,
206  const char * aFullName,
207  const char * aHostTarget,
208  uint16_t aPort, // In network byte order.
209  uint16_t aTxtLen,
210  const unsigned char *aTxtRecord,
211  void * aContext);
212  void HandleResolveResult(DNSServiceRef aServiceRef,
213  DNSServiceFlags aFlags,
214  uint32_t aInterfaceIndex,
215  DNSServiceErrorType aErrorCode,
216  const char * aFullName,
217  const char * aHostTarget,
218  uint16_t aPort, // In network byte order.
219  uint16_t aTxtLen,
220  const unsigned char *aTxtRecord);
221  static void HandleGetAddrInfoResult(DNSServiceRef aServiceRef,
222  DNSServiceFlags aFlags,
223  uint32_t aInterfaceIndex,
224  DNSServiceErrorType aErrorCode,
225  const char * aHostName,
226  const struct sockaddr *aAddress,
227  uint32_t aTtl,
228  void * aContext);
229  void HandleGetAddrInfoResult(DNSServiceRef aServiceRef,
230  DNSServiceFlags aFlags,
231  uint32_t aInterfaceIndex,
232  DNSServiceErrorType aErrorCode,
233  const char * aHostName,
234  const struct sockaddr *aAddress,
235  uint32_t aTtl);
236 
237  ServiceSubscription * mSubscription;
238  std::string mInstanceName;
239  std::string mTypeEndWithDot;
240  std::string mDomain;
241  uint32_t mNetifIndex;
242  DiscoveredInstanceInfo mInstanceInfo;
243  };
244 
245  struct ServiceSubscription : public ServiceRef
246  {
247  explicit ServiceSubscription(PublisherMDnsSd &aMDnsSd, std::string aType, std::string aInstanceName)
248  : ServiceRef()
249  , mMDnsSd(&aMDnsSd)
250  , mType(std::move(aType))
251  , mInstanceName(std::move(aInstanceName))
252  {
253  }
254 
255  void Browse(void);
256  void Resolve(uint32_t aNetifIndex,
257  const std::string &aInstanceName,
258  const std::string &aType,
259  const std::string &aDomain);
260  void RemoveInstanceResolution(ServiceInstanceResolution &aInstanceResolution);
261  void UpdateAll(MainloopContext &aMainloop) const;
262  void ProcessAll(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
263 
264  static void HandleBrowseResult(DNSServiceRef aServiceRef,
265  DNSServiceFlags aFlags,
266  uint32_t aInterfaceIndex,
267  DNSServiceErrorType aErrorCode,
268  const char * aInstanceName,
269  const char * aType,
270  const char * aDomain,
271  void * aContext);
272  void HandleBrowseResult(DNSServiceRef aServiceRef,
273  DNSServiceFlags aFlags,
274  uint32_t aInterfaceIndex,
275  DNSServiceErrorType aErrorCode,
276  const char * aInstanceName,
277  const char * aType,
278  const char * aDomain);
279 
280  PublisherMDnsSd *mMDnsSd;
281  std::string mType;
282  std::string mInstanceName;
283 
284  std::vector<std::unique_ptr<ServiceInstanceResolution>> mResolvingInstances;
285  };
286 
287  struct HostSubscription : public ServiceRef
288  {
289  explicit HostSubscription(PublisherMDnsSd &aMDnsSd, std::string aHostName)
290  : ServiceRef()
291  , mMDnsSd(&aMDnsSd)
292  , mHostName(std::move(aHostName))
293  {
294  }
295 
296  void Resolve(void);
297  static void HandleResolveResult(DNSServiceRef aServiceRef,
298  DNSServiceFlags aFlags,
299  uint32_t aInterfaceIndex,
300  DNSServiceErrorType aErrorCode,
301  const char * aHostName,
302  const struct sockaddr *aAddress,
303  uint32_t aTtl,
304  void * aContext);
305  void HandleResolveResult(DNSServiceRef aServiceRef,
306  DNSServiceFlags aFlags,
307  uint32_t aInterfaceIndex,
308  DNSServiceErrorType aErrorCode,
309  const char * aHostName,
310  const struct sockaddr *aAddress,
311  uint32_t aTtl);
312 
313  PublisherMDnsSd * mMDnsSd;
314  std::string mHostName;
315  DiscoveredHostInfo mHostInfo;
316  };
317 
318  using ServiceSubscriptionList = std::vector<std::unique_ptr<ServiceSubscription>>;
319  using HostSubscriptionList = std::vector<std::unique_ptr<HostSubscription>>;
320 
321  static void HandleServiceRegisterResult(DNSServiceRef aService,
322  const DNSServiceFlags aFlags,
323  DNSServiceErrorType aError,
324  const char * aName,
325  const char * aType,
326  const char * aDomain,
327  void * aContext);
328  void HandleServiceRegisterResult(DNSServiceRef aService,
329  const DNSServiceFlags aFlags,
330  DNSServiceErrorType aError,
331  const char * aName,
332  const char * aType,
333  const char * aDomain);
334  static void HandleRegisterHostResult(DNSServiceRef aHostsConnection,
335  DNSRecordRef aHostRecord,
336  DNSServiceFlags aFlags,
337  DNSServiceErrorType aErrorCode,
338  void * aContext);
339  void HandleRegisterHostResult(DNSServiceRef aHostsConnection,
340  DNSRecordRef aHostRecord,
341  DNSServiceFlags aFlags,
342  DNSServiceErrorType aErrorCode);
343 
344  static std::string MakeRegType(const std::string &aType, SubTypeList aSubTypeList);
345 
346  ServiceRegistration *FindServiceRegistration(const DNSServiceRef &aServiceRef);
347  HostRegistration * FindHostRegistration(const DNSServiceRef &aServiceRef, const DNSRecordRef &aRecordRef);
348 
349  DNSServiceRef mHostsRef;
350  State mState;
351  StateCallback mStateCallback;
352 
353  ServiceSubscriptionList mSubscribedServices;
354  HostSubscriptionList mSubscribedHosts;
355 };
356 
361 } // namespace Mdns
362 
363 } // namespace otbr
364 
365 #endif // OTBR_AGENT_MDNS_MDNSSD_HPP_
otbr::Mdns::PublisherMDnsSd::UnpublishService
void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override
Definition: mdns_mdnssd.cpp:544
mainloop.hpp
otbr::Mdns::Publisher::DiscoveredInstanceInfo
Definition: mdns.hpp:106
otbr::Mdns::PublisherMDnsSd::Start
otbrError Start(void) override
Definition: mdns_mdnssd.cpp:228
otbr::Mdns::PublisherMDnsSd::Process
void Process(const MainloopContext &aMainloop) override
Definition: mdns_mdnssd.cpp:306
otbr::Mdns::PublisherMDnsSd::Update
void Update(MainloopContext &aMainloop) override
Definition: mdns_mdnssd.cpp:267
otbr::Mdns::PublisherMDnsSd::UnsubscribeService
void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override
Definition: mdns_mdnssd.cpp:705
otbr::Mdns::Publisher::HostRegistration
Definition: mdns.hpp:457
otbr::MainloopProcessor
Definition: mainloop.hpp:54
otbr::Mdns::Publisher::ServiceRegistration
Definition: mdns.hpp:415
code_utils.hpp
otbr::Mdns::PublisherMDnsSd::SubscribeHost
void SubscribeHost(const std::string &aHostName) override
Definition: mdns_mdnssd.cpp:742
otbr::Mdns::Publisher::State
State
Definition: mdns.hpp:149
otbr::Mdns::PublisherMDnsSd::IsStarted
bool IsStarted(void) const override
Definition: mdns_mdnssd.cpp:235
otbr::Mdns::Publisher::DiscoveredHostInfo
Definition: mdns.hpp:124
otbr::Mdns::PublisherMDnsSd::Stop
void Stop(void) override
Definition: mdns_mdnssd.cpp:240
otbr::Mdns::Publisher::StateCallback
std::function< void(State aNewState)> StateCallback
Definition: mdns.hpp:156
otbr::Mdns::Publisher
Definition: mdns.hpp:67
otbrError
otbrError
Definition: types.hpp:70
otbr::Mdns::PublisherMDnsSd
Definition: mdns_mdnssd.hpp:59
mdns.hpp
otbr::Mdns::PublisherMDnsSd::UnpublishHost
void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override
Definition: mdns_mdnssd.cpp:609
otbr::Mdns::PublisherMDnsSd::UnsubscribeHost
void UnsubscribeHost(const std::string &aHostName) override
Definition: mdns_mdnssd.cpp:755
otbr::MainloopContext
otSysMainloopContext MainloopContext
Definition: mainloop.hpp:47
otbr::OnceCallback< void(otbrError aError)>
NonCopyable
Definition: code_utils.hpp:169
otbr::Mdns::PublisherMDnsSd::SubscribeService
void SubscribeService(const std::string &aType, const std::string &aInstanceName) override
Definition: mdns_mdnssd.cpp:684