1 /* 2 * Copyright (c) 2021, 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 related to Thread Network Data service/server entries. 32 */ 33 34 #ifndef NETWORK_DATA_SERVICE_HPP_ 35 #define NETWORK_DATA_SERVICE_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/netdata.h> 40 41 #include "backbone_router/bbr_leader.hpp" 42 #include "common/encoding.hpp" 43 #include "common/locator.hpp" 44 #include "common/non_copyable.hpp" 45 #include "common/serial_number.hpp" 46 #include "net/socket.hpp" 47 #include "thread/network_data_tlvs.hpp" 48 49 namespace ot { 50 namespace NetworkData { 51 namespace Service { 52 53 const uint32_t kThreadEnterpriseNumber = ServiceTlv::kThreadEnterpriseNumber; ///< Thread enterprise number. 54 55 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 56 57 /** 58 * Implements Thread Network Data "Backbone Router Service" server data generation and parsing. 59 * 60 */ 61 class BackboneRouter 62 { 63 public: 64 /** 65 * This constant variable represents the Backbone Router service data. 66 * 67 * The service data contains only the service number (THREAD_SERVICE_DATA_BBR) as a single byte. 68 * 69 */ 70 static const uint8_t kServiceData = 0x01; 71 static constexpr uint8_t kServiceDataMinSize = 1; 72 73 /** 74 * Implements the generation and parsing of "Backbone Router Service" server data. 75 * 76 */ 77 OT_TOOL_PACKED_BEGIN 78 class ServerData 79 { 80 public: 81 /** 82 * Returns the length (in bytes) of server data. 83 * 84 * @returns The server data length in bytes. 85 * 86 */ GetLength(void) const87 uint8_t GetLength(void) const { return sizeof(ServerData); } 88 89 /** 90 * Returns the sequence number of Backbone Router. 91 * 92 * @returns The sequence number of the Backbone Router. 93 * 94 */ GetSequenceNumber(void) const95 uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } 96 97 /** 98 * Sets the sequence number of Backbone Router. 99 * 100 * @param[in] aSequenceNumber The sequence number of Backbone Router. 101 * 102 */ SetSequenceNumber(uint8_t aSequenceNumber)103 void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; } 104 105 /** 106 * Returns the Registration Delay (in seconds) of Backbone Router. 107 * 108 * @returns The BBR Registration Delay (in seconds) of Backbone Router. 109 * 110 */ GetReregistrationDelay(void) const111 uint16_t GetReregistrationDelay(void) const { return BigEndian::HostSwap16(mReregistrationDelay); } 112 113 /** 114 * Sets the Registration Delay (in seconds) of Backbone Router. 115 * 116 * @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router. 117 * 118 */ SetReregistrationDelay(uint16_t aReregistrationDelay)119 void SetReregistrationDelay(uint16_t aReregistrationDelay) 120 { 121 mReregistrationDelay = BigEndian::HostSwap16(aReregistrationDelay); 122 } 123 124 /** 125 * Returns the multicast listener report timeout (in seconds) of Backbone Router. 126 * 127 * @returns The multicast listener report timeout (in seconds) of Backbone Router. 128 * 129 */ GetMlrTimeout(void) const130 uint32_t GetMlrTimeout(void) const { return BigEndian::HostSwap32(mMlrTimeout); } 131 132 /** 133 * Sets multicast listener report timeout (in seconds) of Backbone Router. 134 * 135 * @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router. 136 * 137 */ SetMlrTimeout(uint32_t aMlrTimeout)138 void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = BigEndian::HostSwap32(aMlrTimeout); } 139 140 private: 141 uint8_t mSequenceNumber; 142 uint16_t mReregistrationDelay; 143 uint32_t mMlrTimeout; 144 } OT_TOOL_PACKED_END; 145 146 BackboneRouter(void) = delete; 147 }; 148 149 #endif // #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 150 151 /** 152 * Implements Thread Network Data "DNS/SRP Service Anycast Address" generation and parsing. 153 * 154 */ 155 class DnsSrpAnycast 156 { 157 public: 158 static constexpr uint8_t kServiceNumber = 0x5c; ///< The service number of a `DnsSrpAnycast` entry. 159 160 /** 161 * This constant variable represents the short version of service data. 162 * 163 * The short version of service data contains only service number as a single byte. 164 * 165 */ 166 static const uint8_t kServiceData = kServiceNumber; 167 168 /** 169 * Represents information about an DNS/SRP server parsed from related Network Data service entries. 170 * 171 */ 172 struct Info 173 { 174 Ip6::Address mAnycastAddress; ///< The anycast address associated with the DNS/SRP servers. 175 uint8_t mSequenceNumber; ///< Sequence number used to notify SRP client if they need to re-register. 176 }; 177 178 /** 179 * Represents the "DNS/SRP Service (Anycast)" service data. 180 * 181 */ 182 OT_TOOL_PACKED_BEGIN 183 class ServiceData 184 { 185 public: 186 /** 187 * Initializes the `ServiceData` object. 188 * 189 * @param[in] aSequenceNumber The sequence number of "DNS/SRP server" service. 190 * 191 */ ServiceData(uint8_t aSequenceNumber)192 explicit ServiceData(uint8_t aSequenceNumber) 193 : mServiceNumber(kServiceNumber) 194 , mSequenceNumber(aSequenceNumber) 195 { 196 OT_UNUSED_VARIABLE(mServiceNumber); 197 } 198 199 /** 200 * Returns the length (in bytes) of service data. 201 * 202 * @returns The data length in bytes. 203 * 204 */ GetLength(void) const205 uint8_t GetLength(void) const { return sizeof(ServiceData); } 206 207 /** 208 * Returns the sequence number. 209 * 210 * @returns The sequence number. 211 * 212 */ GetSequenceNumber(void) const213 uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } 214 215 private: 216 uint8_t mServiceNumber; 217 uint8_t mSequenceNumber; 218 } OT_TOOL_PACKED_END; 219 220 DnsSrpAnycast(void) = delete; 221 }; 222 223 /** 224 * Implements Thread Network Data DNS/SRP Service (Unicast Address) generation and parsing. 225 * 226 */ 227 class DnsSrpUnicast 228 { 229 public: 230 static constexpr uint8_t kServiceNumber = 0x5d; ///< The service number of `DnsSrpUnicast` entry. 231 232 /** 233 * This constant variable represents the short version of service data. 234 * 235 * The short version of service data contains only service number as a single byte. 236 * 237 */ 238 static const uint8_t kServiceData = kServiceNumber; 239 240 /** 241 * Represents the origin a `DnsSrpUnicast` entry. 242 * 243 */ 244 enum Origin : uint8_t 245 { 246 kFromServiceData, ///< Socket address is from service data. 247 kFromServerData, ///< Socket address is from server data. 248 }; 249 250 /** 251 * Represents information about an DNS/SRP server parsed from related Network Data service entries. 252 * 253 */ 254 struct Info 255 { 256 Ip6::SockAddr mSockAddr; ///< The socket address (IPv6 address and port) of the DNS/SRP server. 257 Origin mOrigin; ///< The origin of the socket address (whether from service or server data). 258 uint16_t mRloc16; ///< The BR RLOC16 adding the entry (only used when `mOrigin == kFromServerData`). 259 }; 260 261 /** 262 * Represents long version of "DNS/SRP Service (Unicast)" service data. 263 * 264 */ 265 OT_TOOL_PACKED_BEGIN 266 class ServiceData 267 { 268 public: 269 /** 270 * Initializes the `ServiceData` object. 271 * 272 * @param[in] aAddress The IPv6 address of DNS/SRP server. 273 * @param[in] aPort The port number of DNS/SRP server. 274 * 275 */ ServiceData(const Ip6::Address & aAddress,uint16_t aPort)276 explicit ServiceData(const Ip6::Address &aAddress, uint16_t aPort) 277 : mServiceNumber(kServiceNumber) 278 , mAddress(aAddress) 279 , mPort(BigEndian::HostSwap16(aPort)) 280 { 281 OT_UNUSED_VARIABLE(mServiceNumber); 282 } 283 284 /** 285 * Returns the length (in bytes) of service data. 286 * 287 * @returns The data length in bytes. 288 * 289 */ GetLength(void) const290 uint8_t GetLength(void) const { return sizeof(ServiceData); } 291 292 /** 293 * Returns the IPv6 address. 294 * 295 * @returns The IPv6 address 296 * 297 */ GetAddress(void) const298 const Ip6::Address &GetAddress(void) const { return mAddress; } 299 300 /** 301 * Returns the port number. 302 * 303 * @returns The port number. 304 * 305 */ GetPort(void) const306 uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); } 307 308 private: 309 uint8_t mServiceNumber; 310 Ip6::Address mAddress; 311 uint16_t mPort; 312 } OT_TOOL_PACKED_END; 313 314 /** 315 * Represents long version of "DNS/SRP Service (Unicast)" server data. 316 * 317 */ 318 OT_TOOL_PACKED_BEGIN 319 class ServerData 320 { 321 public: 322 /** 323 * Initializes the `ServerData` object. 324 * 325 * @param[in] aAddress The IPv6 address of DNS/SRP server. 326 * @param[in] aPort The port number of DNS/SRP server. 327 * 328 */ ServerData(const Ip6::Address & aAddress,uint16_t aPort)329 ServerData(const Ip6::Address &aAddress, uint16_t aPort) 330 : mAddress(aAddress) 331 , mPort(BigEndian::HostSwap16(aPort)) 332 { 333 } 334 335 /** 336 * Returns the length (in bytes) of server data. 337 * 338 * @returns The data length in bytes. 339 * 340 */ GetLength(void) const341 uint8_t GetLength(void) const { return sizeof(ServerData); } 342 343 /** 344 * Returns the IPv6 address. 345 * 346 * @returns The IPv6 address 347 * 348 */ GetAddress(void) const349 const Ip6::Address &GetAddress(void) const { return mAddress; } 350 351 /** 352 * Returns the port number. 353 * 354 * @returns The port number. 355 * 356 */ GetPort(void) const357 uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); } 358 359 private: 360 Ip6::Address mAddress; 361 uint16_t mPort; 362 } OT_TOOL_PACKED_END; 363 364 DnsSrpUnicast(void) = delete; 365 }; 366 367 /** 368 * Manages the Thread Service entries in Thread Network Data. 369 * 370 */ 371 class Manager : public InstanceLocator, private NonCopyable 372 { 373 public: 374 /** 375 * Represents an iterator used to iterate through Network Data Service entries. 376 * 377 */ 378 class Iterator : public Clearable<Iterator> 379 { 380 friend class Manager; 381 382 public: 383 /** 384 * Initializes the iterator (as empty/clear). 385 * 386 */ Iterator(void)387 Iterator(void) 388 : mServiceTlv(nullptr) 389 , mServerSubTlv(nullptr) 390 { 391 } 392 393 /** 394 * Resets the iterator to start from beginning. 395 * 396 */ Reset(void)397 void Reset(void) 398 { 399 mServiceTlv = nullptr; 400 mServerSubTlv = nullptr; 401 } 402 403 private: 404 const ServiceTlv *mServiceTlv; 405 const ServerTlv *mServerSubTlv; 406 }; 407 408 /** 409 * Initializes the `Manager` object. 410 * 411 * @param[in] aInstance A reference to the OpenThread instance. 412 * 413 */ Manager(Instance & aInstance)414 explicit Manager(Instance &aInstance) 415 : InstanceLocator(aInstance) 416 { 417 } 418 419 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 420 /** 421 * Adds a Thread Service entry to the local Thread Network Data. 422 * 423 * This version of `Add<ServiceType>()` is intended for use with a `ServiceType` that has a constant service data 424 * format with a non-empty and potentially non-const server data format (provided as input parameter). 425 * 426 * The template type `ServiceType` has the following requirements: 427 * - It MUST have a constant variable `ServiceType::kServiceData` specifying the service data. 428 * - It MUST define nested type `ServiceType::ServerData` representing the server data (and its format). 429 * - The `ServiceType::ServerData` MUST provide `GetLength()` method returning the length of server data. 430 * 431 * @tparam ServiceType The service type to be added. 432 * 433 * @param[in] aServerData The server data. 434 * @param[in] aServerStable The Stable flag value for Server TLV. 435 * 436 * @retval kErrorNone Successfully added the Service entry. 437 * @retval kErrorNoBufs Insufficient space to add the Service entry. 438 * 439 */ 440 template <typename ServiceType> Add(const typename ServiceType::ServerData & aServerData,bool aServerStable=true)441 Error Add(const typename ServiceType::ServerData &aServerData, bool aServerStable = true) 442 { 443 return AddService(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData), aServerStable, &aServerData, 444 aServerData.GetLength()); 445 } 446 447 /** 448 * Adds a Thread Service entry to the local Thread Network Data. 449 * 450 * This version of `Add<ServiceType>()` is intended for use with a `ServiceType` that has a non-const service data 451 * format (provided as input parameter) with an empty server data. 452 * 453 * The template type `ServiceType` has the following requirements: 454 * - It MUST define nested type `ServiceType::ServiceData` representing the service data (and its format). 455 * - The `ServiceType::ServiceData` MUST provide `GetLength()` method returning the length of service data. 456 * 457 * @tparam ServiceType The service type to be added. 458 * 459 * @param[in] aServiceData The service data. 460 * @param[in] aServerStable The Stable flag value for Server TLV. 461 * 462 * @retval kErrorNone Successfully added the Service entry. 463 * @retval kErrorNoBufs Insufficient space to add the Service entry. 464 * 465 */ 466 template <typename ServiceType> Add(const typename ServiceType::ServiceData & aServiceData,bool aServerStable=true)467 Error Add(const typename ServiceType::ServiceData &aServiceData, bool aServerStable = true) 468 { 469 return AddService(&aServiceData, aServiceData.GetLength(), aServerStable, nullptr, 0); 470 } 471 472 /** 473 * Removes a Thread Service entry from the local Thread Network Data. 474 * 475 * This version of `Remove<SeviceType>()` is intended for use with a `ServiceType` that has a constant service data 476 * format. 477 * 478 * The template type `ServiceType` has the following requirements: 479 * - It MUST have a constant variable `ServiceType::kServiceData` specifying the service data. 480 * 481 * @tparam ServiceType The service type to be removed. 482 * 483 * @retval kErrorNone Successfully removed the Service entry. 484 * @retval kErrorNotFound Could not find the Service entry. 485 * 486 */ Remove(void)487 template <typename ServiceType> Error Remove(void) 488 { 489 return RemoveService(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData)); 490 } 491 492 /** 493 * Removes a Thread Service entry from the local Thread Network Data. 494 * 495 * This version of `Remove<ServiceType>()` is intended for use with a `ServiceType` that has a non-const service 496 * data format (provided as input parameter). 497 * 498 * The template type `ServiceType` has the following requirements: 499 * - It MUST define nested type `ServiceType::ServiceData` representing the service data (and its format). 500 * - The `ServiceType::ServiceData` MUST provide `GetLength()` method returning the length of service data. 501 * 502 * @tparam ServiceType The service type to be removed. 503 * 504 * @param[in] aServiceData The service data. 505 * 506 * @retval kErrorNone Successfully removed the Service entry. 507 * @retval kErrorNotFound Could not find the Service entry. 508 * 509 */ Remove(const typename ServiceType::ServiceData & aServiceData)510 template <typename ServiceType> Error Remove(const typename ServiceType::ServiceData &aServiceData) 511 { 512 return RemoveService(&aServiceData, aServiceData.GetLength()); 513 } 514 515 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 516 517 /** 518 * Gets the Service ID for the specified service from Thread Network Data. 519 * 520 * The template type `ServiceType` has the following requirements: 521 * - It MUST have a constant `ServiceType::kServiceNumber` specifying the service number. 522 * 523 * @tparam ServiceType The service type to be added. 524 * 525 * @param[in] aServerStable The Stable flag value for Server TLV 526 * @param[out] aServiceId A reference where to put the Service ID. 527 * 528 * @retval kErrorNone Successfully got the Service ID. 529 * @retval kErrorNotFound The specified service was not found. 530 * 531 */ GetServiceId(bool aServerStable,uint8_t & aServiceId) const532 template <typename ServiceType> Error GetServiceId(bool aServerStable, uint8_t &aServiceId) const 533 { 534 return GetServiceId(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData), aServerStable, aServiceId); 535 } 536 537 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 538 /** 539 * Gets the Primary Backbone Router (PBBR) in the Thread Network Data. 540 * 541 * @param[out] aConfig The Primary Backbone Router configuration. 542 * 543 */ 544 void GetBackboneRouterPrimary(ot::BackboneRouter::Config &aConfig) const; 545 #endif 546 547 /** 548 * Gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Anycast Address" entries. 549 * 550 * To get the first entry, @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()` 551 * method). 552 * 553 * @param[in,out] aIterator A reference to an iterator. 554 * @param[out] aInfo A reference to `DnsSrpAnycast::Info` to return the info. 555 * 556 * @retval kErrorNone Successfully got the next info. @p aInfo and @p aIterator are updated. 557 * @retval kErrorNotFound No more matching entries in the Network Data. 558 * 559 */ 560 Error GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycast::Info &aInfo) const; 561 562 /** 563 * Finds the preferred DNS/SRP info among all the Thread Network Data "DNS/SRP Service Anycast Address" 564 * entries. 565 * 566 * The preferred entry is determined based on the sequence number value where a larger value (in the sense 567 * specified by Serial Number Arithmetic logic in RFC-1982) is considered more recent and therefore preferred. 568 * 569 * @param[out] aInfo A reference to `DnsSrpAnycast::Info` to return the info. 570 * 571 * @retval kErrorNone Successfully found the preferred info. @p aInfo is updated. 572 * @retval kErrorNotFound No "DNS/SRP Service Anycast" entry in Network Data. 573 * 574 */ 575 Error FindPreferredDnsSrpAnycastInfo(DnsSrpAnycast::Info &aInfo) const; 576 577 /** 578 * Gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Unicast Address" entries. 579 * 580 * To get the first entry @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()` 581 * method). 582 * 583 * @param[in,out] aIterator A reference to an iterator. 584 * @param[out] aInfo A reference to `DnsSrpUnicast::Info` to return the info. 585 * 586 * @retval kErrorNone Successfully got the next info. @p aInfo and @p aIterator are updated. 587 * @retval kErrorNotFound No more matching entries in the Network Data. 588 * 589 */ 590 Error GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info &aInfo) const; 591 592 private: 593 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 594 Error AddService(const void *aServiceData, 595 uint8_t aServiceDataLength, 596 bool aServerStable, 597 const void *aServerData, 598 uint8_t aServerDataLength); 599 Error RemoveService(const void *aServiceData, uint8_t aServiceDataLength); 600 #endif 601 602 Error GetServiceId(const void *aServiceData, 603 uint8_t aServiceDataLength, 604 bool aServerStable, 605 uint8_t &aServiceId) const; 606 Error IterateToNextServer(Iterator &aIterator) const; 607 608 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 609 bool IsBackboneRouterPreferredTo(const ServerTlv &aServerTlv, 610 const BackboneRouter::ServerData &aServerData, 611 const ServerTlv &aOtherServerTlv, 612 const BackboneRouter::ServerData &aOtherServerData) const; 613 #endif 614 }; 615 616 } // namespace Service 617 } // namespace NetworkData 618 } // namespace ot 619 620 #endif // NETWORK_DATA_SERVICE_HPP_ 621