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