xref: /aosp_15_r20/external/ot-br-posix/src/mdns/mdns_mdnssd.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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 class PublisherMDnsSd : public MainloopProcessor, public Publisher
61 {
62 public:
63     explicit PublisherMDnsSd(StateCallback aCallback);
64 
65     ~PublisherMDnsSd(void) override;
66 
67     // Implementation of Mdns::Publisher.
68 
69     void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override;
70 
71     void      UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override;
72     void      UnpublishKey(const std::string &aName, ResultCallback &&aCallback) override;
73     void      SubscribeService(const std::string &aType, const std::string &aInstanceName) override;
74     void      UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override;
75     void      SubscribeHost(const std::string &aHostName) override;
76     void      UnsubscribeHost(const std::string &aHostName) override;
77     otbrError Start(void) override;
78     bool      IsStarted(void) const override;
Stop(void)79     void      Stop(void) override { Stop(kNormalStop); }
80 
81     // Implementation of MainloopProcessor.
82 
83     void Update(MainloopContext &aMainloop) override;
84     void Process(const MainloopContext &aMainloop) override;
85 
86 protected:
87     otbrError PublishServiceImpl(const std::string &aHostName,
88                                  const std::string &aName,
89                                  const std::string &aType,
90                                  const SubTypeList &aSubTypeList,
91                                  uint16_t           aPort,
92                                  const TxtData     &aTxtData,
93                                  ResultCallback   &&aCallback) override;
94     otbrError PublishHostImpl(const std::string &aName,
95                               const AddressList &aAddress,
96                               ResultCallback   &&aCallback) override;
97     otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, 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 uint32_t kDefaultTtl = 10;
106 
107     enum StopMode : uint8_t
108     {
109         kNormalStop,
110         kStopOnServiceNotRunningError,
111     };
112 
113     class DnssdKeyRegistration;
114 
115     class DnssdServiceRegistration : public ServiceRegistration
116     {
117         friend class DnssdKeyRegistration;
118 
119     public:
120         using ServiceRegistration::ServiceRegistration; // Inherit base constructor
121 
~DnssdServiceRegistration(void)122         ~DnssdServiceRegistration(void) override { Unregister(); }
123 
124         void      Update(MainloopContext &aMainloop) const;
125         void      Process(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
126         otbrError Register(void);
127 
128     private:
129         void             Unregister(void);
GetPublisher(void)130         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
131         void             HandleRegisterResult(DNSServiceFlags aFlags, DNSServiceErrorType aError);
132         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
133                                               DNSServiceFlags     aFlags,
134                                               DNSServiceErrorType aError,
135                                               const char         *aName,
136                                               const char         *aType,
137                                               const char         *aDomain,
138                                               void               *aContext);
139 
140         DNSServiceRef         mServiceRef    = nullptr;
141         DnssdKeyRegistration *mRelatedKeyReg = nullptr;
142     };
143 
144     class DnssdHostRegistration : public HostRegistration
145     {
146     public:
147         using HostRegistration::HostRegistration; // Inherit base class constructor
148 
~DnssdHostRegistration(void)149         ~DnssdHostRegistration(void) override { Unregister(); }
150 
151         otbrError Register(void);
152 
153     private:
154         void             Unregister(void);
GetPublisher(void)155         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
156         void             HandleRegisterResult(DNSRecordRef aRecordRef, DNSServiceErrorType aError);
157         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
158                                               DNSRecordRef        aRecordRef,
159                                               DNSServiceFlags     aFlags,
160                                               DNSServiceErrorType aErrorCode,
161                                               void               *aContext);
162 
163         std::vector<DNSRecordRef> mAddrRecordRefs;
164         std::vector<bool>         mAddrRegistered;
165     };
166 
167     class DnssdKeyRegistration : public KeyRegistration
168     {
169         friend class DnssdServiceRegistration;
170 
171     public:
172         using KeyRegistration::KeyRegistration; // Inherit base class constructor
173 
~DnssdKeyRegistration(void)174         ~DnssdKeyRegistration(void) override { Unregister(); }
175 
176         otbrError Register(void);
177 
178     private:
179         void             Unregister(void);
GetPublisher(void)180         PublisherMDnsSd &GetPublisher(void) { return *static_cast<PublisherMDnsSd *>(mPublisher); }
181         void             HandleRegisterResult(DNSServiceErrorType aError);
182         static void      HandleRegisterResult(DNSServiceRef       aServiceRef,
183                                               DNSRecordRef        aRecordRef,
184                                               DNSServiceFlags     aFlags,
185                                               DNSServiceErrorType aErrorCode,
186                                               void               *aContext);
187 
188         DNSRecordRef              mRecordRef         = nullptr;
189         DnssdServiceRegistration *mRelatedServiceReg = nullptr;
190     };
191 
192     struct ServiceRef : private ::NonCopyable
193     {
194         DNSServiceRef    mServiceRef;
195         PublisherMDnsSd &mPublisher;
196 
ServiceRefotbr::Mdns::PublisherMDnsSd::ServiceRef197         explicit ServiceRef(PublisherMDnsSd &aPublisher)
198             : mServiceRef(nullptr)
199             , mPublisher(aPublisher)
200         {
201         }
202 
~ServiceRefotbr::Mdns::PublisherMDnsSd::ServiceRef203         ~ServiceRef() { Release(); }
204 
205         void Update(MainloopContext &aMainloop) const;
206         void Process(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
207         void Release(void);
208         void DeallocateServiceRef(void);
209     };
210 
211     struct ServiceSubscription;
212 
213     struct ServiceInstanceResolution : public ServiceRef
214     {
ServiceInstanceResolutionotbr::Mdns::PublisherMDnsSd::ServiceInstanceResolution215         explicit ServiceInstanceResolution(ServiceSubscription &aSubscription,
216                                            std::string          aInstanceName,
217                                            std::string          aType,
218                                            std::string          aDomain,
219                                            uint32_t             aNetifIndex)
220             : ServiceRef(aSubscription.mPublisher)
221             , mSubscription(&aSubscription)
222             , mInstanceName(std::move(aInstanceName))
223             , mType(std::move(aType))
224             , mDomain(std::move(aDomain))
225             , mNetifIndex(aNetifIndex)
226         {
227         }
228 
229         void      Resolve(void);
230         otbrError GetAddrInfo(uint32_t aInterfaceIndex);
231         void      FinishResolution(void);
232 
233         static void HandleResolveResult(DNSServiceRef        aServiceRef,
234                                         DNSServiceFlags      aFlags,
235                                         uint32_t             aInterfaceIndex,
236                                         DNSServiceErrorType  aErrorCode,
237                                         const char          *aFullName,
238                                         const char          *aHostTarget,
239                                         uint16_t             aPort, // In network byte order.
240                                         uint16_t             aTxtLen,
241                                         const unsigned char *aTxtRecord,
242                                         void                *aContext);
243         void        HandleResolveResult(DNSServiceRef        aServiceRef,
244                                         DNSServiceFlags      aFlags,
245                                         uint32_t             aInterfaceIndex,
246                                         DNSServiceErrorType  aErrorCode,
247                                         const char          *aFullName,
248                                         const char          *aHostTarget,
249                                         uint16_t             aPort, // In network byte order.
250                                         uint16_t             aTxtLen,
251                                         const unsigned char *aTxtRecord);
252         static void HandleGetAddrInfoResult(DNSServiceRef          aServiceRef,
253                                             DNSServiceFlags        aFlags,
254                                             uint32_t               aInterfaceIndex,
255                                             DNSServiceErrorType    aErrorCode,
256                                             const char            *aHostName,
257                                             const struct sockaddr *aAddress,
258                                             uint32_t               aTtl,
259                                             void                  *aContext);
260         void        HandleGetAddrInfoResult(DNSServiceRef          aServiceRef,
261                                             DNSServiceFlags        aFlags,
262                                             uint32_t               aInterfaceIndex,
263                                             DNSServiceErrorType    aErrorCode,
264                                             const char            *aHostName,
265                                             const struct sockaddr *aAddress,
266                                             uint32_t               aTtl);
267 
268         ServiceSubscription   *mSubscription;
269         std::string            mInstanceName;
270         std::string            mType;
271         std::string            mDomain;
272         uint32_t               mNetifIndex;
273         DiscoveredInstanceInfo mInstanceInfo;
274     };
275 
276     struct ServiceSubscription : public ServiceRef
277     {
ServiceSubscriptionotbr::Mdns::PublisherMDnsSd::ServiceSubscription278         explicit ServiceSubscription(PublisherMDnsSd &aPublisher, std::string aType, std::string aInstanceName)
279             : ServiceRef(aPublisher)
280             , mType(std::move(aType))
281             , mInstanceName(std::move(aInstanceName))
282         {
283         }
284 
285         void Browse(void);
286         void Resolve(uint32_t           aNetifIndex,
287                      const std::string &aInstanceName,
288                      const std::string &aType,
289                      const std::string &aDomain);
290         void UpdateAll(MainloopContext &aMainloop) const;
291         void ProcessAll(const MainloopContext &aMainloop, std::vector<DNSServiceRef> &aReadyServices) const;
292 
293         static void HandleBrowseResult(DNSServiceRef       aServiceRef,
294                                        DNSServiceFlags     aFlags,
295                                        uint32_t            aInterfaceIndex,
296                                        DNSServiceErrorType aErrorCode,
297                                        const char         *aInstanceName,
298                                        const char         *aType,
299                                        const char         *aDomain,
300                                        void               *aContext);
301         void        HandleBrowseResult(DNSServiceRef       aServiceRef,
302                                        DNSServiceFlags     aFlags,
303                                        uint32_t            aInterfaceIndex,
304                                        DNSServiceErrorType aErrorCode,
305                                        const char         *aInstanceName,
306                                        const char         *aType,
307                                        const char         *aDomain);
308 
309         std::string mType;
310         std::string mInstanceName;
311 
312         std::vector<std::unique_ptr<ServiceInstanceResolution>> mResolvingInstances;
313     };
314 
315     struct HostSubscription : public ServiceRef
316     {
HostSubscriptionotbr::Mdns::PublisherMDnsSd::HostSubscription317         explicit HostSubscription(PublisherMDnsSd &aPublisher, std::string aHostName)
318             : ServiceRef(aPublisher)
319             , mHostName(std::move(aHostName))
320         {
321         }
322 
323         void        Resolve(void);
324         static void HandleResolveResult(DNSServiceRef          aServiceRef,
325                                         DNSServiceFlags        aFlags,
326                                         uint32_t               aInterfaceIndex,
327                                         DNSServiceErrorType    aErrorCode,
328                                         const char            *aHostName,
329                                         const struct sockaddr *aAddress,
330                                         uint32_t               aTtl,
331                                         void                  *aContext);
332         void        HandleResolveResult(DNSServiceRef          aServiceRef,
333                                         DNSServiceFlags        aFlags,
334                                         uint32_t               aInterfaceIndex,
335                                         DNSServiceErrorType    aErrorCode,
336                                         const char            *aHostName,
337                                         const struct sockaddr *aAddress,
338                                         uint32_t               aTtl);
339 
340         std::string        mHostName;
341         DiscoveredHostInfo mHostInfo;
342     };
343 
344     using ServiceSubscriptionList = std::vector<std::unique_ptr<ServiceSubscription>>;
345     using HostSubscriptionList    = std::vector<std::unique_ptr<HostSubscription>>;
346 
347     static std::string MakeRegType(const std::string &aType, SubTypeList aSubTypeList);
348 
349     void                Stop(StopMode aStopMode);
350     DNSServiceErrorType CreateSharedHostsRef(void);
351     void                DeallocateHostsRef(void);
352     void                HandleServiceRefDeallocating(const DNSServiceRef &aServiceRef);
353 
354     DNSServiceRef mHostsRef;
355     State         mState;
356     StateCallback mStateCallback;
357 
358     ServiceSubscriptionList mSubscribedServices;
359     HostSubscriptionList    mSubscribedHosts;
360 
361     std::vector<DNSServiceRef> mServiceRefsToProcess;
362 };
363 
364 /**
365  * @}
366  */
367 
368 } // namespace Mdns
369 
370 } // namespace otbr
371 
372 #endif // OTBR_AGENT_MDNS_MDNSSD_HPP_
373