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