openthread-br  0.3.0-72c0388
mdns_avahi.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, 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_AVAHI_HPP_
35 #define OTBR_AGENT_MDNS_AVAHI_HPP_
36 
37 #include <memory>
38 #include <set>
39 #include <vector>
40 
41 #include <avahi-client/client.h>
42 #include <avahi-client/lookup.h>
43 #include <avahi-client/publish.h>
44 #include <avahi-common/domain.h>
45 #include <avahi-common/watch.h>
46 
47 #include "mdns.hpp"
48 #include "common/code_utils.hpp"
49 #include "common/mainloop.hpp"
50 #include "common/time.hpp"
51 
61 namespace otbr {
62 
63 namespace Mdns {
64 
65 class AvahiPoller;
66 
71 class PublisherAvahi : public Publisher
72 {
73 public:
74  PublisherAvahi(StateCallback aStateCallback);
75  ~PublisherAvahi(void) override;
76 
77  void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override;
78  void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override;
79  void SubscribeService(const std::string &aType, const std::string &aInstanceName) override;
80  void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override;
81  void SubscribeHost(const std::string &aHostName) override;
82  void UnsubscribeHost(const std::string &aHostName) override;
83  otbrError Start(void) override;
84  bool IsStarted(void) const override;
85  void Stop(void) override;
86 
87 protected:
88  otbrError PublishServiceImpl(const std::string &aHostName,
89  const std::string &aName,
90  const std::string &aType,
91  const SubTypeList &aSubTypeList,
92  uint16_t aPort,
93  const TxtList & aTxtList,
94  ResultCallback && aCallback) override;
95  otbrError PublishHostImpl(const std::string & aName,
96  const std::vector<Ip6Address> &aAddresses,
97  ResultCallback && aCallback) override;
98  void OnServiceResolveFailedImpl(const std::string &aType,
99  const std::string &aInstanceName,
100  int32_t aErrorCode) override;
101  void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override;
102  otbrError DnsErrorToOtbrError(int32_t aErrorCode) override;
103 
104 private:
105  static constexpr size_t kMaxSizeOfTxtRecord = 1024;
106  static constexpr uint32_t kDefaultTtl = 10; // In seconds.
107 
108  class AvahiServiceRegistration : public ServiceRegistration
109  {
110  public:
111  AvahiServiceRegistration(const std::string &aHostName,
112  const std::string &aName,
113  const std::string &aType,
114  const SubTypeList &aSubTypeList,
115  uint16_t aPort,
116  const TxtList & aTxtList,
117  ResultCallback && aCallback,
118  AvahiEntryGroup * aEntryGroup,
119  PublisherAvahi * aPublisher)
120  : ServiceRegistration(aHostName,
121  aName,
122  aType,
123  aSubTypeList,
124  aPort,
125  aTxtList,
126  std::move(aCallback),
127  aPublisher)
128  , mEntryGroup(aEntryGroup)
129  {
130  }
131 
132  ~AvahiServiceRegistration(void) override;
133  const AvahiEntryGroup *GetEntryGroup(void) const { return mEntryGroup; }
134 
135  private:
136  AvahiEntryGroup *mEntryGroup;
137  };
138 
139  class AvahiHostRegistration : public HostRegistration
140  {
141  public:
142  AvahiHostRegistration(const std::string & aName,
143  const std::vector<Ip6Address> &aAddresses,
144  ResultCallback && aCallback,
145  AvahiEntryGroup * aEntryGroup,
146  PublisherAvahi * aPublisher)
147  : HostRegistration(aName, aAddresses, std::move(aCallback), aPublisher)
148  , mEntryGroup(aEntryGroup)
149  {
150  }
151 
152  ~AvahiHostRegistration(void) override;
153  const AvahiEntryGroup *GetEntryGroup(void) const { return mEntryGroup; }
154 
155  private:
156  AvahiEntryGroup *mEntryGroup;
157  };
158 
159  struct Subscription : private ::NonCopyable
160  {
161  PublisherAvahi *mPublisherAvahi;
162 
163  explicit Subscription(PublisherAvahi &aPublisherAvahi)
164  : mPublisherAvahi(&aPublisherAvahi)
165  {
166  }
167  };
168 
169  struct ServiceSubscription : public Subscription
170  {
171  explicit ServiceSubscription(PublisherAvahi &aPublisherAvahi, std::string aType, std::string aInstanceName)
172  : Subscription(aPublisherAvahi)
173  , mType(std::move(aType))
174  , mInstanceName(std::move(aInstanceName))
175  , mServiceBrowser(nullptr)
176  {
177  }
178 
179  ~ServiceSubscription() { Release(); }
180 
181  void Release(void);
182  void Browse(void);
183  void Resolve(uint32_t aInterfaceIndex,
184  AvahiProtocol aProtocol,
185  const std::string &aInstanceName,
186  const std::string &aType);
187  void AddServiceResolver(AvahiServiceResolver *aServiceResolver);
188  void RemoveServiceResolver(AvahiServiceResolver *aServiceResolver);
189 
190  static void HandleBrowseResult(AvahiServiceBrowser * aServiceBrowser,
191  AvahiIfIndex aInterfaceIndex,
192  AvahiProtocol aProtocol,
193  AvahiBrowserEvent aEvent,
194  const char * aName,
195  const char * aType,
196  const char * aDomain,
197  AvahiLookupResultFlags aFlags,
198  void * aContext);
199 
200  void HandleBrowseResult(AvahiServiceBrowser * aServiceBrowser,
201  AvahiIfIndex aInterfaceIndex,
202  AvahiProtocol aProtocol,
203  AvahiBrowserEvent aEvent,
204  const char * aName,
205  const char * aType,
206  const char * aDomain,
207  AvahiLookupResultFlags aFlags);
208 
209  static void HandleResolveResult(AvahiServiceResolver * aServiceResolver,
210  AvahiIfIndex aInterfaceIndex,
211  AvahiProtocol Protocol,
212  AvahiResolverEvent aEvent,
213  const char * aName,
214  const char * aType,
215  const char * aDomain,
216  const char * aHostName,
217  const AvahiAddress * aAddress,
218  uint16_t aPort,
219  AvahiStringList * aTxt,
220  AvahiLookupResultFlags aFlags,
221  void * aContext);
222 
223  void HandleResolveResult(AvahiServiceResolver * aServiceResolver,
224  AvahiIfIndex aInterfaceIndex,
225  AvahiProtocol Protocol,
226  AvahiResolverEvent aEvent,
227  const char * aName,
228  const char * aType,
229  const char * aDomain,
230  const char * aHostName,
231  const AvahiAddress * aAddress,
232  uint16_t aPort,
233  AvahiStringList * aTxt,
234  AvahiLookupResultFlags aFlags);
235 
236  std::string mType;
237  std::string mInstanceName;
238  AvahiServiceBrowser * mServiceBrowser;
239  std::set<AvahiServiceResolver *> mServiceResolvers;
240  };
241 
242  struct HostSubscription : public Subscription
243  {
244  explicit HostSubscription(PublisherAvahi &aAvahiPublisher, std::string aHostName)
245  : Subscription(aAvahiPublisher)
246  , mHostName(std::move(aHostName))
247  , mRecordBrowser(nullptr)
248  {
249  }
250 
251  ~HostSubscription() { Release(); }
252 
253  void Release(void);
254  void Resolve(void);
255  static void HandleResolveResult(AvahiRecordBrowser * aRecordBrowser,
256  AvahiIfIndex aInterfaceIndex,
257  AvahiProtocol aProtocol,
258  AvahiBrowserEvent aEvent,
259  const char * aName,
260  uint16_t aClazz,
261  uint16_t aType,
262  const void * aRdata,
263  size_t aSize,
264  AvahiLookupResultFlags aFlags,
265  void * aContext);
266 
267  void HandleResolveResult(AvahiRecordBrowser * aRecordBrowser,
268  AvahiIfIndex aInterfaceIndex,
269  AvahiProtocol aProtocol,
270  AvahiBrowserEvent aEvent,
271  const char * aName,
272  uint16_t aClazz,
273  uint16_t aType,
274  const void * aRdata,
275  size_t aSize,
276  AvahiLookupResultFlags aFlags);
277 
278  std::string mHostName;
279  DiscoveredHostInfo mHostInfo;
280  AvahiRecordBrowser *mRecordBrowser;
281  };
282 
283  typedef std::vector<std::unique_ptr<ServiceSubscription>> ServiceSubscriptionList;
284  typedef std::vector<std::unique_ptr<HostSubscription>> HostSubscriptionList;
285 
286  static void HandleClientState(AvahiClient *aClient, AvahiClientState aState, void *aContext);
287  void HandleClientState(AvahiClient *aClient, AvahiClientState aState);
288 
289  AvahiEntryGroup *CreateGroup(AvahiClient *aClient);
290  static void ReleaseGroup(AvahiEntryGroup *aGroup);
291 
292  static void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState, void *aContext);
293  void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState);
294  void CallHostOrServiceCallback(AvahiEntryGroup *aGroup, otbrError aError);
295 
296  static otbrError TxtListToAvahiStringList(const TxtList & aTxtList,
297  AvahiStringList * aBuffer,
298  size_t aBufferSize,
299  AvahiStringList *&aHead);
300 
301  ServiceRegistration *FindServiceRegistration(const AvahiEntryGroup *aEntryGroup);
302  HostRegistration * FindHostRegistration(const AvahiEntryGroup *aEntryGroup);
303 
304  AvahiClient * mClient;
305  std::unique_ptr<AvahiPoller> mPoller;
306  State mState;
307  StateCallback mStateCallback;
308 
309  ServiceSubscriptionList mSubscribedServices;
310  HostSubscriptionList mSubscribedHosts;
311 };
312 
313 } // namespace Mdns
314 
315 } // namespace otbr
316 
320 #endif // OTBR_AGENT_MDNS_AVAHI_HPP_
mainloop.hpp
otbr::Mdns::PublisherAvahi::Start
otbrError Start(void) override
Definition: mdns_avahi.cpp:443
otbr::Mdns::PublisherAvahi::SubscribeService
void SubscribeService(const std::string &aType, const std::string &aInstanceName) override
Definition: mdns_avahi.cpp:861
otbr::Mdns::PublisherAvahi::UnpublishHost
void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override
Definition: mdns_avahi.cpp:777
otbr::Mdns::PublisherAvahi::UnpublishService
void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override
Definition: mdns_avahi.cpp:711
otbr::Mdns::PublisherAvahi::UnsubscribeService
void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override
Definition: mdns_avahi.cpp:884
otbr::Mdns::Publisher::HostRegistration
Definition: mdns.hpp:457
otbr::Mdns::Publisher::ServiceRegistration
Definition: mdns.hpp:415
code_utils.hpp
otbr::Mdns::Publisher::State
State
Definition: mdns.hpp:149
otbr::Mdns::Publisher::DiscoveredHostInfo
Definition: mdns.hpp:124
otbr::Mdns::PublisherAvahi::Stop
void Stop(void) override
Definition: mdns_avahi.cpp:466
otbr::Mdns::Publisher::StateCallback
std::function< void(State aNewState)> StateCallback
Definition: mdns.hpp:156
otbr::Mdns::Publisher
Definition: mdns.hpp:67
otbr::Mdns::PublisherAvahi::UnsubscribeHost
void UnsubscribeHost(const std::string &aHostName) override
Definition: mdns_avahi.cpp:944
otbrError
otbrError
Definition: types.hpp:70
otbr::Mdns::PublisherAvahi::SubscribeHost
void SubscribeHost(const std::string &aHostName) override
Definition: mdns_avahi.cpp:928
otbr::Mdns::PublisherAvahi
Definition: mdns_avahi.hpp:71
mdns.hpp
otbr::Mdns::PublisherAvahi::IsStarted
bool IsStarted(void) const override
Definition: mdns_avahi.cpp:461
time.hpp
otbr::OnceCallback< void(otbrError aError)>
NonCopyable
Definition: code_utils.hpp:169