• 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 #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