1 /* 2 * Copyright (c) 2017, 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 definitions for mDNS publisher. 32 */ 33 34 #ifndef OTBR_AGENT_MDNS_HPP_ 35 #define OTBR_AGENT_MDNS_HPP_ 36 37 #include "openthread-br/config.h" 38 39 #ifndef OTBR_ENABLE_MDNS 40 #define OTBR_ENABLE_MDNS (OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD) 41 #endif 42 43 #include <functional> 44 #include <list> 45 #include <map> 46 #include <memory> 47 #include <string> 48 #include <vector> 49 50 #include <sys/select.h> 51 52 #include "common/callback.hpp" 53 #include "common/code_utils.hpp" 54 #include "common/time.hpp" 55 #include "common/types.hpp" 56 57 namespace otbr { 58 59 namespace Mdns { 60 61 /** 62 * @addtogroup border-router-mdns 63 * 64 * @brief 65 * This module includes definition for mDNS publisher. 66 * 67 * @{ 68 */ 69 70 /** 71 * This interface defines the functionality of mDNS publisher. 72 */ 73 class Publisher : private NonCopyable 74 { 75 public: 76 /** 77 * This structure represents a key/value pair of the TXT record. 78 */ 79 struct TxtEntry 80 { 81 std::string mKey; ///< The key of the TXT entry. 82 std::vector<uint8_t> mValue; ///< The value of the TXT entry. Can be empty. 83 bool mIsBooleanAttribute; ///< This entry is boolean attribute (encoded as `key` without `=`). 84 TxtEntryotbr::Mdns::Publisher::TxtEntry85 TxtEntry(const char *aKey, const char *aValue) 86 : TxtEntry(aKey, reinterpret_cast<const uint8_t *>(aValue), strlen(aValue)) 87 { 88 } 89 TxtEntryotbr::Mdns::Publisher::TxtEntry90 TxtEntry(const char *aKey, const uint8_t *aValue, size_t aValueLength) 91 : TxtEntry(aKey, strlen(aKey), aValue, aValueLength) 92 { 93 } 94 TxtEntryotbr::Mdns::Publisher::TxtEntry95 TxtEntry(const char *aKey, size_t aKeyLength, const uint8_t *aValue, size_t aValueLength) 96 : mKey(aKey, aKeyLength) 97 , mValue(aValue, aValue + aValueLength) 98 , mIsBooleanAttribute(false) 99 { 100 } 101 TxtEntryotbr::Mdns::Publisher::TxtEntry102 TxtEntry(const char *aKey) 103 : TxtEntry(aKey, strlen(aKey)) 104 { 105 } 106 TxtEntryotbr::Mdns::Publisher::TxtEntry107 TxtEntry(const char *aKey, size_t aKeyLength) 108 : mKey(aKey, aKeyLength) 109 , mIsBooleanAttribute(true) 110 { 111 } 112 operator ==otbr::Mdns::Publisher::TxtEntry113 bool operator==(const TxtEntry &aOther) const 114 { 115 return (mKey == aOther.mKey) && (mValue == aOther.mValue) && 116 (mIsBooleanAttribute == aOther.mIsBooleanAttribute); 117 } 118 }; 119 120 typedef std::vector<uint8_t> TxtData; 121 typedef std::vector<TxtEntry> TxtList; 122 typedef std::vector<std::string> SubTypeList; 123 typedef std::vector<Ip6Address> AddressList; 124 typedef std::vector<uint8_t> KeyData; 125 126 /** 127 * This structure represents information of a discovered service instance. 128 */ 129 struct DiscoveredInstanceInfo 130 { 131 bool mRemoved = false; ///< The Service Instance is removed. 132 uint32_t mNetifIndex = 0; ///< Network interface. 133 std::string mName; ///< Instance name. 134 std::string mHostName; ///< Full host name. 135 AddressList mAddresses; ///< IPv6 addresses. 136 uint16_t mPort = 0; ///< Port. 137 uint16_t mPriority = 0; ///< Service priority. 138 uint16_t mWeight = 0; ///< Service weight. 139 TxtData mTxtData; ///< TXT RDATA bytes. 140 uint32_t mTtl = 0; ///< Service TTL. 141 AddAddressotbr::Mdns::Publisher::DiscoveredInstanceInfo142 void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); } RemoveAddressotbr::Mdns::Publisher::DiscoveredInstanceInfo143 void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); } 144 }; 145 146 /** 147 * This structure represents information of a discovered host. 148 */ 149 struct DiscoveredHostInfo 150 { 151 std::string mHostName; ///< Full host name. 152 AddressList mAddresses; ///< IP6 addresses. 153 uint32_t mNetifIndex = 0; ///< Network interface. 154 uint32_t mTtl = 0; ///< Host TTL. 155 AddAddressotbr::Mdns::Publisher::DiscoveredHostInfo156 void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); } RemoveAddressotbr::Mdns::Publisher::DiscoveredHostInfo157 void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); } 158 }; 159 160 /** 161 * This function is called to notify a discovered service instance. 162 */ 163 using DiscoveredServiceInstanceCallback = 164 std::function<void(const std::string &aType, const DiscoveredInstanceInfo &aInstanceInfo)>; 165 166 /** 167 * This function is called to notify a discovered host. 168 */ 169 using DiscoveredHostCallback = 170 std::function<void(const std::string &aHostName, const DiscoveredHostInfo &aHostInfo)>; 171 172 /** 173 * mDNS state values. 174 */ 175 enum class State 176 { 177 kIdle, ///< Unable to publish service. 178 kReady, ///< Ready to publish service. 179 }; 180 181 /** The callback for receiving mDNS publisher state changes. */ 182 using StateCallback = std::function<void(State aNewState)>; 183 184 /** The callback for receiving the result of a operation. */ 185 using ResultCallback = OnceCallback<void(otbrError aError)>; 186 187 /** 188 * This method starts the mDNS publisher. 189 * 190 * @retval OTBR_ERROR_NONE Successfully started mDNS publisher; 191 * @retval OTBR_ERROR_MDNS Failed to start mDNS publisher. 192 */ 193 virtual otbrError Start(void) = 0; 194 195 /** 196 * This method stops the mDNS publisher. 197 */ 198 virtual void Stop(void) = 0; 199 200 /** 201 * This method checks if publisher has been started. 202 * 203 * @retval true Already started. 204 * @retval false Not started. 205 */ 206 virtual bool IsStarted(void) const = 0; 207 208 /** 209 * This method publishes or updates a service. 210 * 211 * @param[in] aHostName The name of the host which this service resides on. If an empty string is 212 * provided, this service resides on local host and it is the implementation 213 * to provide specific host name. Otherwise, the caller MUST publish the host 214 * with method PublishHost. 215 * @param[in] aName The name of this service. If an empty string is provided, the service's name will be the 216 * same as the platform's hostname. 217 * @param[in] aType The type of this service, e.g., "_srv._udp" (MUST NOT end with dot). 218 * @param[in] aSubTypeList A list of service subtypes. 219 * @param[in] aPort The port number of this service. 220 * @param[in] aTxtData The encoded TXT data for this service. 221 * @param[in] aCallback The callback for receiving the publishing result. `OTBR_ERROR_NONE` will be 222 * returned if the operation is successful and all other values indicate a 223 * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has 224 * already been published and the caller can re-publish with a new name if an 225 * alternative name is available/acceptable. 226 */ 227 void PublishService(const std::string &aHostName, 228 const std::string &aName, 229 const std::string &aType, 230 const SubTypeList &aSubTypeList, 231 uint16_t aPort, 232 const TxtData &aTxtData, 233 ResultCallback &&aCallback); 234 235 /** 236 * This method un-publishes a service. 237 * 238 * @param[in] aName The name of this service. 239 * @param[in] aType The type of this service, e.g., "_srv._udp" (MUST NOT end with dot). 240 * @param[in] aCallback The callback for receiving the publishing result. 241 */ 242 virtual void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) = 0; 243 244 /** 245 * This method publishes or updates a host. 246 * 247 * Publishing a host is advertising an AAAA RR for the host name. This method should be called 248 * before a service with non-empty host name is published. 249 * 250 * @param[in] aName The name of the host. 251 * @param[in] aAddresses The addresses of the host. 252 * @param[in] aCallback The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be 253 * returned if the operation is successful and all other values indicate a 254 * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has 255 * already been published and the caller can re-publish with a new name if an 256 * alternative name is available/acceptable. 257 */ 258 void PublishHost(const std::string &aName, const AddressList &aAddresses, ResultCallback &&aCallback); 259 260 /** 261 * This method un-publishes a host. 262 * 263 * @param[in] aName A host name (MUST not end with dot). 264 * @param[in] aCallback The callback for receiving the publishing result. 265 */ 266 virtual void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) = 0; 267 268 /** 269 * This method publishes or updates a key record for a name. 270 * 271 * @param[in] aName The name associated with key record (can be host name or service instance name). 272 * @param[in] aKeyData The key data to publish. 273 * @param[in] aCallback The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be 274 * returned if the operation is successful and all other values indicate a 275 * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has 276 * already been published and the caller can re-publish with a new name if an 277 * alternative name is available/acceptable. 278 */ 279 void PublishKey(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback); 280 281 /** 282 * This method un-publishes a key record 283 * 284 * @param[in] aName The name associated with key record. 285 * @param[in] aCallback The callback for receiving the publishing result. 286 */ 287 virtual void UnpublishKey(const std::string &aName, ResultCallback &&aCallback) = 0; 288 289 /** 290 * This method subscribes a given service or service instance. 291 * 292 * If @p aInstanceName is not empty, this method subscribes the service instance. Otherwise, this method subscribes 293 * the service. mDNS implementations should use the `DiscoveredServiceInstanceCallback` function to notify 294 * discovered service instances. 295 * 296 * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same service or service 297 * instance. 298 * 299 * @param[in] aType The service type, e.g., "_srv._udp" (MUST NOT end with dot). 300 * @param[in] aInstanceName The service instance to subscribe, or empty to subscribe the service. 301 */ 302 virtual void SubscribeService(const std::string &aType, const std::string &aInstanceName) = 0; 303 304 /** 305 * This method unsubscribes a given service or service instance. 306 * 307 * If @p aInstanceName is not empty, this method unsubscribes the service instance. Otherwise, this method 308 * unsubscribes the service. 309 * 310 * @note Discovery Proxy implementation guarantees no redundant unsubscription for a service or service instance. 311 * 312 * @param[in] aType The service type, e.g., "_srv._udp" (MUST NOT end with dot). 313 * @param[in] aInstanceName The service instance to unsubscribe, or empty to unsubscribe the service. 314 */ 315 virtual void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) = 0; 316 317 /** 318 * This method subscribes a given host. 319 * 320 * mDNS implementations should use the `DiscoveredHostCallback` function to notify discovered hosts. 321 * 322 * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same host. 323 * 324 * @param[in] aHostName The host name (without domain). 325 */ 326 virtual void SubscribeHost(const std::string &aHostName) = 0; 327 328 /** 329 * This method unsubscribes a given host. 330 * 331 * @note Discovery Proxy implementation guarantees no redundant unsubscription for a host. 332 * 333 * @param[in] aHostName The host name (without domain). 334 */ 335 virtual void UnsubscribeHost(const std::string &aHostName) = 0; 336 337 /** 338 * This method sets the callbacks for subscriptions. 339 * 340 * @param[in] aInstanceCallback The callback function to receive discovered service instances. 341 * @param[in] aHostCallback The callback function to receive discovered hosts. 342 * 343 * @returns The Subscriber ID for the callbacks. 344 */ 345 uint64_t AddSubscriptionCallbacks(DiscoveredServiceInstanceCallback aInstanceCallback, 346 DiscoveredHostCallback aHostCallback); 347 348 /** 349 * This method cancels callbacks for subscriptions. 350 * 351 * @param[in] aSubscriberId The Subscriber ID previously returned by `AddSubscriptionCallbacks`. 352 */ 353 void RemoveSubscriptionCallbacks(uint64_t aSubscriberId); 354 355 /** 356 * This method returns the mDNS statistics information of the publisher. 357 * 358 * @returns The MdnsTelemetryInfo of the publisher. 359 */ GetMdnsTelemetryInfo(void) const360 const MdnsTelemetryInfo &GetMdnsTelemetryInfo(void) const { return mTelemetryInfo; } 361 362 virtual ~Publisher(void) = default; 363 364 /** 365 * This function creates a mDNS publisher. 366 * 367 * @param[in] aCallback The callback for receiving mDNS publisher state changes. 368 * 369 * @returns A pointer to the newly created mDNS publisher. 370 */ 371 static Publisher *Create(StateCallback aCallback); 372 373 /** 374 * This function destroys the mDNS publisher. 375 * 376 * @param[in] aPublisher A pointer to the publisher. 377 */ 378 static void Destroy(Publisher *aPublisher); 379 380 /** 381 * This function writes the TXT entry list to a TXT data buffer. The TXT entries 382 * will be sorted by their keys. 383 * 384 * The output data is in standard DNS-SD TXT data format. 385 * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6. 386 * 387 * @param[in] aTxtList A TXT entry list. 388 * @param[out] aTxtData A TXT data buffer. Will be cleared. 389 * 390 * @retval OTBR_ERROR_NONE Successfully write the TXT entry list. 391 * @retval OTBR_ERROR_INVALID_ARGS The @p aTxtList includes invalid TXT entry. 392 * 393 * @sa DecodeTxtData 394 */ 395 static otbrError EncodeTxtData(const TxtList &aTxtList, TxtData &aTxtData); 396 397 /** 398 * This function decodes a TXT entry list from a TXT data buffer. 399 * 400 * The input data should be in standard DNS-SD TXT data format. 401 * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6. 402 * 403 * @param[out] aTxtList A TXT entry list. 404 * @param[in] aTxtData A pointer to TXT data. 405 * @param[in] aTxtLength The TXT data length. 406 * 407 * @retval OTBR_ERROR_NONE Successfully decoded the TXT data. 408 * @retval OTBR_ERROR_INVALID_ARGS The @p aTxtdata has invalid TXT format. 409 * 410 * @sa EncodeTxtData 411 */ 412 static otbrError DecodeTxtData(TxtList &aTxtList, const uint8_t *aTxtData, uint16_t aTxtLength); 413 414 protected: 415 static constexpr uint8_t kMaxTextEntrySize = 255; 416 417 class Registration 418 { 419 public: 420 ResultCallback mCallback; 421 Publisher *mPublisher; 422 Registration(ResultCallback && aCallback,Publisher * aPublisher)423 Registration(ResultCallback &&aCallback, Publisher *aPublisher) 424 : mCallback(std::move(aCallback)) 425 , mPublisher(aPublisher) 426 { 427 } 428 virtual ~Registration(void); 429 430 // Tells whether the service registration has been completed (typically by calling 431 // `ServiceRegistration::Complete`). IsCompleted() const432 bool IsCompleted() const { return mCallback.IsNull(); } 433 434 protected: 435 // Completes the service registration with given result/error. TriggerCompleteCallback(otbrError aError)436 void TriggerCompleteCallback(otbrError aError) 437 { 438 if (!IsCompleted()) 439 { 440 std::move(mCallback)(aError); 441 } 442 } 443 }; 444 445 // TODO: We may need a registration ID to fetch the information of a registration. 446 class ServiceRegistration : public Registration 447 { 448 public: 449 std::string mHostName; 450 std::string mName; 451 std::string mType; 452 SubTypeList mSubTypeList; 453 uint16_t mPort; 454 TxtData mTxtData; 455 ServiceRegistration(std::string aHostName,std::string aName,std::string aType,SubTypeList aSubTypeList,uint16_t aPort,TxtData aTxtData,ResultCallback && aCallback,Publisher * aPublisher)456 ServiceRegistration(std::string aHostName, 457 std::string aName, 458 std::string aType, 459 SubTypeList aSubTypeList, 460 uint16_t aPort, 461 TxtData aTxtData, 462 ResultCallback &&aCallback, 463 Publisher *aPublisher) 464 : Registration(std::move(aCallback), aPublisher) 465 , mHostName(std::move(aHostName)) 466 , mName(std::move(aName)) 467 , mType(std::move(aType)) 468 , mSubTypeList(SortSubTypeList(std::move(aSubTypeList))) 469 , mPort(aPort) 470 , mTxtData(std::move(aTxtData)) 471 { 472 } ~ServiceRegistration(void)473 ~ServiceRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); } 474 475 void Complete(otbrError aError); 476 477 // Tells whether this `ServiceRegistration` object is outdated comparing to the given parameters. 478 bool IsOutdated(const std::string &aHostName, 479 const std::string &aName, 480 const std::string &aType, 481 const SubTypeList &aSubTypeList, 482 uint16_t aPort, 483 const TxtData &aTxtData) const; 484 485 private: 486 void OnComplete(otbrError aError); 487 }; 488 489 class HostRegistration : public Registration 490 { 491 public: 492 std::string mName; 493 AddressList mAddresses; 494 HostRegistration(std::string aName,AddressList aAddresses,ResultCallback && aCallback,Publisher * aPublisher)495 HostRegistration(std::string aName, AddressList aAddresses, ResultCallback &&aCallback, Publisher *aPublisher) 496 : Registration(std::move(aCallback), aPublisher) 497 , mName(std::move(aName)) 498 , mAddresses(SortAddressList(std::move(aAddresses))) 499 { 500 } 501 ~HostRegistration(void)502 ~HostRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); } 503 504 void Complete(otbrError aError); 505 506 // Tells whether this `HostRegistration` object is outdated comparing to the given parameters. 507 bool IsOutdated(const std::string &aName, const AddressList &aAddresses) const; 508 509 private: 510 void OnComplete(otbrError aError); 511 }; 512 513 class KeyRegistration : public Registration 514 { 515 public: 516 std::string mName; 517 KeyData mKeyData; 518 KeyRegistration(std::string aName,KeyData aKeyData,ResultCallback && aCallback,Publisher * aPublisher)519 KeyRegistration(std::string aName, KeyData aKeyData, ResultCallback &&aCallback, Publisher *aPublisher) 520 : Registration(std::move(aCallback), aPublisher) 521 , mName(std::move(aName)) 522 , mKeyData(std::move(aKeyData)) 523 { 524 } 525 ~KeyRegistration(void)526 ~KeyRegistration(void) { OnComplete(OTBR_ERROR_ABORTED); } 527 528 void Complete(otbrError aError); 529 530 // Tells whether this `KeyRegistration` object is outdated comparing to the given parameters. 531 bool IsOutdated(const std::string &aName, const KeyData &aKeyData) const; 532 533 private: 534 void OnComplete(otbrError aError); 535 }; 536 537 using ServiceRegistrationPtr = std::unique_ptr<ServiceRegistration>; 538 using ServiceRegistrationMap = std::map<std::string, ServiceRegistrationPtr>; 539 using HostRegistrationPtr = std::unique_ptr<HostRegistration>; 540 using HostRegistrationMap = std::map<std::string, HostRegistrationPtr>; 541 using KeyRegistrationPtr = std::unique_ptr<KeyRegistration>; 542 using KeyRegistrationMap = std::map<std::string, KeyRegistrationPtr>; 543 544 static SubTypeList SortSubTypeList(SubTypeList aSubTypeList); 545 static AddressList SortAddressList(AddressList aAddressList); 546 static std::string MakeFullName(const std::string &aName); 547 static std::string MakeFullServiceName(const std::string &aName, const std::string &aType); MakeFullHostName(const std::string & aName)548 static std::string MakeFullHostName(const std::string &aName) { return MakeFullName(aName); } MakeFullKeyName(const std::string & aName)549 static std::string MakeFullKeyName(const std::string &aName) { return MakeFullName(aName); } 550 551 virtual otbrError PublishServiceImpl(const std::string &aHostName, 552 const std::string &aName, 553 const std::string &aType, 554 const SubTypeList &aSubTypeList, 555 uint16_t aPort, 556 const TxtData &aTxtData, 557 ResultCallback &&aCallback) = 0; 558 559 virtual otbrError PublishHostImpl(const std::string &aName, 560 const AddressList &aAddresses, 561 ResultCallback &&aCallback) = 0; 562 563 virtual otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback) = 0; 564 565 virtual void OnServiceResolveFailedImpl(const std::string &aType, 566 const std::string &aInstanceName, 567 int32_t aErrorCode) = 0; 568 569 virtual void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) = 0; 570 571 virtual otbrError DnsErrorToOtbrError(int32_t aError) = 0; 572 573 void AddServiceRegistration(ServiceRegistrationPtr &&aServiceReg); 574 void RemoveServiceRegistration(const std::string &aName, const std::string &aType, otbrError aError); 575 ServiceRegistration *FindServiceRegistration(const std::string &aName, const std::string &aType); 576 ServiceRegistration *FindServiceRegistration(const std::string &aNameAndType); 577 578 void OnServiceResolved(std::string aType, DiscoveredInstanceInfo aInstanceInfo); 579 void OnServiceResolveFailed(std::string aType, std::string aInstanceName, int32_t aErrorCode); 580 void OnServiceRemoved(uint32_t aNetifIndex, std::string aType, std::string aInstanceName); 581 void OnHostResolved(std::string aHostName, DiscoveredHostInfo aHostInfo); 582 void OnHostResolveFailed(std::string aHostName, int32_t aErrorCode); 583 584 // Handles the cases that there is already a registration for the same service. 585 // If the returned callback is completed, current registration should be considered 586 // success and no further action should be performed. 587 ResultCallback HandleDuplicateServiceRegistration(const std::string &aHostName, 588 const std::string &aName, 589 const std::string &aType, 590 const SubTypeList &aSubTypeList, 591 uint16_t aPort, 592 const TxtData &aTxtData, 593 ResultCallback &&aCallback); 594 595 ResultCallback HandleDuplicateHostRegistration(const std::string &aName, 596 const AddressList &aAddresses, 597 ResultCallback &&aCallback); 598 599 ResultCallback HandleDuplicateKeyRegistration(const std::string &aName, 600 const KeyData &aKeyData, 601 ResultCallback &&aCallback); 602 603 void AddHostRegistration(HostRegistrationPtr &&aHostReg); 604 void RemoveHostRegistration(const std::string &aName, otbrError aError); 605 HostRegistration *FindHostRegistration(const std::string &aName); 606 607 void AddKeyRegistration(KeyRegistrationPtr &&aKeyReg); 608 void RemoveKeyRegistration(const std::string &aName, otbrError aError); 609 KeyRegistration *FindKeyRegistration(const std::string &aName); 610 KeyRegistration *FindKeyRegistration(const std::string &aName, const std::string &aType); 611 612 static void UpdateMdnsResponseCounters(MdnsResponseCounters &aCounters, otbrError aError); 613 static void UpdateEmaLatency(uint32_t &aEmaLatency, uint32_t aLatency, otbrError aError); 614 615 void UpdateServiceRegistrationEmaLatency(const std::string &aInstanceName, 616 const std::string &aType, 617 otbrError aError); 618 void UpdateHostRegistrationEmaLatency(const std::string &aHostName, otbrError aError); 619 void UpdateKeyRegistrationEmaLatency(const std::string &aKeyName, otbrError aError); 620 void UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName, 621 const std::string &aType, 622 otbrError aError); 623 void UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError); 624 625 static void AddAddress(AddressList &aAddressList, const Ip6Address &aAddress); 626 static void RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddress); 627 628 ServiceRegistrationMap mServiceRegistrations; 629 HostRegistrationMap mHostRegistrations; 630 KeyRegistrationMap mKeyRegistrations; 631 632 struct DiscoverCallback 633 { DiscoverCallbackotbr::Mdns::Publisher::DiscoverCallback634 DiscoverCallback(uint64_t aId, 635 DiscoveredServiceInstanceCallback aServiceCallback, 636 DiscoveredHostCallback aHostCallback) 637 : mId(aId) 638 , mServiceCallback(std::move(aServiceCallback)) 639 , mHostCallback(std::move(aHostCallback)) 640 , mShouldInvoke(false) 641 { 642 } 643 644 uint64_t mId; 645 DiscoveredServiceInstanceCallback mServiceCallback; 646 DiscoveredHostCallback mHostCallback; 647 bool mShouldInvoke; 648 }; 649 650 uint64_t mNextSubscriberId = 1; 651 652 std::list<DiscoverCallback> mDiscoverCallbacks; 653 654 // {instance name, service type} -> the timepoint to begin service registration 655 std::map<std::pair<std::string, std::string>, Timepoint> mServiceRegistrationBeginTime; 656 // host name -> the timepoint to begin host registration 657 std::map<std::string, Timepoint> mHostRegistrationBeginTime; 658 // key name -> the timepoint to begin key registration 659 std::map<std::string, Timepoint> mKeyRegistrationBeginTime; 660 // {instance name, service type} -> the timepoint to begin service resolution 661 std::map<std::pair<std::string, std::string>, Timepoint> mServiceInstanceResolutionBeginTime; 662 // host name -> the timepoint to begin host resolution 663 std::map<std::string, Timepoint> mHostResolutionBeginTime; 664 665 MdnsTelemetryInfo mTelemetryInfo{}; 666 }; 667 668 /** 669 * @} 670 */ 671 672 } // namespace Mdns 673 674 } // namespace otbr 675 676 #endif // OTBR_AGENT_MDNS_HPP_ 677