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