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