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