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