1 /* 2 * Copyright (c) 2020, 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 SRP server. 32 */ 33 34 #ifndef NET_SRP_SERVER_HPP_ 35 #define NET_SRP_SERVER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 40 41 #if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 42 #error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE" 43 #endif 44 45 #if !OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE 46 #error "OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE" 47 #endif 48 49 #if !OPENTHREAD_CONFIG_ECDSA_ENABLE 50 #error "OPENTHREAD_CONFIG_ECDSA_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE" 51 #endif 52 53 #include <openthread/ip6.h> 54 #include <openthread/srp_server.h> 55 56 #include "common/array.hpp" 57 #include "common/as_core_type.hpp" 58 #include "common/clearable.hpp" 59 #include "common/heap.hpp" 60 #include "common/heap_allocatable.hpp" 61 #include "common/heap_array.hpp" 62 #include "common/heap_data.hpp" 63 #include "common/heap_string.hpp" 64 #include "common/linked_list.hpp" 65 #include "common/locator.hpp" 66 #include "common/non_copyable.hpp" 67 #include "common/notifier.hpp" 68 #include "common/numeric_limits.hpp" 69 #include "common/retain_ptr.hpp" 70 #include "common/timer.hpp" 71 #include "crypto/ecdsa.hpp" 72 #include "net/dns_types.hpp" 73 #include "net/ip6.hpp" 74 #include "net/ip6_address.hpp" 75 #include "net/udp6.hpp" 76 #include "thread/network_data_publisher.hpp" 77 78 struct otSrpServerHost 79 { 80 }; 81 82 struct otSrpServerService 83 { 84 }; 85 86 namespace ot { 87 88 namespace Dns { 89 namespace ServiceDiscovery { 90 class Server; 91 } 92 } // namespace Dns 93 94 namespace Srp { 95 96 /** 97 * This class implements the SRP server. 98 * 99 */ 100 class Server : public InstanceLocator, private NonCopyable 101 { 102 friend class NetworkData::Publisher; 103 friend class UpdateMetadata; 104 friend class Service; 105 friend class Host; 106 friend class Dns::ServiceDiscovery::Server; 107 108 enum RetainName : bool 109 { 110 kDeleteName = false, 111 kRetainName = true, 112 }; 113 114 enum NotifyMode : bool 115 { 116 kDoNotNotifyServiceHandler = false, 117 kNotifyServiceHandler = true, 118 }; 119 120 public: 121 static constexpr uint16_t kUdpPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN; ///< The reserved min port. 122 static constexpr uint16_t kUdpPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX; ///< The reserved max port. 123 124 static_assert(kUdpPortMin <= kUdpPortMax, "invalid port range"); 125 126 /** 127 * The ID of SRP service update transaction. 128 * 129 */ 130 typedef otSrpServerServiceUpdateId ServiceUpdateId; 131 132 /** 133 * The SRP server lease information of a host/service. 134 * 135 */ 136 typedef otSrpServerLeaseInfo LeaseInfo; 137 138 /** 139 * This enumeration represents the address mode used by the SRP server. 140 * 141 * Address mode specifies how the address and port number are determined by the SRP server and how this info ins 142 * published in the Thread Network Data. 143 * 144 */ 145 enum AddressMode : uint8_t 146 { 147 kAddressModeUnicast = OT_SRP_SERVER_ADDRESS_MODE_UNICAST, ///< Unicast address mode. 148 kAddressModeAnycast = OT_SRP_SERVER_ADDRESS_MODE_ANYCAST, ///< Anycast address mode. 149 }; 150 151 class Host; 152 153 enum State : uint8_t 154 { 155 kStateDisabled = OT_SRP_SERVER_STATE_DISABLED, 156 kStateRunning = OT_SRP_SERVER_STATE_RUNNING, 157 kStateStopped = OT_SRP_SERVER_STATE_STOPPED, 158 }; 159 160 /** 161 * This class implements a server-side SRP service. 162 * 163 */ 164 class Service : public otSrpServerService, 165 public LinkedListEntry<Service>, 166 private Heap::Allocatable<Service>, 167 private NonCopyable 168 { 169 friend class Server; 170 friend class LinkedList<Service>; 171 friend class LinkedListEntry<Service>; 172 friend class Heap::Allocatable<Service>; 173 174 public: 175 /** 176 * This type represents the flags which indicates which services to include or exclude when searching in (or 177 * iterating over) the list of SRP services. 178 * 179 */ 180 typedef otSrpServerServiceFlags Flags; 181 182 /** 183 * This `Flags` constant indicates to include base services (not a sub-type). 184 * 185 */ 186 static constexpr Flags kFlagBaseType = OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE; 187 188 /** 189 * This `Flags` constant indicates to include sub-type services. 190 * 191 */ 192 static constexpr Flags kFlagSubType = OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE; 193 194 /** 195 * This `Flags` constant indicates to include active (not deleted) services. 196 * 197 */ 198 static constexpr Flags kFlagActive = OT_SRP_SERVER_SERVICE_FLAG_ACTIVE; 199 200 /** 201 * This `Flags` constant indicates to include deleted services. 202 * 203 */ 204 static constexpr Flags kFlagDeleted = OT_SRP_SERVER_SERVICE_FLAG_DELETED; 205 206 /** 207 * This method tells if the SRP service has been deleted. 208 * 209 * A SRP service can be deleted but retains its name for future uses. 210 * In this case, the service instance is not removed from the SRP server/registry. 211 * It is guaranteed that all services are deleted if the host is deleted. 212 * 213 * @returns TRUE if the service has been deleted, FALSE if not. 214 * 215 */ IsDeleted(void) const216 bool IsDeleted(void) const { return mIsDeleted; } 217 218 /** 219 * This method indicates whether the SRP service is a sub-type. 220 * 221 * @retval TRUE If the service is a sub-type. 222 * @retval FALSE If the service is not a sub-type. 223 * 224 */ IsSubType(void) const225 bool IsSubType(void) const { return mIsSubType; } 226 227 /** 228 * This method gets the full service instance name of the service. 229 * 230 * @returns A pointer service instance name (as a null-terminated C string). 231 * 232 */ GetInstanceName(void) const233 const char *GetInstanceName(void) const { return mDescription->mInstanceName.AsCString(); } 234 235 /** 236 * This method gets the full service name of the service. 237 * 238 * @returns A pointer service name (as a null-terminated C string). 239 * 240 */ GetServiceName(void) const241 const char *GetServiceName(void) const { return mServiceName.AsCString(); } 242 243 /** 244 * This method gets the sub-type label from service name. 245 * 246 * The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This 247 * method copies the `<sub-label>` into the @p aLabel buffer. 248 * 249 * The @p aLabel is ensured to always be null-terminated after returning even in case of failure. 250 * 251 * @param[out] aLabel A pointer to a buffer to copy the sub-type label name. 252 * @param[in] aMaxSize Maximum size of @p aLabel buffer. 253 * 254 * @retval kErrorNone @p aLabel was updated successfully. 255 * @retval kErrorNoBufs The sub-type label could not fit in @p aLabel buffer (number of chars from label 256 * that could fit are copied in @p aLabel ensuring it is null-terminated). 257 * @retval kErrorInvalidArgs SRP service is not a sub-type. 258 * 259 */ 260 Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const; 261 262 /** 263 * This method returns the TTL of the service instance. 264 * 265 * @returns The TTL of the service instance. 266 * 267 */ GetTtl(void) const268 uint32_t GetTtl(void) const { return mDescription->mTtl; } 269 270 /** 271 * This method returns the port of the service instance. 272 * 273 * @returns The port of the service. 274 * 275 */ GetPort(void) const276 uint16_t GetPort(void) const { return mDescription->mPort; } 277 278 /** 279 * This method returns the weight of the service instance. 280 * 281 * @returns The weight of the service. 282 * 283 */ GetWeight(void) const284 uint16_t GetWeight(void) const { return mDescription->mWeight; } 285 286 /** 287 * This method returns the priority of the service instance. 288 * 289 * @returns The priority of the service. 290 * 291 */ GetPriority(void) const292 uint16_t GetPriority(void) const { return mDescription->mPriority; } 293 294 /** 295 * This method returns the TXT record data of the service instance. 296 * 297 * @returns A pointer to the buffer containing the TXT record data. 298 * 299 */ GetTxtData(void) const300 const uint8_t *GetTxtData(void) const { return mDescription->mTxtData.GetBytes(); } 301 302 /** 303 * This method returns the TXT record data length of the service instance. 304 * 305 * @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`). 306 * 307 */ GetTxtDataLength(void) const308 uint16_t GetTxtDataLength(void) const { return mDescription->mTxtData.GetLength(); } 309 310 /** 311 * This method returns the host which the service instance reside on. 312 * 313 * @returns A reference to the host instance. 314 * 315 */ GetHost(void) const316 const Host &GetHost(void) const { return *mDescription->mHost; } 317 318 /** 319 * This method returns the LEASE time of the service. 320 * 321 * @returns The LEASE time in seconds. 322 * 323 */ GetLease(void) const324 uint32_t GetLease(void) const { return mDescription->mLease; } 325 326 /** 327 * This method returns the KEY-LEASE time of the key of the service. 328 * 329 * @returns The KEY-LEASE time in seconds. 330 * 331 */ GetKeyLease(void) const332 uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; } 333 334 /** 335 * This method returns the expire time (in milliseconds) of the service. 336 * 337 * @returns The service expire time in milliseconds. 338 * 339 */ 340 TimeMilli GetExpireTime(void) const; 341 342 /** 343 * This method returns the key expire time (in milliseconds) of the service. 344 * 345 * @returns The service key expire time in milliseconds. 346 * 347 */ 348 TimeMilli GetKeyExpireTime(void) const; 349 350 /** 351 * This method gets the LEASE and KEY-LEASE information of a given service. 352 * 353 * @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time, 354 * remaining LEASE time and the remaining KEY-LEASE time. 355 * 356 */ 357 void GetLeaseInfo(LeaseInfo &aLeaseInfo) const; 358 359 /** 360 * This method indicates whether this service matches a given service instance name. 361 * 362 * @param[in] aInstanceName The service instance name. 363 * 364 * @retval TRUE If the service matches the service instance name. 365 * @retval FALSE If the service does not match the service instance name. 366 * 367 */ 368 bool MatchesInstanceName(const char *aInstanceName) const; 369 370 /** 371 * This method tells whether this service matches a given service name. 372 * 373 * @param[in] aServiceName The full service name to match. 374 * 375 * @retval TRUE If the service matches the full service name. 376 * @retval FALSE If the service does not match the full service name. 377 * 378 */ 379 bool MatchesServiceName(const char *aServiceName) const; 380 381 private: 382 struct Description : public LinkedListEntry<Description>, 383 public Heap::Allocatable<Description>, 384 public RetainCountable, 385 private NonCopyable 386 { 387 Error Init(const char *aInstanceName, Host &aHost); GetInstanceNameot::Srp::Server::Service::Description388 const char *GetInstanceName(void) const { return mInstanceName.AsCString(); } 389 bool Matches(const char *aInstanceName) const; 390 void ClearResources(void); 391 void TakeResourcesFrom(Description &aDescription); 392 Error SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength); 393 394 Description *mNext; 395 Heap::String mInstanceName; 396 Host * mHost; 397 Heap::Data mTxtData; 398 uint16_t mPriority; 399 uint16_t mWeight; 400 uint16_t mPort; 401 uint32_t mTtl; // The TTL in seconds. 402 uint32_t mLease; // The LEASE time in seconds. 403 uint32_t mKeyLease; // The KEY-LEASE time in seconds. 404 TimeMilli mUpdateTime; 405 }; 406 407 enum Action : uint8_t 408 { 409 kAddNew, 410 kUpdateExisting, 411 kRemoveButRetainName, 412 kFullyRemove, 413 kLeaseExpired, 414 kKeyLeaseExpired, 415 }; 416 417 Error Init(const char *aServiceName, Description &aDescription, bool aIsSubType, TimeMilli aUpdateTime); 418 bool MatchesFlags(Flags aFlags) const; GetUpdateTime(void) const419 const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; } 420 void Log(Action aAction) const; 421 422 Heap::String mServiceName; 423 RetainPtr<Description> mDescription; 424 Service * mNext; 425 TimeMilli mUpdateTime; 426 bool mIsDeleted : 1; 427 bool mIsSubType : 1; 428 bool mIsCommitted : 1; 429 }; 430 431 /** 432 * This class implements the Host which registers services on the SRP server. 433 * 434 */ 435 class Host : public otSrpServerHost, 436 public InstanceLocator, 437 public LinkedListEntry<Host>, 438 private Heap::Allocatable<Host>, 439 private NonCopyable 440 { 441 friend class Server; 442 friend class LinkedListEntry<Host>; 443 friend class Heap::Allocatable<Host>; 444 445 public: 446 /** 447 * This method tells whether the Host object has been deleted. 448 * 449 * The Host object retains event if the host has been deleted by the SRP client, 450 * because the host name may retain. 451 * 452 * @returns TRUE if the host is deleted, FALSE if the host is not deleted. 453 * 454 */ IsDeleted(void) const455 bool IsDeleted(void) const { return (mLease == 0); } 456 457 /** 458 * This method returns the full name of the host. 459 * 460 * @returns A pointer to the null-terminated full host name. 461 * 462 */ GetFullName(void) const463 const char *GetFullName(void) const { return mFullName.AsCString(); } 464 465 /** 466 * This method returns addresses of the host. 467 * 468 * @param[out] aAddressesNum The number of the addresses. 469 * 470 * @returns A pointer to the addresses array or `nullptr` if no addresses. 471 * 472 */ GetAddresses(uint8_t & aAddressesNum) const473 const Ip6::Address *GetAddresses(uint8_t &aAddressesNum) const 474 { 475 aAddressesNum = static_cast<uint8_t>(OT_MIN(mAddresses.GetLength(), NumericLimits<uint8_t>::kMax)); 476 return mAddresses.AsCArray(); 477 } 478 479 /** 480 * This method returns the TTL of the host. 481 * 482 * @returns The TTL of the host. 483 * 484 */ GetTtl(void) const485 uint32_t GetTtl(void) const { return mTtl; } 486 487 /** 488 * This method returns the LEASE time of the host. 489 * 490 * @returns The LEASE time in seconds. 491 * 492 */ GetLease(void) const493 uint32_t GetLease(void) const { return mLease; } 494 495 /** 496 * This method returns the KEY-LEASE time of the key of the host. 497 * 498 * @returns The KEY-LEASE time in seconds. 499 * 500 */ GetKeyLease(void) const501 uint32_t GetKeyLease(void) const { return mKeyLease; } 502 503 /** 504 * This method gets the LEASE and KEY-LEASE information of a given host. 505 * 506 * @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time, 507 * remaining LEASE time and the remaining KEY-LEASE time. 508 * 509 */ 510 void GetLeaseInfo(LeaseInfo &aLeaseInfo) const; 511 512 /** 513 * This method returns the KEY resource record of the host. 514 * 515 * @returns A pointer to the ECDSA P 256 public key resource record 516 * if there is valid one. `nullptr` if no valid key exists. 517 * 518 */ GetKeyRecord(void) const519 const Dns::Ecdsa256KeyRecord *GetKeyRecord(void) const { return mKeyRecord.IsValid() ? &mKeyRecord : nullptr; } 520 521 /** 522 * This method returns the expire time (in milliseconds) of the host. 523 * 524 * @returns The expire time in milliseconds. 525 * 526 */ 527 TimeMilli GetExpireTime(void) const; 528 529 /** 530 * This method returns the expire time (in milliseconds) of the key of the host. 531 * 532 * @returns The expire time of the key in milliseconds. 533 * 534 */ 535 TimeMilli GetKeyExpireTime(void) const; 536 537 /** 538 * This method returns the `Service` linked list associated with the host. 539 * 540 * @returns The `Service` linked list. 541 * 542 */ GetServices(void) const543 const LinkedList<Service> &GetServices(void) const { return mServices; } 544 545 /** 546 * This method finds the next matching service on the host. 547 * 548 * @param[in] aPrevService A pointer to the previous service or `nullptr` to start from beginning of the list. 549 * @param[in] aFlags Flags indicating which services to include (base/sub-type, active/deleted). 550 * @param[in] aServiceName The service name to match. Set to `nullptr` to accept any name. 551 * @param[in] aInstanceName The service instance name to match. Set to `nullptr` to accept any name. 552 * 553 * @returns A pointer to the next matching service or `nullptr` if no matching service could be found. 554 * 555 */ 556 const Service *FindNextService(const Service *aPrevService, 557 Service::Flags aFlags = kFlagsAnyService, 558 const char * aServiceName = nullptr, 559 const char * aInstanceName = nullptr) const; 560 561 /** 562 * This method tells whether the host matches a given full name. 563 * 564 * @param[in] aFullName The full name. 565 * 566 * @returns A boolean that indicates whether the host matches the given name. 567 * 568 */ 569 bool Matches(const char *aFullName) const; 570 571 private: 572 Host(Instance &aInstance, TimeMilli aUpdateTime); 573 ~Host(void); 574 575 Error SetFullName(const char *aFullName); 576 void SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord); SetTtl(uint32_t aTtl)577 void SetTtl(uint32_t aTtl) { mTtl = aTtl; } SetLease(uint32_t aLease)578 void SetLease(uint32_t aLease) { mLease = aLease; } SetKeyLease(uint32_t aKeyLease)579 void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; } 580 Error ProcessTtl(uint32_t aTtl); 581 GetServices(void)582 LinkedList<Service> &GetServices(void) { return mServices; } 583 Service * AddNewService(const char *aServiceName, 584 const char *aInstanceName, 585 bool aIsSubType, 586 TimeMilli aUpdateTime); 587 void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler); 588 Error AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime); 589 void FreeAllServices(void); 590 void ClearResources(void); 591 Error MergeServicesAndResourcesFrom(Host &aHost); 592 Error AddIp6Address(const Ip6::Address &aIp6Address); 593 bool HasServiceInstance(const char *aInstanceName) const; 594 RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName); 595 const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const; 596 Service * FindService(const char *aServiceName, const char *aInstanceName); 597 const Service * FindService(const char *aServiceName, const char *aInstanceName) const; 598 Service * FindBaseService(const char *aInstanceName); 599 const Service * FindBaseService(const char *aInstanceName) const; 600 601 Host * mNext; 602 Heap::String mFullName; 603 Heap::Array<Ip6::Address> mAddresses; 604 605 // TODO(wgtdkp): there is no necessary to save the entire resource 606 // record, saving only the ECDSA-256 public key should be enough. 607 Dns::Ecdsa256KeyRecord mKeyRecord; 608 uint32_t mTtl; // The TTL in seconds. 609 uint32_t mLease; // The LEASE time in seconds. 610 uint32_t mKeyLease; // The KEY-LEASE time in seconds. 611 TimeMilli mUpdateTime; 612 LinkedList<Service> mServices; 613 }; 614 615 /** 616 * This class handles TTL configuration. 617 * 618 */ 619 class TtlConfig : public otSrpServerTtlConfig 620 { 621 friend class Server; 622 623 public: 624 /** 625 * This constructor initializes to default TTL configuration. 626 * 627 */ 628 TtlConfig(void); 629 630 private: IsValid(void) const631 bool IsValid(void) const { return mMinTtl <= mMaxTtl; } 632 uint32_t GrantTtl(uint32_t aLease, uint32_t aTtl) const; 633 }; 634 635 /** 636 * This class handles LEASE and KEY-LEASE configurations. 637 * 638 */ 639 class LeaseConfig : public otSrpServerLeaseConfig 640 { 641 friend class Server; 642 643 public: 644 /** 645 * This constructor initialize to default LEASE and KEY-LEASE configurations. 646 * 647 */ 648 LeaseConfig(void); 649 650 private: 651 bool IsValid(void) const; 652 uint32_t GrantLease(uint32_t aLease) const; 653 uint32_t GrantKeyLease(uint32_t aKeyLease) const; 654 }; 655 656 /** 657 * This constant defines a `Service::Flags` combination accepting any service (base/sub-type, active/deleted). 658 * 659 */ 660 static constexpr Service::Flags kFlagsAnyService = OT_SRP_SERVER_FLAGS_ANY_SERVICE; 661 662 /** 663 * This constant defines a `Service::Flags` combination accepting base services only. 664 * 665 */ 666 static constexpr Service::Flags kFlagsBaseTypeServiceOnly = OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY; 667 668 /** 669 * This constant defines a `Service::Flags` combination accepting sub-type services only. 670 * 671 */ 672 static constexpr Service::Flags kFlagsSubTypeServiceOnly = OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY; 673 674 /** 675 * This constant defines a `Service::Flags` combination accepting any active services (not deleted). 676 * 677 */ 678 static constexpr Service::Flags kFlagsAnyTypeActiveService = OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE; 679 680 /** 681 * This constant defines a `Service::Flags` combination accepting any deleted services. 682 * 683 */ 684 static constexpr Service::Flags kFlagsAnyTypeDeletedService = OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE; 685 686 /** 687 * This constructor initializes the SRP server object. 688 * 689 * @param[in] aInstance A reference to the OpenThread instance. 690 * 691 */ 692 explicit Server(Instance &aInstance); 693 694 /** 695 * This method sets the SRP service events handler. 696 * 697 * @param[in] aServiceHandler A service events handler. 698 * @param[in] aServiceHandlerContext A pointer to arbitrary context information. 699 * 700 * @note The handler SHOULD call HandleServiceUpdateResult to report the result of its processing. 701 * Otherwise, a SRP update will be considered failed. 702 * 703 * @sa HandleServiceUpdateResult 704 * 705 */ 706 void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext); 707 708 /** 709 * This method returns the domain authorized to the SRP server. 710 * 711 * If the domain if not set by SetDomain, "default.service.arpa." will be returned. 712 * A trailing dot is always appended even if the domain is set without it. 713 * 714 * @returns A pointer to the dot-joined domain string. 715 * 716 */ GetDomain(void) const717 const char *GetDomain(void) const { return mDomain.AsCString(); } 718 719 /** 720 * This method sets the domain on the SRP server. 721 * 722 * A trailing dot will be appended to @p aDomain if it is not already there. 723 * This method should only be called before the SRP server is enabled. 724 * 725 * @param[in] aDomain The domain to be set. MUST NOT be `nullptr`. 726 * 727 * @retval kErrorNone Successfully set the domain to @p aDomain. 728 * @retval kErrorInvalidState The SRP server is already enabled and the Domain cannot be changed. 729 * @retval kErrorInvalidArgs The argument @p aDomain is not a valid DNS domain name. 730 * @retval kErrorNoBufs There is no memory to store content of @p aDomain. 731 * 732 */ 733 Error SetDomain(const char *aDomain); 734 735 /** 736 * This method returns the address mode being used by the SRP server. 737 * 738 * @returns The SRP server's address mode. 739 * 740 */ GetAddressMode(void) const741 AddressMode GetAddressMode(void) const { return mAddressMode; } 742 743 /** 744 * This method sets the address mode to be used by the SRP server. 745 * 746 * @param[in] aMode The address mode to use. 747 * 748 * @retval kErrorNone Successfully set the address mode. 749 * @retval kErrorInvalidState The SRP server is enabled and the address mode cannot be changed. 750 * 751 */ 752 Error SetAddressMode(AddressMode aMode); 753 754 /** 755 * This method gets the sequence number used with anycast address mode. 756 * 757 * The sequence number is included in "DNS/SRP Service Anycast Address" entry published in the Network Data. 758 * 759 * @returns The anycast sequence number. 760 * 761 */ GetAnycastModeSequenceNumber(void) const762 uint8_t GetAnycastModeSequenceNumber(void) const { return mAnycastSequenceNumber; } 763 764 /** 765 * This method sets the sequence number used with anycast address mode. 766 * 767 * @param[in] aSequenceNumber The sequence number to use. 768 * 769 * @retval kErrorNone Successfully set the address mode. 770 * @retval kErrorInvalidState The SRP server is enabled and the sequence number cannot be changed. 771 * 772 */ 773 Error SetAnycastModeSequenceNumber(uint8_t aSequenceNumber); 774 775 /** 776 * This method tells whether the SRP server is currently running. 777 * 778 * @returns A boolean that indicates whether the server is running. 779 * 780 */ IsRunning(void) const781 bool IsRunning(void) const { return (mState == kStateRunning); } 782 783 /** 784 * This method tells the state of the SRP server. 785 * 786 * @returns An enum that represents the state of the server. 787 * 788 */ GetState(void) const789 State GetState(void) const { return mState; } 790 791 /** 792 * This method tells the port the SRP server is listening to. 793 * 794 * @returns An integer that represents the port of the server. It returns 0 if the SRP server is not running. 795 * 796 */ GetPort(void) const797 uint16_t GetPort(void) const { return IsRunning() ? mPort : 0; } 798 799 /** 800 * This method enables/disables the SRP server. 801 * 802 * @param[in] aEnabled A boolean to enable/disable the SRP server. 803 * 804 */ 805 void SetEnabled(bool aEnabled); 806 807 /** 808 * This method returns the TTL configuration. 809 * 810 * @param[out] aTtlConfig A reference to the `TtlConfig` instance. 811 * 812 */ GetTtlConfig(TtlConfig & aTtlConfig) const813 void GetTtlConfig(TtlConfig &aTtlConfig) const { aTtlConfig = mTtlConfig; } 814 815 /** 816 * This method sets the TTL configuration. 817 * 818 * @param[in] aTtlConfig A reference to the `TtlConfig` instance. 819 * 820 * @retval kErrorNone Successfully set the TTL configuration 821 * @retval kErrorInvalidArgs The TTL range is not valid. 822 * 823 */ 824 Error SetTtlConfig(const TtlConfig &aTtlConfig); 825 826 /** 827 * This method returns the LEASE and KEY-LEASE configurations. 828 * 829 * @param[out] aLeaseConfig A reference to the `LeaseConfig` instance. 830 * 831 */ GetLeaseConfig(LeaseConfig & aLeaseConfig) const832 void GetLeaseConfig(LeaseConfig &aLeaseConfig) const { aLeaseConfig = mLeaseConfig; } 833 834 /** 835 * This method sets the LEASE and KEY-LEASE configurations. 836 * 837 * When a LEASE time is requested from a client, the granted value will be 838 * limited in range [aMinLease, aMaxLease]; and a KEY-LEASE will be granted 839 * in range [aMinKeyLease, aMaxKeyLease]. 840 * 841 * @param[in] aLeaseConfig A reference to the `LeaseConfig` instance. 842 * 843 * @retval kErrorNone Successfully set the LEASE and KEY-LEASE ranges. 844 * @retval kErrorInvalidArgs The LEASE or KEY-LEASE range is not valid. 845 * 846 */ 847 Error SetLeaseConfig(const LeaseConfig &aLeaseConfig); 848 849 /** 850 * This method returns the next registered SRP host. 851 * 852 * @param[in] aHost The current SRP host; use `nullptr` to get the first SRP host. 853 * 854 * @returns A pointer to the next SRP host or `nullptr` if no more SRP hosts can be found. 855 * 856 */ 857 const Host *GetNextHost(const Host *aHost); 858 859 /** 860 * This method returns the response counters of the SRP server. 861 * 862 * @returns A pointer to the response counters of the SRP server. 863 * 864 */ GetResponseCounters(void) const865 const otSrpServerResponseCounters *GetResponseCounters(void) const { return &mResponseCounters; } 866 867 /** 868 * This method receives the service update result from service handler set by 869 * SetServiceHandler. 870 * 871 * @param[in] aId The ID of the service update transaction. 872 * @param[in] aError The service update result. 873 * 874 */ 875 void HandleServiceUpdateResult(ServiceUpdateId aId, Error aError); 876 877 private: 878 static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header); 879 880 static constexpr uint32_t kDefaultMinTtl = 60u; // 1 min (in seconds). 881 static constexpr uint32_t kDefaultMaxTtl = 3600u * 2; // 2 hours (in seconds). 882 static constexpr uint32_t kDefaultMinLease = 60u * 30; // 30 min (in seconds). 883 static constexpr uint32_t kDefaultMaxLease = 3600u * 2; // 2 hours (in seconds). 884 static constexpr uint32_t kDefaultMinKeyLease = 3600u * 24; // 1 day (in seconds). 885 static constexpr uint32_t kDefaultMaxKeyLease = 3600u * 24 * 14; // 14 days (in seconds). 886 static constexpr uint32_t kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT; 887 888 static constexpr AddressMode kDefaultAddressMode = 889 static_cast<AddressMode>(OPENTHREAD_CONFIG_SRP_SERVER_DEFAULT_ADDDRESS_MODE); 890 891 static constexpr uint16_t kAnycastAddressModePort = 53; 892 893 // Metdata for a received SRP Update message. 894 struct MessageMetadata 895 { 896 // Indicates whether the `Message` is received directly from a 897 // client or from an SRPL partner. IsDirectRxFromClientot::Srp::Server::MessageMetadata898 bool IsDirectRxFromClient(void) const { return (mMessageInfo != nullptr); } 899 900 Dns::UpdateHeader mDnsHeader; 901 Dns::Zone mDnsZone; 902 uint16_t mOffset; 903 TimeMilli mRxTime; 904 TtlConfig mTtlConfig; 905 LeaseConfig mLeaseConfig; 906 const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL. 907 }; 908 909 // This class includes metadata for processing a SRP update (register, deregister) 910 // and sending DNS response to the client. 911 class UpdateMetadata : public InstanceLocator, 912 public LinkedListEntry<UpdateMetadata>, 913 public Heap::Allocatable<UpdateMetadata> 914 { 915 friend class LinkedListEntry<UpdateMetadata>; 916 friend class Heap::Allocatable<UpdateMetadata>; 917 918 public: GetExpireTime(void) const919 TimeMilli GetExpireTime(void) const { return mExpireTime; } GetDnsHeader(void) const920 const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; } GetId(void) const921 ServiceUpdateId GetId(void) const { return mId; } GetTtlConfig(void) const922 const TtlConfig & GetTtlConfig(void) const { return mTtlConfig; } GetLeaseConfig(void) const923 const LeaseConfig & GetLeaseConfig(void) const { return mLeaseConfig; } GetHost(void)924 Host & GetHost(void) { return mHost; } GetMessageInfo(void) const925 const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; } IsDirectRxFromClient(void) const926 bool IsDirectRxFromClient(void) const { return mIsDirectRxFromClient; } Matches(ServiceUpdateId aId) const927 bool Matches(ServiceUpdateId aId) const { return mId == aId; } 928 929 private: 930 UpdateMetadata(Instance &aInstance, Host &aHost, const MessageMetadata &aMessageMetadata); 931 932 UpdateMetadata * mNext; 933 TimeMilli mExpireTime; 934 Dns::UpdateHeader mDnsHeader; 935 ServiceUpdateId mId; // The ID of this service update transaction. 936 TtlConfig mTtlConfig; // TTL config to use when processing the message. 937 LeaseConfig mLeaseConfig; // Lease config to use when processing the message. 938 Host & mHost; // The `UpdateMetadata` has no ownership of this host. 939 Ip6::MessageInfo mMessageInfo; // Valid when `mIsDirectRxFromClient` is true. 940 bool mIsDirectRxFromClient; 941 }; 942 943 void Start(void); 944 void Stop(void); 945 void SelectPort(void); 946 void PrepareSocket(void); 947 Ip6::Udp::Socket &GetSocket(void); 948 949 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 950 void HandleDnssdServerStateChange(void); 951 Error HandleDnssdServerUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 952 #endif 953 954 void HandleNetDataPublisherEvent(NetworkData::Publisher::Event aEvent); 955 AllocateId(void)956 ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; } 957 958 void InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata); 959 void CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata); 960 void CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata); 961 void CommitSrpUpdate(Error aError, 962 Host & aHost, 963 const Dns::UpdateHeader &aDnsHeader, 964 const Ip6::MessageInfo * aMessageInfo, 965 const TtlConfig & aTtlConfig, 966 const LeaseConfig & aLeaseConfig); 967 Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 968 Error ProcessMessage(Message & aMessage, 969 TimeMilli aRxTime, 970 const TtlConfig & aTtlConfig, 971 const LeaseConfig & aLeaseConfig, 972 const Ip6::MessageInfo *aMessageInfo); 973 void ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata); 974 Error ProcessUpdateSection(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const; 975 Error ProcessAdditionalSection(Host *aHost, const Message &aMessage, MessageMetadata &aMetadata) const; 976 Error VerifySignature(const Dns::Ecdsa256KeyRecord &aKeyRecord, 977 const Message & aMessage, 978 Dns::UpdateHeader aDnsHeader, 979 uint16_t aSigOffset, 980 uint16_t aSigRdataOffset, 981 uint16_t aSigRdataLength, 982 const char * aSignerName) const; 983 Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata); 984 Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const; 985 Error ProcessHostDescriptionInstruction(Host & aHost, 986 const Message & aMessage, 987 const MessageMetadata &aMetadata) const; 988 Error ProcessServiceDiscoveryInstructions(Host & aHost, 989 const Message & aMessage, 990 const MessageMetadata &aMetadata) const; 991 Error ProcessServiceDescriptionInstructions(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const; 992 993 static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord); 994 995 void HandleUpdate(Host &aHost, const MessageMetadata &aMetadata); 996 void AddHost(Host &aHost); 997 void RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler); 998 bool HasNameConflictsWith(Host &aHost) const; 999 void SendResponse(const Dns::UpdateHeader & aHeader, 1000 Dns::UpdateHeader::Response aResponseCode, 1001 const Ip6::MessageInfo & aMessageInfo); 1002 void SendResponse(const Dns::UpdateHeader &aHeader, 1003 uint32_t aLease, 1004 uint32_t aKeyLease, 1005 const Ip6::MessageInfo & aMessageInfo); 1006 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 1007 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 1008 static void HandleLeaseTimer(Timer &aTimer); 1009 void HandleLeaseTimer(void); 1010 static void HandleOutstandingUpdatesTimer(Timer &aTimer); 1011 void HandleOutstandingUpdatesTimer(void); 1012 1013 void HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError); 1014 const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const; 1015 static const char * AddressModeToString(AddressMode aMode); 1016 1017 void UpdateResponseCounters(Dns::Header::Response aResponseCode); 1018 1019 Ip6::Udp::Socket mSocket; 1020 otSrpServerServiceUpdateHandler mServiceUpdateHandler; 1021 void * mServiceUpdateHandlerContext; 1022 1023 Heap::String mDomain; 1024 1025 TtlConfig mTtlConfig; 1026 LeaseConfig mLeaseConfig; 1027 1028 LinkedList<Host> mHosts; 1029 TimerMilli mLeaseTimer; 1030 1031 TimerMilli mOutstandingUpdatesTimer; 1032 LinkedList<UpdateMetadata> mOutstandingUpdates; 1033 1034 ServiceUpdateId mServiceUpdateId; 1035 uint16_t mPort; 1036 State mState; 1037 AddressMode mAddressMode; 1038 uint8_t mAnycastSequenceNumber; 1039 bool mHasRegisteredAnyService : 1; 1040 1041 otSrpServerResponseCounters mResponseCounters; 1042 }; 1043 1044 } // namespace Srp 1045 1046 DefineCoreType(otSrpServerTtlConfig, Srp::Server::TtlConfig); 1047 DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig); 1048 DefineCoreType(otSrpServerHost, Srp::Server::Host); 1049 DefineCoreType(otSrpServerService, Srp::Server::Service); 1050 DefineMapEnum(otSrpServerState, Srp::Server::State); 1051 DefineMapEnum(otSrpServerAddressMode, Srp::Server::AddressMode); 1052 1053 } // namespace ot 1054 1055 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 1056 #endif // NET_SRP_SERVER_HPP_ 1057