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/clearable.hpp" 57 #include "common/heap_string.hpp" 58 #include "common/linked_list.hpp" 59 #include "common/locator.hpp" 60 #include "common/non_copyable.hpp" 61 #include "common/notifier.hpp" 62 #include "common/timer.hpp" 63 #include "crypto/ecdsa.hpp" 64 #include "net/dns_types.hpp" 65 #include "net/ip6.hpp" 66 #include "net/ip6_address.hpp" 67 #include "net/udp6.hpp" 68 #include "thread/network_data_publisher.hpp" 69 70 namespace ot { 71 namespace Srp { 72 73 /** 74 * This class implements the SRP server. 75 * 76 */ 77 class Server : public InstanceLocator, private NonCopyable 78 { 79 friend class NetworkData::Publisher; 80 friend class UpdateMetadata; 81 friend class Service; 82 friend class Host; 83 84 public: 85 static constexpr uint16_t kUdpPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN; ///< The reserved min port. 86 static constexpr uint16_t kUdpPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX; ///< The reserved max port. 87 88 static_assert(kUdpPortMin <= kUdpPortMax, "invalid port range"); 89 90 /** 91 * The ID of SRP service update transaction. 92 * 93 */ 94 typedef otSrpServerServiceUpdateId ServiceUpdateId; 95 96 class Host; 97 98 enum State : uint8_t 99 { 100 kStateDisabled = OT_SRP_SERVER_STATE_DISABLED, 101 kStateRunning = OT_SRP_SERVER_STATE_RUNNING, 102 kStateStopped = OT_SRP_SERVER_STATE_STOPPED, 103 }; 104 105 /** 106 * This class implements a server-side SRP service. 107 * 108 */ 109 class Service : public LinkedListEntry<Service>, private NonCopyable 110 { 111 friend class Server; 112 friend class LinkedList<Service>; 113 friend class LinkedListEntry<Service>; 114 115 public: 116 /** 117 * This type represents the flags which indicates which services to include or exclude when searching in (or 118 * iterating over) the list of SRP services. 119 * 120 */ 121 typedef otSrpServerServiceFlags Flags; 122 123 /** 124 * This `Flags` constant indicates to include base services (not a sub-type). 125 * 126 */ 127 static constexpr Flags kFlagBaseType = OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE; 128 129 /** 130 * This `Flags` constant indicates to include sub-type services. 131 * 132 */ 133 static constexpr Flags kFlagSubType = OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE; 134 135 /** 136 * This `Flags` constant indicates to include active (not deleted) services. 137 * 138 */ 139 static constexpr Flags kFlagActive = OT_SRP_SERVER_SERVICE_FLAG_ACTIVE; 140 141 /** 142 * This `Flags` constant indicates to include deleted services. 143 * 144 */ 145 static constexpr Flags kFlagDeleted = OT_SRP_SERVER_SERVICE_FLAG_DELETED; 146 147 /** 148 * This method tells if the SRP service has been deleted. 149 * 150 * A SRP service can be deleted but retains its name for future uses. 151 * In this case, the service instance is not removed from the SRP server/registry. 152 * It is guaranteed that all services are deleted if the host is deleted. 153 * 154 * @returns TRUE if the service has been deleted, FALSE if not. 155 * 156 */ IsDeleted(void) const157 bool IsDeleted(void) const { return mIsDeleted; } 158 159 /** 160 * This method indicates whether the SRP service is a sub-type. 161 * 162 * @retval TRUE If the service is a sub-type. 163 * @retval FALSE If the service is not a sub-type. 164 * 165 */ IsSubType(void) const166 bool IsSubType(void) const { return mIsSubType; } 167 168 /** 169 * This method gets the full service instance name of the service. 170 * 171 * @returns A pointer service instance name (as a null-terminated C string). 172 * 173 */ GetInstanceName(void) const174 const char *GetInstanceName(void) const { return mDescription.mInstanceName.AsCString(); } 175 176 /** 177 * This method gets the full service name of the service. 178 * 179 * @returns A pointer service name (as a null-terminated C string). 180 * 181 */ GetServiceName(void) const182 const char *GetServiceName(void) const { return mServiceName.AsCString(); } 183 184 /** 185 * This method gets the sub-type label from service name. 186 * 187 * The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This 188 * method copies the `<sub-label>` into the @p aLabel buffer. 189 * 190 * The @p aLabel is ensured to always be null-terminated after returning even in case of failure. 191 * 192 * @param[out] aLabel A pointer to a buffer to copy the sub-type label name. 193 * @param[in] aMaxSize Maximum size of @p aLabel buffer. 194 * 195 * @retval kErrorNone @p aLabel was updated successfully. 196 * @retval kErrorNoBufs The sub-type label could not fit in @p aLabel buffer (number of chars from label 197 * that could fit are copied in @p aLabel ensuring it is null-terminated). 198 * @retval kErrorInvalidArgs SRP service is not a sub-type. 199 * 200 */ 201 Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const; 202 203 /** 204 * This method returns the port of the service instance. 205 * 206 * @returns The port of the service. 207 * 208 */ GetPort(void) const209 uint16_t GetPort(void) const { return mDescription.mPort; } 210 211 /** 212 * This method returns the weight of the service instance. 213 * 214 * @returns The weight of the service. 215 * 216 */ GetWeight(void) const217 uint16_t GetWeight(void) const { return mDescription.mWeight; } 218 219 /** 220 * This method returns the priority of the service instance. 221 * 222 * @param[in] aService A pointer to the SRP service. 223 * 224 * @returns The priority of the service. 225 * 226 */ GetPriority(void) const227 uint16_t GetPriority(void) const { return mDescription.mPriority; } 228 229 /** 230 * This method returns the TXT record data of the service instance. 231 * 232 * @returns A pointer to the buffer containing the TXT record data. 233 * 234 */ GetTxtData(void) const235 const uint8_t *GetTxtData(void) const { return mDescription.mTxtData; } 236 237 /** 238 * This method returns the TXT record data length of the service instance. 239 * 240 * @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`). 241 * 242 */ GetTxtDataLength(void) const243 uint16_t GetTxtDataLength(void) const { return mDescription.mTxtLength; } 244 245 /** 246 * This method returns the host which the service instance reside on. 247 * 248 * @returns A reference to the host instance. 249 * 250 */ GetHost(void) const251 const Host &GetHost(void) const { return mDescription.mHost; } 252 253 /** 254 * This method returns the expire time (in milliseconds) of the service. 255 * 256 * @returns The service expire time in milliseconds. 257 * 258 */ 259 TimeMilli GetExpireTime(void) const; 260 261 /** 262 * This method returns the key expire time (in milliseconds) of the service. 263 * 264 * @returns The service key expire time in milliseconds. 265 * 266 */ 267 TimeMilli GetKeyExpireTime(void) const; 268 269 /** 270 * This method indicates whether this service matches a given service instance name. 271 * 272 * @param[in] aInstanceName The service instance name. 273 * 274 * @retval TRUE If the service matches the service instance name. 275 * @retval FALSE If the service does not match the service instance name. 276 * 277 */ MatchesInstanceName(const char * aInstanceName) const278 bool MatchesInstanceName(const char *aInstanceName) const 279 { 280 return (mDescription.mInstanceName == aInstanceName); 281 } 282 283 /** 284 * This method tells whether this service matches a given service name. 285 * 286 * @param[in] aServiceName The full service name to match. 287 * 288 * @retval TRUE If the service matches the full service name. 289 * @retval FALSE If the service does not match the full service name. 290 * 291 */ MatchesServiceName(const char * aServiceName) const292 bool MatchesServiceName(const char *aServiceName) const { return (mServiceName == aServiceName); } 293 294 private: 295 struct Description : public LinkedListEntry<Description>, private NonCopyable 296 { 297 static Description *New(const char *aInstanceName, Host &aHost); 298 299 explicit Description(Host &aHost); 300 void Free(void); GetInstanceNameot::Srp::Server::Service::Description301 const char *GetInstanceName(void) const { return mInstanceName.AsCString(); } Matchesot::Srp::Server::Service::Description302 bool Matches(const char *aInstanceName) const { return (mInstanceName == aInstanceName); } 303 void ClearResources(void); 304 void TakeResourcesFrom(Description &aDescription); 305 Error SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength); 306 307 Description *mNext; 308 HeapString mInstanceName; 309 Host & mHost; 310 uint16_t mPriority; 311 uint16_t mWeight; 312 uint16_t mPort; 313 uint16_t mTxtLength; 314 uint8_t * mTxtData; 315 uint32_t mLease; // The LEASE time in seconds. 316 uint32_t mKeyLease; // The KEY-LEASE time in seconds. 317 TimeMilli mTimeLastUpdate; 318 }; 319 320 enum Action : uint8_t 321 { 322 kAddNew, 323 kUpdateExisting, 324 kRemoveButRetainName, 325 kFullyRemove, 326 kLeaseExpired, 327 kKeyLeaseExpired, 328 }; 329 330 static Service *New(const char *aServiceName, Description &aDescription, bool aIsSubType); 331 332 Service(Description &aDescription, bool aIsSubType); 333 334 void Free(void); 335 bool MatchesFlags(Flags aFlags) const; 336 void Log(Action aAction) const; 337 338 HeapString mServiceName; 339 Description &mDescription; 340 Service * mNext; 341 TimeMilli mTimeLastUpdate; 342 bool mIsDeleted : 1; 343 bool mIsSubType : 1; 344 bool mIsCommitted : 1; 345 }; 346 347 /** 348 * This class implements the Host which registers services on the SRP server. 349 * 350 */ 351 class Host : public LinkedListEntry<Host>, public InstanceLocator, private NonCopyable 352 { 353 friend class LinkedListEntry<Host>; 354 friend class Server; 355 356 public: 357 /** 358 * This method tells whether the Host object has been deleted. 359 * 360 * The Host object retains event if the host has been deleted by the SRP client, 361 * because the host name may retain. 362 * 363 * @returns TRUE if the host is deleted, FALSE if the host is not deleted. 364 * 365 */ IsDeleted(void) const366 bool IsDeleted(void) const { return (mLease == 0); } 367 368 /** 369 * This method returns the full name of the host. 370 * 371 * @returns A pointer to the null-terminated full host name. 372 * 373 */ GetFullName(void) const374 const char *GetFullName(void) const { return mFullName.AsCString(); } 375 376 /** 377 * This method returns addresses of the host. 378 * 379 * @param[out] aAddressesNum The number of the addresses. 380 * 381 * @returns A pointer to the addresses array. 382 * 383 */ GetAddresses(uint8_t & aAddressesNum) const384 const Ip6::Address *GetAddresses(uint8_t &aAddressesNum) const 385 { 386 aAddressesNum = mAddressesNum; 387 return mAddresses; 388 } 389 390 /** 391 * This method returns the LEASE time of the host. 392 * 393 * @returns The LEASE time in seconds. 394 * 395 */ GetLease(void) const396 uint32_t GetLease(void) const { return mLease; } 397 398 /** 399 * This method returns the KEY-LEASE time of the key of the host. 400 * 401 * @returns The KEY-LEASE time in seconds. 402 * 403 */ GetKeyLease(void) const404 uint32_t GetKeyLease(void) const { return mKeyLease; } 405 406 /** 407 * This method returns the KEY resource of the host. 408 * 409 * @returns A pointer to the ECDSA P 256 public key if there is valid one. 410 * nullptr if no valid key exists. 411 * 412 */ GetKey(void) const413 const Dns::Ecdsa256KeyRecord *GetKey(void) const { return mKey.IsValid() ? &mKey : nullptr; } 414 415 /** 416 * This method returns the expire time (in milliseconds) of the host. 417 * 418 * @returns The expire time in milliseconds. 419 * 420 */ 421 TimeMilli GetExpireTime(void) const; 422 423 /** 424 * This method returns the expire time (in milliseconds) of the key of the host. 425 * 426 * @returns The expire time of the key in milliseconds. 427 * 428 */ 429 TimeMilli GetKeyExpireTime(void) const; 430 431 /** 432 * This method returns the `Service` linked list associated with the host. 433 * 434 * @returns The `Service` linked list. 435 * 436 */ GetServices(void) const437 const LinkedList<Service> &GetServices(void) const { return mServices; } 438 439 /** 440 * This method finds the next matching service on the host. 441 * 442 * @param[in] aPrevService A pointer to the previous service or `nullptr` to start from beginning of the list. 443 * @param[in] aFlags Flags indicating which services to include (base/sub-type, active/deleted). 444 * @param[in] aServiceName The service name to match. Set to `nullptr` to accept any name. 445 * @param[in] aInstanceName The service instance name to match. Set to `nullptr` to accept any name. 446 * 447 * @returns A pointer to the next matching service or `nullptr` if no matching service could be found. 448 * 449 */ 450 const Service *FindNextService(const Service *aPrevService, 451 Service::Flags aFlags = kFlagsAnyService, 452 const char * aServiceName = nullptr, 453 const char * aInstanceName = nullptr) const; 454 455 /** 456 * This method tells whether the host matches a given full name. 457 * 458 * @param[in] aFullName The full name. 459 * 460 * @returns A boolean that indicates whether the host matches the given name. 461 * 462 */ Matches(const char * aFullName) const463 bool Matches(const char *aFullName) const { return (mFullName == aFullName); } 464 465 private: 466 static constexpr uint16_t kMaxAddressesNum = OPENTHREAD_CONFIG_SRP_SERVER_MAX_ADDRESSES_NUM; 467 468 static Host *New(Instance &aInstance); 469 470 explicit Host(Instance &aInstance); 471 void Free(void); 472 Error SetFullName(const char *aFullName); 473 void SetKey(Dns::Ecdsa256KeyRecord &aKey); SetLease(uint32_t aLease)474 void SetLease(uint32_t aLease) { mLease = aLease; } SetKeyLease(uint32_t aKeyLease)475 void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; } GetServices(void)476 LinkedList<Service> & GetServices(void) { return mServices; } 477 Service * AddNewService(const char *aServiceName, const char *aInstanceName, bool aIsSubType); 478 void RemoveService(Service *aService, bool aRetainName, bool aNotifyServiceHandler); 479 void FreeAllServices(void); 480 void FreeUnusedServiceDescriptions(void); 481 void ClearResources(void); 482 Error MergeServicesAndResourcesFrom(Host &aHost); 483 Error AddIp6Address(const Ip6::Address &aIp6Address); 484 Service::Description * FindServiceDescription(const char *aInstanceName); 485 const Service::Description *FindServiceDescription(const char *aInstanceName) const; 486 Service * FindService(const char *aServiceName, const char *aInstanceName); 487 const Service * FindService(const char *aServiceName, const char *aInstanceName) const; 488 489 HeapString mFullName; 490 Ip6::Address mAddresses[kMaxAddressesNum]; 491 uint8_t mAddressesNum; 492 Host * mNext; 493 494 Dns::Ecdsa256KeyRecord mKey; 495 uint32_t mLease; // The LEASE time in seconds. 496 uint32_t mKeyLease; // The KEY-LEASE time in seconds. 497 TimeMilli mTimeLastUpdate; 498 LinkedList<Service> mServices; 499 LinkedList<Service::Description> mServiceDescriptions; 500 }; 501 502 /** 503 * This class handles LEASE and KEY-LEASE configurations. 504 * 505 */ 506 class LeaseConfig : public otSrpServerLeaseConfig 507 { 508 friend class Server; 509 510 public: 511 /** 512 * This constructor initialize to default LEASE and KEY-LEASE configurations. 513 * 514 */ 515 LeaseConfig(void); 516 517 private: 518 bool IsValid(void) const; 519 uint32_t GrantLease(uint32_t aLease) const; 520 uint32_t GrantKeyLease(uint32_t aKeyLease) const; 521 }; 522 523 /** 524 * This constant defines a `Service::Flags` combination accepting any service (base/sub-type, active/deleted). 525 * 526 */ 527 static constexpr Service::Flags kFlagsAnyService = OT_SRP_SERVER_FLAGS_ANY_SERVICE; 528 529 /** 530 * This constant defines a `Service::Flags` combination accepting base services only. 531 * 532 */ 533 static constexpr Service::Flags kFlagsBaseTypeServiceOnly = OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY; 534 535 /** 536 * This constant defines a `Service::Flags` combination accepting sub-type services only. 537 * 538 */ 539 static constexpr Service::Flags kFlagsSubTypeServiceOnly = OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY; 540 541 /** 542 * This constant defines a `Service::Flags` combination accepting any active services (not deleted). 543 * 544 */ 545 static constexpr Service::Flags kFlagsAnyTypeActiveService = OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE; 546 547 /** 548 * This constant defines a `Service::Flags` combination accepting any deleted services. 549 * 550 */ 551 static constexpr Service::Flags kFlagsAnyTypeDeletedService = OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE; 552 553 /** 554 * This constructor initializes the SRP server object. 555 * 556 * @param[in] aInstance A reference to the OpenThread instance. 557 * 558 */ 559 explicit Server(Instance &aInstance); 560 561 /** 562 * This method sets the SRP service events handler. 563 * 564 * @param[in] aServiceHandler A service events handler. 565 * @param[in] aServiceHandlerContext A pointer to arbitrary context information. 566 * 567 * @note The handler SHOULD call HandleServiceUpdateResult to report the result of its processing. 568 * Otherwise, a SRP update will be considered failed. 569 * 570 * @sa HandleServiceUpdateResult 571 * 572 */ 573 void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext); 574 575 /** 576 * This method returns the domain authorized to the SRP server. 577 * 578 * If the domain if not set by SetDomain, "default.service.arpa." will be returned. 579 * A trailing dot is always appended even if the domain is set without it. 580 * 581 * @returns A pointer to the dot-joined domain string. 582 * 583 */ GetDomain(void) const584 const char *GetDomain(void) const { return mDomain.AsCString(); } 585 586 /** 587 * This method sets the domain on the SRP server. 588 * 589 * A trailing dot will be appended to @p aDomain if it is not already there. 590 * This method should only be called before the SRP server is enabled. 591 * 592 * @param[in] aDomain The domain to be set. MUST NOT be nullptr. 593 * 594 * @retval kErrorNone Successfully set the domain to @p aDomain. 595 * @retval kErrorInvalidState The SRP server is already enabled and the Domain cannot be changed. 596 * @retval kErrorInvalidArgs The argument @p aDomain is not a valid DNS domain name. 597 * @retval kErrorNoBufs There is no memory to store content of @p aDomain. 598 * 599 */ 600 Error SetDomain(const char *aDomain); 601 602 /** 603 * This method tells whether the SRP server is currently running. 604 * 605 * @returns A boolean that indicates whether the server is running. 606 * 607 */ IsRunning(void) const608 bool IsRunning(void) const { return (mState == kStateRunning); } 609 610 /** 611 * This method tells the state of the SRP server. 612 * 613 * @returns An enum that represents the state of the server. 614 * 615 */ GetState(void) const616 State GetState(void) const { return mState; } 617 618 /** 619 * This method enables/disables the SRP server. 620 * 621 * @param[in] aEnabled A boolean to enable/disable the SRP server. 622 * 623 */ 624 void SetEnabled(bool aEnabled); 625 626 /** 627 * This method returns the LEASE and KEY-LEASE configurations. 628 * 629 * @param[out] aLeaseConfig A reference to the `LeaseConfig` instance. 630 * 631 */ GetLeaseConfig(LeaseConfig & aLeaseConfig) const632 void GetLeaseConfig(LeaseConfig &aLeaseConfig) const { aLeaseConfig = mLeaseConfig; } 633 634 /** 635 * This method sets the LEASE and KEY-LEASE configurations. 636 * 637 * When a LEASE time is requested from a client, the granted value will be 638 * limited in range [aMinLease, aMaxLease]; and a KEY-LEASE will be granted 639 * in range [aMinKeyLease, aMaxKeyLease]. 640 * 641 * @param[in] aLeaseConfig A reference to the `LeaseConfig` instance. 642 * 643 * @retval kErrorNone Successfully set the LEASE and KEY-LEASE ranges. 644 * @retval kErrorInvalidArgs The LEASE or KEY-LEASE range is not valid. 645 * 646 */ 647 Error SetLeaseConfig(const LeaseConfig &aLeaseConfig); 648 649 /** 650 * This method returns the next registered SRP host. 651 * 652 * @param[in] aHost The current SRP host; use nullptr to get the first SRP host. 653 * 654 * @returns A pointer to the next SRP host or nullptr if no more SRP hosts can be found. 655 * 656 */ 657 const Host *GetNextHost(const Host *aHost); 658 659 /** 660 * This method receives the service update result from service handler set by 661 * SetServiceHandler. 662 * 663 * @param[in] aId The ID of the service update transaction. 664 * @param[in] aError The service update result. 665 * 666 */ 667 void HandleServiceUpdateResult(ServiceUpdateId aId, Error aError); 668 669 private: 670 static constexpr uint16_t kUdpPayloadSize = Ip6::Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header); 671 672 static constexpr uint32_t kDefaultMinLease = 60u * 30; // 30 min (in seconds). 673 static constexpr uint32_t kDefaultMaxLease = 3600u * 2; // 2 hours (in seconds). 674 static constexpr uint32_t kDefaultMinKeyLease = 3600u * 24; // 1 day (in seconds). 675 static constexpr uint32_t kDefaultMaxKeyLease = 3600u * 24 * 14; // 14 days (in seconds). 676 static constexpr uint32_t kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT; 677 678 // This class includes metadata for processing a SRP update (register, deregister) 679 // and sending DNS response to the client. 680 class UpdateMetadata : public InstanceLocator, public LinkedListEntry<UpdateMetadata> 681 { 682 friend class LinkedListEntry<UpdateMetadata>; 683 684 public: 685 static UpdateMetadata * New(Instance & aInstance, 686 const Dns::UpdateHeader &aHeader, 687 Host * aHost, 688 const Ip6::MessageInfo & aMessageInfo); 689 void Free(void); GetExpireTime(void) const690 TimeMilli GetExpireTime(void) const { return mExpireTime; } GetDnsHeader(void) const691 const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; } GetId(void) const692 ServiceUpdateId GetId(void) const { return mId; } GetHost(void)693 Host & GetHost(void) { return *mHost; } GetMessageInfo(void) const694 const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; } Matches(ServiceUpdateId aId) const695 bool Matches(ServiceUpdateId aId) const { return mId == aId; } 696 697 private: 698 UpdateMetadata(Instance & aInstance, 699 const Dns::UpdateHeader &aHeader, 700 Host * aHost, 701 const Ip6::MessageInfo & aMessageInfo); 702 703 TimeMilli mExpireTime; 704 Dns::UpdateHeader mDnsHeader; 705 ServiceUpdateId mId; // The ID of this service update transaction. 706 Host * mHost; // The host will be updated. The UpdateMetadata has no ownership of this host. 707 Ip6::MessageInfo mMessageInfo; // The message info of the DNS update request. 708 UpdateMetadata * mNext; 709 }; 710 711 void Start(void); 712 void Stop(void); 713 void SelectPort(void); 714 void HandleNetDataPublisherEvent(NetworkData::Publisher::Event aEvent); 715 AllocateId(void)716 ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; } 717 718 void CommitSrpUpdate(Error aError, 719 const Dns::UpdateHeader &aDnsHeader, 720 Host & aHost, 721 const Ip6::MessageInfo & aMessageInfo); 722 void HandleDnsUpdate(Message & aMessage, 723 const Ip6::MessageInfo & aMessageInfo, 724 const Dns::UpdateHeader &aDnsHeader, 725 uint16_t aOffset); 726 Error ProcessUpdateSection(Host & aHost, 727 const Message & aMessage, 728 const Dns::UpdateHeader &aDnsHeader, 729 const Dns::Zone & aZone, 730 uint16_t & aOffset) const; 731 Error ProcessAdditionalSection(Host * aHost, 732 const Message & aMessage, 733 const Dns::UpdateHeader &aDnsHeader, 734 uint16_t & aOffset) const; 735 Error VerifySignature(const Dns::Ecdsa256KeyRecord &aKey, 736 const Message & aMessage, 737 Dns::UpdateHeader aDnsHeader, 738 uint16_t aSigOffset, 739 uint16_t aSigRdataOffset, 740 uint16_t aSigRdataLength, 741 const char * aSignerName) const; 742 Error ProcessZoneSection(const Message & aMessage, 743 const Dns::UpdateHeader &aDnsHeader, 744 uint16_t & aOffset, 745 Dns::Zone & aZone) const; 746 Error ProcessHostDescriptionInstruction(Host & aHost, 747 const Message & aMessage, 748 const Dns::UpdateHeader &aDnsHeader, 749 const Dns::Zone & aZone, 750 uint16_t aOffset) const; 751 Error ProcessServiceDiscoveryInstructions(Host & aHost, 752 const Message & aMessage, 753 const Dns::UpdateHeader &aDnsHeader, 754 const Dns::Zone & aZone, 755 uint16_t aOffset) const; 756 Error ProcessServiceDescriptionInstructions(Host & aHost, 757 const Message & aMessage, 758 const Dns::UpdateHeader &aDnsHeader, 759 const Dns::Zone & aZone, 760 uint16_t & aOffset) const; 761 762 static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord); 763 764 void HandleUpdate(const Dns::UpdateHeader &aDnsHeader, Host &aHost, const Ip6::MessageInfo &aMessageInfo); 765 void AddHost(Host &aHost); 766 void RemoveHost(Host *aHost, bool aRetainName, bool aNotifyServiceHandler); 767 bool HasNameConflictsWith(Host &aHost) const; 768 void SendResponse(const Dns::UpdateHeader & aHeader, 769 Dns::UpdateHeader::Response aResponseCode, 770 const Ip6::MessageInfo & aMessageInfo); 771 void SendResponse(const Dns::UpdateHeader &aHeader, 772 uint32_t aLease, 773 uint32_t aKeyLease, 774 const Ip6::MessageInfo & aMessageInfo); 775 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 776 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 777 static void HandleLeaseTimer(Timer &aTimer); 778 void HandleLeaseTimer(void); 779 static void HandleOutstandingUpdatesTimer(Timer &aTimer); 780 void HandleOutstandingUpdatesTimer(void); 781 782 void HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError); 783 const UpdateMetadata *FindOutstandingUpdate(const Ip6::MessageInfo &aMessageInfo, uint16_t aDnsMessageId); 784 785 Ip6::Udp::Socket mSocket; 786 otSrpServerServiceUpdateHandler mServiceUpdateHandler; 787 void * mServiceUpdateHandlerContext; 788 789 HeapString mDomain; 790 791 LeaseConfig mLeaseConfig; 792 793 LinkedList<Host> mHosts; 794 TimerMilli mLeaseTimer; 795 796 TimerMilli mOutstandingUpdatesTimer; 797 LinkedList<UpdateMetadata> mOutstandingUpdates; 798 799 ServiceUpdateId mServiceUpdateId; 800 uint16_t mPort; 801 State mState; 802 bool mHasRegisteredAnyService : 1; 803 }; 804 805 } // namespace Srp 806 } // namespace ot 807 808 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 809 #endif // NET_SRP_SERVER_HPP_ 810