• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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