• 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 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     };
262 
263     /**
264      * This class represents long version of "DNS/SRP Service (Unicast)" service data.
265      *
266      */
267     OT_TOOL_PACKED_BEGIN
268     class ServiceData
269     {
270     public:
271         /**
272          * This constructor initializes the `ServiceData` object.
273          *
274          * @param[in] aAddress   The IPv6 address of DNS/SRP server.
275          * @param[in] aPort      The port number of DNS/SRP server.
276          *
277          */
ServiceData(const Ip6::Address & aAddress,uint16_t aPort)278         explicit ServiceData(const Ip6::Address &aAddress, uint16_t aPort)
279             : mServiceNumber(kServiceNumber)
280             , mAddress(aAddress)
281             , mPort(HostSwap16(aPort))
282         {
283             OT_UNUSED_VARIABLE(mServiceNumber);
284         }
285 
286         /**
287          * This method returns the length (in bytes) of service data.
288          *
289          * @returns The data length in bytes.
290          *
291          */
GetLength(void) const292         uint8_t GetLength(void) const { return sizeof(ServiceData); }
293 
294         /**
295          * This method returns the IPv6 address.
296          *
297          * @returns The IPv6 address
298          *
299          */
GetAddress(void) const300         const Ip6::Address &GetAddress(void) const { return mAddress; }
301 
302         /**
303          * This method returns the port number.
304          *
305          * @returns The port number.
306          *
307          */
GetPort(void) const308         uint16_t GetPort(void) const { return HostSwap16(mPort); }
309 
310     private:
311         uint8_t      mServiceNumber;
312         Ip6::Address mAddress;
313         uint16_t     mPort;
314     } OT_TOOL_PACKED_END;
315 
316     /**
317      * This class represents long version of "DNS/SRP Service (Unicast)" server data.
318      *
319      */
320     OT_TOOL_PACKED_BEGIN
321     class ServerData
322     {
323     public:
324         /**
325          * This constructor initializes the `ServerData` object.
326          *
327          * @param[in] aAddress   The IPv6 address of DNS/SRP server.
328          * @param[in] aPort      The port number of DNS/SRP server.
329          *
330          */
ServerData(const Ip6::Address & aAddress,uint16_t aPort)331         ServerData(const Ip6::Address &aAddress, uint16_t aPort)
332             : mAddress(aAddress)
333             , mPort(HostSwap16(aPort))
334         {
335         }
336 
337         /**
338          * This method returns the length (in bytes) of server data.
339          *
340          * @returns The data length in bytes.
341          *
342          */
GetLength(void) const343         uint8_t GetLength(void) const { return sizeof(ServerData); }
344 
345         /**
346          * This method returns the IPv6 address.
347          *
348          * @returns The IPv6 address
349          *
350          */
GetAddress(void) const351         const Ip6::Address &GetAddress(void) const { return mAddress; }
352 
353         /**
354          * This method returns the port number.
355          *
356          * @returns The port number.
357          *
358          */
GetPort(void) const359         uint16_t GetPort(void) const { return HostSwap16(mPort); }
360 
361     private:
362         Ip6::Address mAddress;
363         uint16_t     mPort;
364     } OT_TOOL_PACKED_END;
365 
366     DnsSrpUnicast(void) = delete;
367 };
368 
369 /**
370  * This class manages the Thread Service entries in Thread Network Data.
371  *
372  */
373 class Manager : public InstanceLocator, private NonCopyable
374 {
375 public:
376     /**
377      * This class represents an iterator used to iterate through Network Data Service entries.
378      *
379      */
380     class Iterator : public Clearable<Iterator>
381     {
382         friend class Manager;
383 
384     public:
385         /**
386          * This constructor initializes the iterator (as empty/clear).
387          *
388          */
Iterator(void)389         Iterator(void)
390             : mServiceTlv(nullptr)
391             , mServerSubTlv(nullptr)
392         {
393         }
394 
395         /**
396          * This method resets the iterator to start from beginning.
397          *
398          */
Reset(void)399         void Reset(void)
400         {
401             mServiceTlv   = nullptr;
402             mServerSubTlv = nullptr;
403         }
404 
405     private:
406         const ServiceTlv *mServiceTlv;
407         const ServerTlv * mServerSubTlv;
408     };
409 
410     /**
411      * This constructor initializes the `Manager` object.
412      *
413      * @param[in]  aInstance     A reference to the OpenThread instance.
414      *
415      */
Manager(Instance & aInstance)416     explicit Manager(Instance &aInstance)
417         : InstanceLocator(aInstance)
418     {
419     }
420 
421 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
422     /**
423      * This method adds a Thread Service entry to the local Thread Network Data.
424      *
425      * This version of `Add<SeviceType>()` is intended for use with a `ServiceType` that has a constant service data
426      * format with a non-empty and potentially non-const server data format (provided as input parameter).
427      *
428      * The template type `ServiceType` has the following requirements:
429      *   - It MUST have a constant variable `ServiceType::kServiceData` specifying the service data.
430      *   - It MUST define nested type `ServiceType::ServerData` representing the server data (and its format).
431      *   - The `ServiceType::ServerData` MUST provide `GetLength()` method returning the length of server data.
432      *
433      * @tparam    ServiceType    The service type to be added.
434      *
435      * @param[in] aServerData    The server data.
436      * @param[in] aServerStable  The Stable flag value for Server TLV.
437      *
438      * @retval kErrorNone     Successfully added the Service entry.
439      * @retval kErrorNoBufs   Insufficient space to add the Service entry.
440      *
441      */
442     template <typename ServiceType>
Add(const typename ServiceType::ServerData & aServerData,bool aServerStable=true)443     Error Add(const typename ServiceType::ServerData &aServerData, bool aServerStable = true)
444     {
445         return AddService(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData), aServerStable, &aServerData,
446                           aServerData.GetLength());
447     }
448 
449     /**
450      * This method adds a Thread Service entry to the local Thread Network Data.
451      *
452      * This version of `Add<SeviceType>()` is intended for use with a `ServiceType` that has a non-const service data
453      * format (provided as input parameter) with an empty server data.
454      *
455      * The template type `ServiceType` has the following requirements:
456      *   - It MUST define nested type `ServiceType::ServiceData` representing the service data (and its format).
457      *   - The `ServiceType::ServiceData` MUST provide `GetLength()` method returning the length of service data.
458      *
459      * @tparam    ServiceType    The service type to be added.
460      *
461      * @param[in] aServiceData   The service data.
462      * @param[in] aServerStable  The Stable flag value for Server TLV.
463      *
464      * @retval kErrorNone     Successfully added the Service entry.
465      * @retval kErrorNoBufs   Insufficient space to add the Service entry.
466      *
467      */
468     template <typename ServiceType>
Add(const typename ServiceType::ServiceData & aServiceData,bool aServerStable=true)469     Error Add(const typename ServiceType::ServiceData &aServiceData, bool aServerStable = true)
470     {
471         return AddService(&aServiceData, aServiceData.GetLength(), aServerStable, nullptr, 0);
472     }
473 
474     /**
475      * This method removes a Thread Service entry from the local Thread Network Data.
476      *
477      * This version of `Remove<SeviceType>()` is intended for use with a `ServiceType` that has a constant service data
478      * format.
479      *
480      * The template type `ServiceType` has the following requirements:
481      *   - It MUST have a constant variable `ServiceType::kServiceData` specifying the service data.
482      *
483      * @tparam   ServiceType       The service type to be removed.
484      *
485      * @retval kErrorNone       Successfully removed the Service entry.
486      * @retval kErrorNotFound   Could not find the Service entry.
487      *
488      */
Remove(void)489     template <typename ServiceType> Error Remove(void)
490     {
491         return RemoveService(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData));
492     }
493 
494     /**
495      * This method removes a Thread Service entry from the local Thread Network Data.
496      *
497      * This version of `Remove<SeviceType>()` is intended for use with a `ServiceType` that has a non-const service data
498      * format (provided as input parameter).
499      *
500      * The template type `ServiceType` has the following requirements:
501      *   - It MUST define nested type `ServiceType::ServiceData` representing the service data (and its format).
502      *   - The `ServiceType::ServiceData` MUST provide `GetLength()` method returning the length of service data.
503      *
504      * @tparam   ServiceType       The service type to be removed.
505      *
506      * @param[in] aServiceData     The service data.
507      *
508      * @retval kErrorNone       Successfully removed the Service entry.
509      * @retval kErrorNotFound   Could not find the Service entry.
510      *
511      */
Remove(const typename ServiceType::ServiceData & aServiceData)512     template <typename ServiceType> Error Remove(const typename ServiceType::ServiceData &aServiceData)
513     {
514         return RemoveService(&aServiceData, aServiceData.GetLength());
515     }
516 
517 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
518 
519     /**
520      * This method gets the Service ID for the specified service from Thread Network Data.
521      *
522      * The template type `ServiceType` has the following requirements:
523      *   - It MUST have a constant `ServiceType::kServiceNumber` specifying the service number.
524      *
525      * @tparam     ServiceType     The service type to be added.
526      *
527      * @param[in]  aServerStable   The Stable flag value for Server TLV
528      * @param[out] aServiceId      A reference where to put the Service ID.
529      *
530      * @retval kErrorNone       Successfully got the Service ID.
531      * @retval kErrorNotFound   The specified service was not found.
532      *
533      */
GetServiceId(bool aServerStable,uint8_t & aServiceId) const534     template <typename ServiceType> Error GetServiceId(bool aServerStable, uint8_t &aServiceId) const
535     {
536         return GetServiceId(&ServiceType::kServiceData, sizeof(ServiceType::kServiceData), aServerStable, aServiceId);
537     }
538 
539 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
540     /**
541      * This method gets the Primary Backbone Router (PBBR) in the Thread Network Data.
542      *
543      * @param[out]  aConfig      The Primary Backbone Router configuration.
544      *
545      */
546     void GetBackboneRouterPrimary(ot::BackboneRouter::BackboneRouterConfig &aConfig) const;
547 #endif
548 
549     /**
550      * This method gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Anycast Address" entries.
551      *
552      * To get the first entry, @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()`
553      * method).
554      *
555      * @param[in,out] aIterator    A reference to an iterator.
556      * @param[out]    aInfo        A reference to `DnsSrpAnycast::Info` to return the info.
557      *
558      * @retval kErrorNone       Successfully got the next info. @p aInfo and @p aIterator are updated.
559      * @retval kErrorNotFound   No more matching entries in the Network Data.
560      *
561      */
562     Error GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycast::Info &aInfo) const;
563 
564     /**
565      * This method finds the preferred DNS/SRP info among all the Thread Network Data "DNS/SRP Service Anycast Address"
566      * entries.
567      *
568      * The preferred entry is determined based on the sequence number value where a larger value (in the sense
569      * specified by Serial Number Arithmetic logic in RFC-1982) is considered more recent and therefore preferred.
570      *
571      * @param[out] aInfo        A reference to `DnsSrpAnycast::Info` to return the info.
572      *
573      * @retval kErrorNone       Successfully found the preferred info. @p aInfo is updated.
574      * @retval kErrorNotFound   No "DNS/SRP Service Anycast" entry in Network Data.
575      *
576      */
577     Error FindPreferredDnsSrpAnycastInfo(DnsSrpAnycast::Info &aInfo) const;
578 
579     /**
580      * This method gets the next DNS/SRP info from the Thread Network Data "DNS/SRP Service Unicast Address" entries.
581      *
582      * To get the first entry @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()`
583      * method).
584      *
585      * @param[in,out] aIterator    A reference to an iterator.
586      * @param[out]    aInfo        A reference to `DnsSrpUnicast::Info` to return the info.
587      *
588      * @retval kErrorNone       Successfully got the next info. @p aInfo and @p aIterator are updated.
589      * @retval kErrorNotFound   No more matching entries in the Network Data.
590      *
591      */
592     Error GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info &aInfo) const;
593 
594 private:
595 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
596     Error AddService(const void *aServiceData,
597                      uint8_t     aServiceDataLength,
598                      bool        aServerStable,
599                      const void *aServerData,
600                      uint8_t     aServerDataLength);
601     Error RemoveService(const void *aServiceData, uint8_t aServiceDataLength);
602 #endif
603 
604     Error GetServiceId(const void *aServiceData,
605                        uint8_t     aServiceDataLength,
606                        bool        aServerStable,
607                        uint8_t &   aServiceId) const;
608     Error IterateToNextServer(Iterator &aIterator) const;
609 
610 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
611     bool IsBackboneRouterPreferredTo(const ServerTlv &                 aServerTlv,
612                                      const BackboneRouter::ServerData &aServerData,
613                                      const ServerTlv &                 aOtherServerTlv,
614                                      const BackboneRouter::ServerData &aOtherServerData) const;
615 #endif
616 };
617 
618 } // namespace Service
619 } // namespace NetworkData
620 } // namespace ot
621 
622 #endif // NETWORK_DATA_SERVICE_HPP_
623