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