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 /** 56 * Represents information about an DNS/SRP server parsed from related Network Data service entries. 57 */ 58 struct DnsSrpAnycastInfo 59 { 60 Ip6::Address mAnycastAddress; ///< The anycast address associated with the DNS/SRP servers. 61 uint8_t mSequenceNumber; ///< Sequence number used to notify SRP client if they need to re-register. 62 uint8_t mVersion; ///< Version number. 63 uint16_t mRloc16; ///< The RLOC16 of the entry. 64 }; 65 66 /** 67 * Represents the `DnsSrpUnicast` entry type. 68 */ 69 enum DnsSrpUnicastType : uint8_t 70 { 71 kAddrInServiceData, ///< Socket address is from service data. 72 kAddrInServerData, ///< Socket address is from server data. 73 }; 74 75 /** 76 * Represents information about an DNS/SRP server parsed from related Network Data service entries. 77 */ 78 struct DnsSrpUnicastInfo 79 { 80 Ip6::SockAddr mSockAddr; ///< The socket address (IPv6 address and port) of the DNS/SRP server. 81 uint8_t mVersion; ///< Version number. 82 uint16_t mRloc16; ///< The BR RLOC16 adding the entry. 83 }; 84 85 /** 86 * Manages the Thread Service entries in Thread Network Data. 87 */ 88 class Manager : public InstanceLocator, private NonCopyable 89 { 90 public: 91 /** 92 * Represents an iterator used to iterate through Network Data Service entries. 93 */ 94 class Iterator : public Clearable<Iterator> 95 { 96 friend class Manager; 97 98 public: 99 /** 100 * Initializes the iterator (as empty/clear). 101 */ Iterator(void)102 Iterator(void) 103 : mServiceTlv(nullptr) 104 , mServerSubTlv(nullptr) 105 { 106 } 107 108 /** 109 * Resets the iterator to start from beginning. 110 */ Reset(void)111 void Reset(void) 112 { 113 mServiceTlv = nullptr; 114 mServerSubTlv = nullptr; 115 } 116 117 private: 118 const ServiceTlv *mServiceTlv; 119 const ServerTlv *mServerSubTlv; 120 }; 121 122 /** 123 * Initializes the `Manager` object. 124 * 125 * @param[in] aInstance A reference to the OpenThread instance. 126 */ Manager(Instance & aInstance)127 explicit Manager(Instance &aInstance) 128 : InstanceLocator(aInstance) 129 { 130 } 131 132 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 133 /** 134 * Adds a DNS/SRP Anycast Service entry to the local Thread Network Data. 135 * 136 * @param[in] aSequenceNumber The anycast sequence number. 137 * @param[in] aVersion The version number 138 * 139 * @retval kErrorNone Successfully added the Service entry. 140 * @retval kErrorNoBufs Insufficient space to add the Service entry. 141 */ 142 Error AddDnsSrpAnycastService(uint8_t aSequenceNumber, uint8_t aVersion); 143 144 /** 145 * Removes a DNS/SRP Anycast Service entry from local Thread Network Data. 146 * 147 * @param[in] aSequenceNumber The anycast sequence number. 148 * 149 * @retval kErrorNone Successfully removed the Service entry. 150 * @retval kErrorNotFound Could not find the Service entry. 151 */ RemoveDnsSrpAnycastService(uint8_t aSequenceNumber)152 Error RemoveDnsSrpAnycastService(uint8_t aSequenceNumber) 153 { 154 return RemoveService(DnsSrpAnycastServiceData(aSequenceNumber)); 155 } 156 157 /** 158 * Adds a DNS/SRP Unicast Service entry with address in Service Data to the local Thread Network Data. 159 * 160 * @param[in] aAddress The unicast address. 161 * @param[in] aPort The port number. 162 * @param[in] aVersion The version. 163 * 164 * @retval kErrorNone Successfully added the Service entry. 165 * @retval kErrorNoBufs Insufficient space to add the Service entry. 166 */ AddDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)167 Error AddDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion) 168 { 169 return AddService(DnsSrpUnicast::ServiceData(aAddress, aPort, aVersion)); 170 } 171 172 /** 173 * Removes a DNS/SRP Unicast Service entry with address in Service Data from the local Thread Network Data. 174 * 175 * @param[in] aAddress The unicast address. 176 * @param[in] aPort The port number. 177 * @param[in] aVersion The version. 178 * 179 * @retval kErrorNone Successfully removed the Service entry. 180 * @retval kErrorNotFound Could not find the Service entry. 181 */ RemoveDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)182 Error RemoveDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress, 183 uint16_t aPort, 184 uint8_t aVersion) 185 { 186 return RemoveService(DnsSrpUnicast::ServiceData(aAddress, aPort, aVersion)); 187 } 188 189 /** 190 * Adds a DNS/SRP Unicast Service entry with address in Server Data to the local Thread Network Data. 191 * 192 * @param[in] aAddress The unicast address. 193 * @param[in] aPort The port number. 194 * @param[in] aVersion The version. 195 * 196 * @retval kErrorNone Successfully added the Service entry. 197 * @retval kErrorNoBufs Insufficient space to add the Service entry. 198 */ AddDnsSrpUnicastServiceWithAddrInServerData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)199 Error AddDnsSrpUnicastServiceWithAddrInServerData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion) 200 { 201 return AddServiceWithNumber(kDnsSrpUnicastServiceNumber, DnsSrpUnicast::ServerData(aAddress, aPort, aVersion)); 202 } 203 204 /** 205 * Removes a DNS/SRP Unicast Service entry with address in Server Data from the local Thread Network Data. 206 * 207 * @retval kErrorNone Successfully removed the Service entry. 208 * @retval kErrorNotFound Could not find the Service entry. 209 */ RemoveDnsSrpUnicastServiceWithAddrInServerData(void)210 Error RemoveDnsSrpUnicastServiceWithAddrInServerData(void) { return RemoveService(kDnsSrpUnicastServiceNumber); } 211 212 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 213 /** 214 * Adds a Backbone Router Service entry to the local Thread Network Data. 215 * 216 * @param[in] aSequenceNumber The sequence number of Backbone Router. 217 * @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router. 218 * @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router. 219 * 220 * @retval kErrorNone Successfully added the Service entry. 221 * @retval kErrorNoBufs Insufficient space to add the Service entry. 222 */ AddBackboneRouterService(uint8_t aSequenceNumber,uint16_t aReregistrationDelay,uint32_t aMlrTimeout)223 Error AddBackboneRouterService(uint8_t aSequenceNumber, uint16_t aReregistrationDelay, uint32_t aMlrTimeout) 224 { 225 return AddServiceWithNumber(kBackboneRouterServiceNumber, 226 BbrServerData(aSequenceNumber, aReregistrationDelay, aMlrTimeout)); 227 } 228 229 /** 230 * Removes the Backbone Router Service entry from the local Thread Network Data. 231 * 232 * @retval kErrorNone Successfully removed the Service entry. 233 * @retval kErrorNotFound Could not find the Service entry. 234 */ RemoveBackboneRouterService(void)235 Error RemoveBackboneRouterService(void) { return RemoveService(kBackboneRouterServiceNumber); } 236 #endif 237 238 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 239 240 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 241 /** 242 * Gets the Primary Backbone Router (PBBR) in the Thread Network Data. 243 * 244 * @param[out] aConfig The Primary Backbone Router configuration. 245 */ 246 void GetBackboneRouterPrimary(ot::BackboneRouter::Config &aConfig) const; 247 248 /** 249 * Gets the Service ID of Backbone Router service from Thread Network Data. 250 * 251 * @param[out] aServiceId A reference where to put the Service ID. 252 * 253 * @retval kErrorNone Successfully got the Service ID. 254 * @retval kErrorNotFound The specified service was not found. 255 */ GetBackboneRouterServiceId(uint8_t & aServiceId) const256 Error GetBackboneRouterServiceId(uint8_t &aServiceId) const 257 { 258 return GetServiceId(kBackboneRouterServiceNumber, aServiceId); 259 } 260 #endif 261 262 /** 263 * Gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Anycast Address" entries. 264 * 265 * To get the first entry, @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()` 266 * method). 267 * 268 * @param[in,out] aIterator A reference to an iterator. 269 * @param[out] aInfo A reference to `DnsSrpAnycastInfo` to return the info. 270 * 271 * @retval kErrorNone Successfully got the next info. @p aInfo and @p aIterator are updated. 272 * @retval kErrorNotFound No more matching entries in the Network Data. 273 */ 274 Error GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycastInfo &aInfo) const; 275 276 /** 277 * Finds the preferred DNS/SRP info among all the Thread Network Data "DNS/SRP Service Anycast Address" 278 * entries. 279 * 280 * The preferred entry is determined based on the sequence number value where a larger value (in the sense 281 * specified by Serial Number Arithmetic logic in RFC-1982) is considered more recent and therefore preferred. 282 * 283 * When successfully found, the `aInfo.mVersion` is set to the minimum version among all the entries matching the 284 * same sequence number as the selected `aInfo.mSequenceNumber`. 285 * 286 * @param[out] aInfo A reference to `DnsSrpAnycastInfo` to return the info. 287 * 288 * @retval kErrorNone Successfully found the preferred info. @p aInfo is updated. 289 * @retval kErrorNotFound No "DNS/SRP Service Anycast" entry in Network Data. 290 */ 291 Error FindPreferredDnsSrpAnycastInfo(DnsSrpAnycastInfo &aInfo) const; 292 293 /** 294 * Gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Unicast Address" entries. 295 * 296 * To get the first entry @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()` 297 * method). 298 * 299 * @param[in,out] aIterator A reference to an iterator. 300 * @param[in] aType The entry type, `kAddrInServiceData` or `kAddrInServerData` 301 * @param[out] aInfo A reference to `DnsSrpUnicastInfo` to return the info. 302 * 303 * @retval kErrorNone Successfully got the next info. @p aInfo and @p aIterator are updated. 304 * @retval kErrorNotFound No more matching entries in the Network Data. 305 */ 306 Error GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicastType aType, DnsSrpUnicastInfo &aInfo) const; 307 308 private: 309 static constexpr uint8_t kBackboneRouterServiceNumber = 0x01; 310 static constexpr uint8_t kDnsSrpAnycastServiceNumber = 0x5c; 311 static constexpr uint8_t kDnsSrpUnicastServiceNumber = 0x5d; 312 313 OT_TOOL_PACKED_BEGIN 314 class DnsSrpAnycastServiceData 315 { 316 public: DnsSrpAnycastServiceData(uint8_t aSequenceNumber)317 explicit DnsSrpAnycastServiceData(uint8_t aSequenceNumber) 318 : mServiceNumber(kDnsSrpAnycastServiceNumber) 319 , mSequenceNumber(aSequenceNumber) 320 { 321 OT_UNUSED_VARIABLE(mServiceNumber); 322 } 323 GetSequenceNumber(void) const324 uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } GetLength(void) const325 uint8_t GetLength(void) const { return sizeof(DnsSrpAnycastServiceData); } 326 327 private: 328 uint8_t mServiceNumber; 329 uint8_t mSequenceNumber; 330 } OT_TOOL_PACKED_END; 331 332 class DnsSrpUnicast 333 { 334 public: 335 OT_TOOL_PACKED_BEGIN 336 class AddrData 337 { 338 public: 339 static constexpr uint8_t kMinLength = sizeof(Ip6::Address) + sizeof(uint16_t); // Address and port. 340 AddrData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)341 AddrData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion) 342 : mAddress(aAddress) 343 , mPort(BigEndian::HostSwap16(aPort)) 344 , mVersion(aVersion) 345 { 346 } 347 GetLength(void) const348 uint8_t GetLength(void) const { return (mVersion == 0) ? kMinLength : sizeof(AddrData); } GetAddress(void) const349 const Ip6::Address &GetAddress(void) const { return mAddress; } GetPort(void) const350 uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); } GetVersion(void) const351 uint8_t GetVersion(void) const { return mVersion; } 352 353 static Error ParseFrom(const uint8_t *aData, uint8_t aLength, DnsSrpUnicastInfo &aInfo); 354 355 private: 356 Ip6::Address mAddress; 357 uint16_t mPort; 358 uint8_t mVersion; 359 } OT_TOOL_PACKED_END; 360 361 static_assert(AddrData::kMinLength + sizeof(uint8_t) == sizeof(AddrData), 362 "Update all methods/constants if adding new (optional) fields to `AddrData`."); 363 364 OT_TOOL_PACKED_BEGIN 365 class ServiceData 366 { 367 public: 368 static constexpr uint8_t kMinLength = sizeof(uint8_t) + AddrData::kMinLength; 369 ServiceData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)370 ServiceData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion) 371 : mServiceNumber(kDnsSrpUnicastServiceNumber) 372 , mAddrData(aAddress, aPort, aVersion) 373 { 374 OT_UNUSED_VARIABLE(mServiceNumber); 375 } 376 GetLength(void) const377 uint8_t GetLength(void) const { return sizeof(uint8_t) + mAddrData.GetLength(); } 378 ParseFrom(const ServiceTlv & aServiceTlv,DnsSrpUnicastInfo & aInfo)379 static Error ParseFrom(const ServiceTlv &aServiceTlv, DnsSrpUnicastInfo &aInfo) 380 { 381 // Skip over `mServiceNumber` field (`uint8_t`)` 382 return AddrData::ParseFrom(aServiceTlv.GetServiceData() + sizeof(uint8_t), 383 aServiceTlv.GetServiceDataLength() - sizeof(uint8_t), aInfo); 384 } 385 386 private: 387 uint8_t mServiceNumber; 388 AddrData mAddrData; 389 } OT_TOOL_PACKED_END; 390 391 static_assert(ServiceData::kMinLength + sizeof(uint8_t) == sizeof(ServiceData), 392 "Update all methods/constants if adding new (optional) fields to `ServiceData`."); 393 394 OT_TOOL_PACKED_BEGIN 395 class ServerData 396 { 397 public: 398 static constexpr uint8_t kMinLength = AddrData::kMinLength; 399 ServerData(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)400 ServerData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion) 401 : mAddrData(aAddress, aPort, aVersion) 402 { 403 } 404 GetLength(void) const405 uint8_t GetLength(void) const { return mAddrData.GetLength(); } 406 ParseFrom(const ServerTlv & aServerTlv,DnsSrpUnicastInfo & aInfo)407 static Error ParseFrom(const ServerTlv &aServerTlv, DnsSrpUnicastInfo &aInfo) 408 { 409 return AddrData::ParseFrom(aServerTlv.GetServerData(), aServerTlv.GetServerDataLength(), aInfo); 410 } 411 412 private: 413 AddrData mAddrData; 414 } OT_TOOL_PACKED_END; 415 416 static_assert(ServerData::kMinLength + sizeof(uint8_t) == sizeof(ServerData), 417 "Update all methods/constants if adding new (optional) fields to `ServerData`."); 418 419 DnsSrpUnicast(void) = delete; 420 }; 421 422 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 423 OT_TOOL_PACKED_BEGIN 424 class BbrServerData 425 { 426 public: BbrServerData(uint8_t aSequenceNumber,uint16_t aReregDelay,uint32_t aMlrTimeout)427 BbrServerData(uint8_t aSequenceNumber, uint16_t aReregDelay, uint32_t aMlrTimeout) 428 : mSequenceNumber(aSequenceNumber) 429 , mReregDelay(BigEndian::HostSwap16(aReregDelay)) 430 , mMlrTimeout(BigEndian::HostSwap32(aMlrTimeout)) 431 { 432 } 433 GetSequenceNumber(void) const434 uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } GetReregistrationDelay(void) const435 uint16_t GetReregistrationDelay(void) const { return BigEndian::HostSwap16(mReregDelay); } GetMlrTimeout(void) const436 uint32_t GetMlrTimeout(void) const { return BigEndian::HostSwap32(mMlrTimeout); } GetLength(void) const437 uint8_t GetLength(void) const { return sizeof(BbrServerData); } 438 439 private: 440 uint8_t mSequenceNumber; 441 uint16_t mReregDelay; 442 uint32_t mMlrTimeout; 443 } OT_TOOL_PACKED_END; 444 #endif 445 446 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE AddService(const ServiceDataType & aServiceData)447 template <typename ServiceDataType> Error AddService(const ServiceDataType &aServiceData) 448 { 449 return AddService(&aServiceData, aServiceData.GetLength(), nullptr, 0); 450 } 451 452 template <typename ServerDataType> AddServiceWithNumber(uint8_t aServiceNumber,const ServerDataType & aServerData)453 Error AddServiceWithNumber(uint8_t aServiceNumber, const ServerDataType &aServerData) 454 { 455 return AddService(&aServiceNumber, sizeof(uint8_t), &aServerData, aServerData.GetLength()); 456 } 457 458 template <typename ServiceDataType, typename ServerDataType> AddService(const ServiceDataType & aServiceData,const ServerDataType & aServerData)459 Error AddService(const ServiceDataType &aServiceData, const ServerDataType &aServerData) 460 { 461 return AddService(&aServiceData, aServiceData.GetLength(), &aServerData, sizeof(ServerDataType)); 462 } 463 464 Error AddService(const void *aServiceData, 465 uint8_t aServiceDataLength, 466 const void *aServerData, 467 uint8_t aServerDataLength); 468 RemoveService(const ServiceDataType & aServiceData)469 template <typename ServiceDataType> Error RemoveService(const ServiceDataType &aServiceData) 470 { 471 return RemoveService(&aServiceData, aServiceData.GetLength()); 472 } 473 RemoveService(uint8_t aServiceNumber)474 Error RemoveService(uint8_t aServiceNumber) { return RemoveService(&aServiceNumber, sizeof(uint8_t)); } 475 Error RemoveService(const void *aServiceData, uint8_t aServiceDataLength); 476 #endif 477 478 Error GetServiceId(uint8_t aServiceNumber, uint8_t &aServiceId) const; 479 Error IterateToNextServer(Iterator &aIterator) const; 480 481 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) 482 bool IsBackboneRouterPreferredTo(const ServerTlv &aServerTlv, 483 const BbrServerData &aServerData, 484 const ServerTlv &aOtherServerTlv, 485 const BbrServerData &aOtherServerData) const; 486 #endif 487 }; 488 489 } // namespace Service 490 } // namespace NetworkData 491 } // namespace ot 492 493 #endif // NETWORK_DATA_SERVICE_HPP_ 494