• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 /**
30  * @file
31  *   This file includes definition for mDNS publisher.
32  */
33 
34 #ifndef OTBR_AGENT_MDNS_MDNSSD_HPP_
35 #define OTBR_AGENT_MDNS_MDNSSD_HPP_
36 
37 #include "openthread-br/config.h"
38 
39 #include <array>
40 #include <map>
41 #include <memory>
42 #include <utility>
43 #include <vector>
44 
45 #include <assert.h>
46 #include <dns_sd.h>
47 
48 #include "common/code_utils.hpp"
49 #include "common/mainloop.hpp"
50 #include "common/types.hpp"
51 #include "mdns/mdns.hpp"
52 
53 namespace otbr {
54 
55 namespace Mdns {
56 
57 /**
58  * This class implements mDNS publisher with mDNSResponder.
59  *
60  */
61 class PublisherMDnsSd : public MainloopProcessor, public Publisher
62 {
63 public:
64     explicit PublisherMDnsSd(StateCallback aCallback);
65 
66     ~PublisherMDnsSd(void) override;
67 
68     // Implementation of Mdns::Publisher.
69 
70     void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override;
71 
72     void      UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override;
73     void      UnpublishKey(const std::string &aName, ResultCallback &&aCallback) override;
74     void      SubscribeService(const std::string &aType, const std::string &aInstanceName) override;
75     void      UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override;
76     void      SubscribeHost(const std::string &aHostName) override;
77     void      UnsubscribeHost(const std::string &aHostName) override;
78     otbrError Start(void) override;
79     bool      IsStarted(void) const override;
Stop(void)80     void      Stop(void) override { Stop(kNormalStop); }
81 
82     // Implementation of MainloopProcessor.
83 
84     void Update(MainloopContext &aMainloop) override;
85     void Process(const MainloopContext &aMainloop) 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 TxtData     &aTxtData,
94                                  ResultCallback   &&aCallback) override;
95     otbrError PublishHostImpl(const std::string &aName,
96                               const AddressList &aAddress,
97                               ResultCallback   &&aCallback) override;
98     otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback) override;
99     void      OnServiceResolveFailedImpl(const std::string &aType,
100                                          const std::string &aInstanceName,
101                                          int32_t            aErrorCode) override;
102     void      OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override;
103     otbrError DnsErrorToOtbrError(int32_t aErrorCode) override;
104 
105 private:
106     static constexpr uint32_t kDefaultTtl = 10;
107 
108     enum StopMode : uint8_t
109     {
110         kNormalStop,
111         kStopOnServiceNotRunningError,
112     };
113 
114     class DnssdKeyRegistration;
115 
116     class DnssdServiceRegistration : public ServiceRegistration
117     {
118         friend class DnssdKeyRegistration;
119 
120     public:
121         using ServiceRegistration::ServiceRegistration; // Inherit base constructor
122 
~DnssdServiceRegistration(void)123         ~DnssdServiceRegistration(void) override { Unregister(); }
124 
125         void      Update(MainloopContext &aMainloop) const;
126         void      Process(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
127         otbrError Register(void);
128 
129     private:
130         void             Unregister(void);
GetPublisher(void)131         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
132         void             HandleRegisterResult(DNSServiceFlags aFlags, DNSServiceErrorType aError);
133         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
134                                               DNSServiceFlags     aFlags,
135                                               DNSServiceErrorType aError,
136                                               const char         *aName,
137                                               const char         *aType,
138                                               const char         *aDomain,
139                                               void               *aContext);
140 
141         DNSServiceRef         mServiceRef    = nullptr;
142         DnssdKeyRegistration *mRelatedKeyReg = nullptr;
143     };
144 
145     class DnssdHostRegistration : public HostRegistration
146     {
147     public:
148         using HostRegistration::HostRegistration; // Inherit base class constructor
149 
~DnssdHostRegistration(void)150         ~DnssdHostRegistration(void) override { Unregister(); }
151 
152         otbrError Register(void);
153 
154     private:
155         void             Unregister(void);
GetPublisher(void)156         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
157         void             HandleRegisterResult(DNSRecordRef aRecordRef, DNSServiceErrorType aError);
158         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
159                                               DNSRecordRef        aRecordRef,
160                                               DNSServiceFlags     aFlags,
161                                               DNSServiceErrorType aErrorCode,
162                                               void               *aContext);
163 
164         std::vector<DNSRecordRef> mAddrRecordRefs;
165         std::vector<bool>         mAddrRegistered;
166     };
167 
168     class DnssdKeyRegistration : public KeyRegistration
169     {
170         friend class DnssdServiceRegistration;
171 
172     public:
173         using KeyRegistration::KeyRegistration; // Inherit base class constructor
174 
~DnssdKeyRegistration(void)175         ~DnssdKeyRegistration(void) override { Unregister(); }
176 
177         otbrError Register(void);
178 
179     private:
180         void             Unregister(void);
GetPublisher(void)181         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
182         void             HandleRegisterResult(DNSServiceErrorType aError);
183         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
184                                               DNSRecordRef        aRecordRef,
185                                               DNSServiceFlags     aFlags,
186                                               DNSServiceErrorType aErrorCode,
187                                               void               *aContext);
188 
189         DNSRecordRef              mRecordRef         = nullptr;
190         DnssdServiceRegistration *mRelatedServiceReg = nullptr;
191     };
192 
193     struct ServiceRef : private ::NonCopyable
194     {
195         DNSServiceRef    mServiceRef;
196         PublisherMDnsSd &mPublisher;
197 
ServiceRefotbr::Mdns::PublisherMDnsSd::ServiceRef198         explicit ServiceRef(PublisherMDnsSd &aPublisher)
199             : mServiceRef(nullptr)
200             , mPublisher(aPublisher)
201         {
202         }
203 
~ServiceRefotbr::Mdns::PublisherMDnsSd::ServiceRef204         ~ServiceRef() { Release(); }
205 
206         void Update(MainloopContext &aMainloop) const;
207         void Process(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
208         void Release(void);
209         void DeallocateServiceRef(void);
210     };
211 
212     struct ServiceSubscription;
213 
214     struct ServiceInstanceResolution : public ServiceRef
215     {
ServiceInstanceResolutionotbr::Mdns::PublisherMDnsSd::ServiceInstanceResolution216         explicit ServiceInstanceResolution(ServiceSubscription &aSubscription,
217                                            std::string          aInstanceName,
218                                            std::string          aType,
219                                            std::string          aDomain,
220                                            uint32_t             aNetifIndex)
221             : ServiceRef(aSubscription.mPublisher)
222             , mSubscription(&aSubscription)
223             , mInstanceName(std::move(aInstanceName))
224             , mType(std::move(aType))
225             , mDomain(std::move(aDomain))
226             , mNetifIndex(aNetifIndex)
227         {
228         }
229 
230         void      Resolve(void);
231         otbrError GetAddrInfo(uint32_t aInterfaceIndex);
232         void      FinishResolution(void);
233 
234         static void HandleResolveResult(DNSServiceRef        aServiceRef,
235                                         DNSServiceFlags      aFlags,
236                                         uint32_t             aInterfaceIndex,
237                                         DNSServiceErrorType  aErrorCode,
238                                         const char          *aFullName,
239                                         const char          *aHostTarget,
240                                         uint16_t             aPort, // In network byte order.
241                                         uint16_t             aTxtLen,
242                                         const unsigned char *aTxtRecord,
243                                         void                *aContext);
244         void        HandleResolveResult(DNSServiceRef        aServiceRef,
245                                         DNSServiceFlags      aFlags,
246                                         uint32_t             aInterfaceIndex,
247                                         DNSServiceErrorType  aErrorCode,
248                                         const char          *aFullName,
249                                         const char          *aHostTarget,
250                                         uint16_t             aPort, // In network byte order.
251                                         uint16_t             aTxtLen,
252                                         const unsigned char *aTxtRecord);
253         static void HandleGetAddrInfoResult(DNSServiceRef          aServiceRef,
254                                             DNSServiceFlags        aFlags,
255                                             uint32_t               aInterfaceIndex,
256                                             DNSServiceErrorType    aErrorCode,
257                                             const char            *aHostName,
258                                             const struct sockaddr *aAddress,
259                                             uint32_t               aTtl,
260                                             void                  *aContext);
261         void        HandleGetAddrInfoResult(DNSServiceRef          aServiceRef,
262                                             DNSServiceFlags        aFlags,
263                                             uint32_t               aInterfaceIndex,
264                                             DNSServiceErrorType    aErrorCode,
265                                             const char            *aHostName,
266                                             const struct sockaddr *aAddress,
267                                             uint32_t               aTtl);
268 
269         ServiceSubscription   *mSubscription;
270         std::string            mInstanceName;
271         std::string            mType;
272         std::string            mDomain;
273         uint32_t               mNetifIndex;
274         DiscoveredInstanceInfo mInstanceInfo;
275     };
276 
277     struct ServiceSubscription : public ServiceRef
278     {
ServiceSubscriptionotbr::Mdns::PublisherMDnsSd::ServiceSubscription279         explicit ServiceSubscription(PublisherMDnsSd &aPublisher, std::string aType, std::string aInstanceName)
280             : ServiceRef(aPublisher)
281             , mType(std::move(aType))
282             , mInstanceName(std::move(aInstanceName))
283         {
284         }
285 
286         void Browse(void);
287         void Resolve(uint32_t           aNetifIndex,
288                      const std::string &aInstanceName,
289                      const std::string &aType,
290                      const std::string &aDomain);
291         void UpdateAll(MainloopContext &aMainloop) const;
292         void ProcessAll(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
293 
294         static void HandleBrowseResult(DNSServiceRef       aServiceRef,
295                                        DNSServiceFlags     aFlags,
296                                        uint32_t            aInterfaceIndex,
297                                        DNSServiceErrorType aErrorCode,
298                                        const char         *aInstanceName,
299                                        const char         *aType,
300                                        const char         *aDomain,
301                                        void               *aContext);
302         void        HandleBrowseResult(DNSServiceRef       aServiceRef,
303                                        DNSServiceFlags     aFlags,
304                                        uint32_t            aInterfaceIndex,
305                                        DNSServiceErrorType aErrorCode,
306                                        const char         *aInstanceName,
307                                        const char         *aType,
308                                        const char         *aDomain);
309 
310         std::string mType;
311         std::string mInstanceName;
312 
313         std::vector<std::unique_ptr<ServiceInstanceResolution>> mResolvingInstances;
314     };
315 
316     struct HostSubscription : public ServiceRef
317     {
HostSubscriptionotbr::Mdns::PublisherMDnsSd::HostSubscription318         explicit HostSubscription(PublisherMDnsSd &aPublisher, std::string aHostName)
319             : ServiceRef(aPublisher)
320             , mHostName(std::move(aHostName))
321         {
322         }
323 
324         void        Resolve(void);
325         static void HandleResolveResult(DNSServiceRef          aServiceRef,
326                                         DNSServiceFlags        aFlags,
327                                         uint32_t               aInterfaceIndex,
328                                         DNSServiceErrorType    aErrorCode,
329                                         const char            *aHostName,
330                                         const struct sockaddr *aAddress,
331                                         uint32_t               aTtl,
332                                         void                  *aContext);
333         void        HandleResolveResult(DNSServiceRef          aServiceRef,
334                                         DNSServiceFlags        aFlags,
335                                         uint32_t               aInterfaceIndex,
336                                         DNSServiceErrorType    aErrorCode,
337                                         const char            *aHostName,
338                                         const struct sockaddr *aAddress,
339                                         uint32_t               aTtl);
340 
341         std::string        mHostName;
342         DiscoveredHostInfo mHostInfo;
343     };
344 
345     using ServiceSubscriptionList = std::vector<std::unique_ptr<ServiceSubscription>>;
346     using HostSubscriptionList    = std::vector<std::unique_ptr<HostSubscription>>;
347 
348     static std::string MakeRegType(const std::string &aType, SubTypeList aSubTypeList);
349 
350     void                Stop(StopMode aStopMode);
351     DNSServiceErrorType CreateSharedHostsRef(void);
352     void                DeallocateHostsRef(void);
353     void                HandleServiceRefDeallocating(const DNSServiceRef &aServiceRef);
354 
355     DNSServiceRef mHostsRef;
356     State         mState;
357     StateCallback mStateCallback;
358 
359     ServiceSubscriptionList mSubscribedServices;
360     HostSubscriptionList    mSubscribedHosts;
361 
362     std::vector<DNSServiceRef> mServiceRefsToProcess;
363 };
364 
365 /**
366  * @}
367  */
368 
369 } // namespace Mdns
370 
371 } // namespace otbr
372 
373 #endif // OTBR_AGENT_MDNS_MDNSSD_HPP_
374