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