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 definition of Network Data Publisher.
32  */
33 
34 #ifndef NETWORK_DATA_PUBLISHER_HPP_
35 #define NETWORK_DATA_PUBLISHER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
40 
41 #if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE && !OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
42 #error "OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE requires either OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE"\
43             "or OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE"
44 #endif
45 
46 #include <openthread/netdata_publisher.h>
47 
48 #include "border_router/routing_manager.hpp"
49 #include "common/callback.hpp"
50 #include "common/clearable.hpp"
51 #include "common/equatable.hpp"
52 #include "common/error.hpp"
53 #include "common/locator.hpp"
54 #include "common/non_copyable.hpp"
55 #include "common/notifier.hpp"
56 #include "common/string.hpp"
57 #include "common/timer.hpp"
58 #include "net/ip6_address.hpp"
59 #include "thread/network_data_service.hpp"
60 #include "thread/network_data_types.hpp"
61 
62 namespace ot {
63 namespace NetworkData {
64 
65 /**
66  * Implements the Network Data Publisher.
67  *
68  * It provides mechanisms to limit the number of similar Service and/or Prefix (on-mesh prefix or external route)
69  * entries in the Thread Network Data by monitoring the Network Data and managing if or when to add or remove entries.
70  *
71  */
72 class Publisher : public InstanceLocator, private NonCopyable
73 {
74     friend class ot::Notifier;
75 
76 public:
77     /**
78      * Represents the events reported from the Publisher callbacks.
79      *
80      */
81     enum Event : uint8_t
82     {
83         kEventEntryAdded   = OT_NETDATA_PUBLISHER_EVENT_ENTRY_ADDED,   ///< Entry is added to Network Data.
84         kEventEntryRemoved = OT_NETDATA_PUBLISHER_EVENT_ENTRY_REMOVED, ///< Entry is removed from Network Data.
85     };
86 
87     /**
88      * Represents the requester associated with a published prefix.
89      *
90      */
91     enum Requester : uint8_t
92     {
93         kFromUser,           ///< Requested by user (public OT API).
94         kFromRoutingManager, ///< Requested by `RoutingManager` module.
95     };
96 
97     /**
98      * Initializes `Publisher` object.
99      *
100      * @param[in]  aInstance     A reference to the OpenThread instance.
101      *
102      */
103     explicit Publisher(Instance &aInstance);
104 
105 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
106 
107     /**
108      * Represents the callback function pointer used to notify when a "DNS/SRP Service" entry is added to or
109      * removed from the Thread Network Data.
110      *
111      * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there
112      * are too many similar entries already present in the Network Data) or through an explicit call to unpublish the
113      * entry (i.e., a call to `UnpublishDnsSrpService()`).
114      *
115      */
116     typedef otNetDataDnsSrpServicePublisherCallback DnsSrpServiceCallback;
117 
118     /**
119      * Sets a callback for notifying when a published "DNS/SRP Service" is actually added to or removed
120      * from the Thread Network Data.
121      *
122      * A subsequent call to this method replaces any previously set callback function.
123      *
124      * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
125      * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
126      *
127      */
SetDnsSrpServiceCallback(DnsSrpServiceCallback aCallback,void * aContext)128     void SetDnsSrpServiceCallback(DnsSrpServiceCallback aCallback, void *aContext)
129     {
130         mDnsSrpServiceEntry.SetCallback(aCallback, aContext);
131     }
132 
133     /**
134      * Requests "DNS/SRP Service Anycast Address" to be published in the Thread Network Data.
135      *
136      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
137      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
138      *
139      * @param[in] aSequenceNumber  The sequence number of DNS/SRP Anycast Service.
140      *
141      */
PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber)142     void PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber) { mDnsSrpServiceEntry.PublishAnycast(aSequenceNumber); }
143 
144     /**
145      * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
146      *
147      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
148      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
149      *
150      * Publishes the "DNS/SRP Service Unicast Address" by including the address and port info in the
151      * Service TLV data.
152      *
153      * @param[in] aAddress   The DNS/SRP server address to publish.
154      * @param[in] aPort      The SRP server port number to publish.
155      *
156      */
PublishDnsSrpServiceUnicast(const Ip6::Address & aAddress,uint16_t aPort)157     void PublishDnsSrpServiceUnicast(const Ip6::Address &aAddress, uint16_t aPort)
158     {
159         mDnsSrpServiceEntry.PublishUnicast(aAddress, aPort);
160     }
161 
162     /**
163      * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
164      *
165      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
166      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
167      *
168      * Unlike the `PublishDnsSrpServiceUnicast(aAddress, aPort)` which requires the published address to be given and
169      * includes the info in the Service TLV data, this method uses the device's mesh-local EID and includes the info
170      * in the Server TLV data.
171      *
172      * @param[in] aPort      The SRP server port number to publish.
173      *
174      */
PublishDnsSrpServiceUnicast(uint16_t aPort)175     void PublishDnsSrpServiceUnicast(uint16_t aPort) { mDnsSrpServiceEntry.PublishUnicast(aPort); }
176 
177     /**
178      * Indicates whether or not currently the "DNS/SRP Service" entry is added to the Thread Network Data.
179      *
180      * @retval TRUE    The published DNS/SRP Service entry is added to the Thread Network Data.
181      * @retval FALSE   The entry is not added to Thread Network Data or there is no entry to publish.
182      *
183      */
IsDnsSrpServiceAdded(void) const184     bool IsDnsSrpServiceAdded(void) const { return mDnsSrpServiceEntry.IsAdded(); }
185 
186     /**
187      * Unpublishes any previously added "DNS/SRP (Anycast or Unicast) Service" entry from the Thread
188      * Network Data.
189      *
190      */
UnpublishDnsSrpService(void)191     void UnpublishDnsSrpService(void) { mDnsSrpServiceEntry.Unpublish(); }
192 
193 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
194 
195 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
196     /**
197      * Represents the callback function pointer used to notify when a prefix (on-mesh or external route)
198      * entry is added to or removed from the Thread Network Data.
199      *
200      * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there
201      * are too many similar entries already present in the Network Data) or through an explicit call to unpublish the
202      * entry.
203      *
204      */
205     typedef otNetDataPrefixPublisherCallback PrefixCallback;
206 
207     /**
208      * Sets a callback for notifying when a published prefix entry is actually added to or removed from
209      * the Thread Network Data.
210      *
211      * A subsequent call to this method replaces any previously set callback function.
212      *
213      * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
214      * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
215      *
216      */
SetPrefixCallback(PrefixCallback aCallback,void * aContext)217     void SetPrefixCallback(PrefixCallback aCallback, void *aContext) { mPrefixCallback.Set(aCallback, aContext); }
218 
219     /**
220      * Requests an on-mesh prefix to be published in the Thread Network Data.
221      *
222      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
223      *
224      * A subsequent call to this method will replace a previous request for the same prefix. In particular if the
225      * new call only changes the flags (e.g., preference level) and the prefix is already added in the Network Data,
226      * the change to flags is immediately reflected in the Network Data. This ensures that existing entries in the
227      * Network Data are not abruptly removed. Note that a change in the preference level can potentially later cause
228      * the entry to be removed from the Network Data after determining there are other nodes that are publishing the
229      * same prefix with the same or higher preference.
230      *
231      * @param[in] aConfig         The on-mesh prefix config to publish.
232      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
233      *
234      * @retval kErrorNone         The on-mesh prefix is published successfully.
235      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
236      * @retval kErrorAlready      An entry with the same prefix is already in the published list.
237      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
238      *                            of entries (shared between on-mesh prefix and external route) determined by config
239      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
240      *
241      *
242      */
243     Error PublishOnMeshPrefix(const OnMeshPrefixConfig &aConfig, Requester aRequester);
244 
245     /**
246      * Requests an external route prefix to be published in the Thread Network Data.
247      *
248      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
249      *
250      * A subsequent call to this method will replace a previous request for the same prefix. In particular if the
251      * new call only changes the flags (e.g., preference level) and the prefix is already added in the Network Data,
252      * the change to flags is immediately reflected in the Network Data. This ensures that existing entries in the
253      * Network Data are not abruptly removed. Note that a change in the preference level can potentially later cause
254      * the entry to be removed from the Network Data after determining there are other nodes that are publishing the
255      * same prefix with the same or higher preference.
256      *
257      * @param[in] aConfig         The external route config to publish.
258      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
259      *
260      * @retval kErrorNone         The external route is published successfully.
261      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
262      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
263      *                            of entries (shared between on-mesh prefix and external route) determined by config
264      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
265      *
266      *
267      */
268     Error PublishExternalRoute(const ExternalRouteConfig &aConfig, Requester aRequester);
269 
270     /**
271      * Replaces a previously published external route.
272      *
273      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
274      *
275      * If there is no previously published external route matching @p aPrefix, this method behaves similarly to
276      * `PublishExternalRoute()`, i.e., it will start the process of publishing @a aConfig as an external route in the
277      * Thread Network Data.
278      *
279      * If there is a previously published route entry matching @p aPrefix, it will be replaced with the new prefix from
280      * @p aConfig.
281      *
282      * - If the @p aPrefix was already added in the Network Data, the change to the new prefix in @p aConfig is
283      *   immediately reflected in the Network Data. This ensures that route entries in the Network Data are not
284      *   abruptly removed and the transition from aPrefix to the new prefix is smooth.
285      *
286      * - If the old published @p aPrefix was not added in the Network Data, it will be replaced with the new @p aConfig
287      *   prefix but it will not be immediately added. Instead, it will start the process of publishing it in the
288      *   Network Data (monitoring the Network Data to determine when/if to add the prefix, depending on the number of
289      *   similar prefixes present in the Network Data).
290      *
291      * @param[in] aPrefix         The previously published external route prefix to replace.
292      * @param[in] aConfig         The external route config to publish.
293      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
294      *
295      * @retval kErrorNone         The external route is published successfully.
296      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
297      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
298      *                            of entries (shared between on-mesh prefix and external route) determined by config
299      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
300      *
301      *
302      */
303     Error ReplacePublishedExternalRoute(const Ip6::Prefix         &aPrefix,
304                                         const ExternalRouteConfig &aConfig,
305                                         Requester                  aRequester);
306 
307     /**
308      * Indicates whether or not currently a published prefix entry (on-mesh or external route) is added to
309      * the Thread Network Data.
310      *
311      * @param[in] aPrefix   The prefix to check.
312      *
313      * @retval TRUE    The published prefix entry is added to the Thread Network Data.
314      * @retval FALSE   The entry is not added to Thread Network Data or there is no matching entry to publish.
315      *
316      */
317     bool IsPrefixAdded(const Ip6::Prefix &aPrefix) const;
318 
319     /**
320      * Unpublishes a previously published prefix (on-mesh or external route).
321      *
322      * @param[in] aPrefix       The prefix to unpublish.
323      *
324      * @retval kErrorNone       The prefix was unpublished successfully.
325      * @retval kErrorNotFound   Could not find the prefix in the published list.
326      *
327      */
328     Error UnpublishPrefix(const Ip6::Prefix &aPrefix);
329 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
330 
331 private:
332     class Entry : public InstanceLocatorInit
333     {
334     protected:
335         enum State : uint8_t
336         {
337             kNoEntry,  // Entry is unused (there is no entry).
338             kToAdd,    // Entry is ready to be added, monitoring network data to decide if/when to add it.
339             kAdding,   // Entry is being added in network data (random wait interval before add).
340             kAdded,    // Entry is added in network data, monitoring to determine if/when to remove.
341             kRemoving, // Entry is being removed from network data (random wait interval before remove).
342         };
343 
344         // All intervals are in milliseconds.
345         static constexpr uint32_t kMaxDelayToAdd    = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_ADD;
346         static constexpr uint32_t kMaxDelayToRemove = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_REMOVE;
347         static constexpr uint32_t kExtraDelayToRemovePreferred =
348             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_EXTRA_DELAY_TIME_TO_REMOVE_PREFERRED;
349 
350         static constexpr uint16_t kInfoStringSize = 60;
351 
352         typedef String<kInfoStringSize> InfoString;
353 
Entry(void)354         Entry(void)
355             : mState(kNoEntry)
356         {
357         }
358 
Init(Instance & aInstance)359         void             Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
GetState(void) const360         State            GetState(void) const { return mState; }
361         void             SetState(State aState);
GetUpdateTime(void) const362         const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; }
363         bool             IsPreferred(uint16_t aRloc16) const;
364         void             UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEntries, uint8_t aDesiredNumEntries);
365         void             HandleTimer(void);
366         InfoString       ToString(bool aIncludeState = true) const;
367 
368     public:
IsAdded(void) const369         bool IsAdded(void) const { return (mState == kAdded); }
370 
371     private:
372         void               Add(void);
373         void               Remove(State aNextState);
374         void               LogUpdateTime(void) const;
375         static const char *StateToString(State aState);
376 
377         TimeMilli mUpdateTime;
378         State     mState;
379     };
380 
381 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
382     class DnsSrpServiceEntry : public Entry, private NonCopyable
383     {
384         friend class Entry;
385 
386     public:
387         explicit DnsSrpServiceEntry(Instance &aInstance);
SetCallback(DnsSrpServiceCallback aCallback,void * aContext)388         void SetCallback(DnsSrpServiceCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
389         void PublishAnycast(uint8_t aSequenceNumber);
390         void PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort);
391         void PublishUnicast(uint16_t aPort);
392         void Unpublish(void);
HandleTimer(void)393         void HandleTimer(void) { Entry::HandleTimer(); }
394         void HandleNotifierEvents(Events aEvents);
395 
396     private:
397         static constexpr uint8_t kDesiredNumAnycast =
398             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_ANYCAST_DNS_SRP_SERVICE_ENTRIES;
399 
400         static constexpr uint8_t kDesiredNumUnicast =
401             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_UNICAST_DNS_SRP_SERVICE_ENTRIES;
402 
403         enum Type : uint8_t
404         {
405             kTypeAnycast,
406             kTypeUnicast,
407             kTypeUnicastMeshLocalEid,
408         };
409 
410         class Info : public Clearable<Info>, public Equatable<Info>
411         {
412         public:
Info(void)413             Info(void) { Clear(); }
GetType(void) const414             Type                GetType(void) const { return mType; }
GetSequenceNumber(void) const415             uint8_t             GetSequenceNumber(void) const { return static_cast<uint8_t>(mPortOrSeqNumber); }
GetPort(void) const416             uint16_t            GetPort(void) const { return mPortOrSeqNumber; }
GetAddress(void) const417             const Ip6::Address &GetAddress(void) const { return mAddress; }
SetAddress(const Ip6::Address & aAddress)418             void                SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; }
419 
InfoAnycast(uint8_t aSequenceNumber)420             static Info InfoAnycast(uint8_t aSequenceNumber) { return Info(kTypeAnycast, aSequenceNumber); }
InfoUnicast(Type aType,const Ip6::Address & aAddress,uint16_t aPort)421             static Info InfoUnicast(Type aType, const Ip6::Address &aAddress, uint16_t aPort)
422             {
423                 return Info(aType, aPort, &aAddress);
424             }
425 
426         private:
427             Info(Type aType, uint16_t aPortOrSeqNumber, const Ip6::Address *aAddress = nullptr);
428 
429             Ip6::Address mAddress;
430             uint16_t     mPortOrSeqNumber;
431             Type         mType;
432         };
433 
GetType(void) const434         Type GetType(void) const { return mInfo.GetType(); }
435         void Publish(const Info &aInfo);
436         void Add(void);
437         void Remove(State aNextState);
438         void Notify(Event aEvent) const;
439         void Process(void);
440         void CountAnycastEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
441         bool HasAnyAnycastEntry(void) const;
442         void CountUnicastEntries(Service::DnsSrpUnicastType aType,
443                                  uint8_t                   &aNumEntries,
444                                  uint8_t                   &aNumPreferredEntries) const;
445         bool HasAnyServiceDataUnicastEntry(void) const;
446 
447         Info                            mInfo;
448         Callback<DnsSrpServiceCallback> mCallback;
449     };
450 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
451 
452 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
453 
454     // Max number of prefix (on-mesh or external route) entries.
455     static constexpr uint16_t kMaxUserPrefixEntries = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES;
456 
457 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
458     static constexpr uint16_t kMaxRoutingManagerPrefixEntries = BorderRouter::RoutingManager::kMaxPublishedPrefixes;
459 #else
460     static constexpr uint16_t kMaxRoutingManagerPrefixEntries = 0;
461 #endif
462 
463     class PrefixEntry : public Entry, private NonCopyable
464     {
465         friend class Entry;
466 
467     public:
Init(Instance & aInstance)468         void      Init(Instance &aInstance) { Entry::Init(aInstance); }
IsInUse(void) const469         bool      IsInUse(void) const { return GetState() != kNoEntry; }
Matches(const Ip6::Prefix & aPrefix) const470         bool      Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
471         void      Publish(const OnMeshPrefixConfig &aConfig, Requester aRequester);
472         void      Publish(const ExternalRouteConfig &aConfig, Requester aRequester);
GetRequester(void) const473         Requester GetRequester(void) const { return mRequester; }
474         void      Unpublish(void);
HandleTimer(void)475         void      HandleTimer(void) { Entry::HandleTimer(); }
476         void      HandleNotifierEvents(Events aEvents);
477 
478     private:
479         static constexpr uint8_t kDesiredNumOnMeshPrefix =
480             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_ON_MESH_PREFIX_ENTRIES;
481 
482         static constexpr uint8_t kDesiredNumExternalRoute =
483             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_EXTERNAL_ROUTE_ENTRIES;
484 
485         enum Type : uint8_t
486         {
487             kTypeOnMeshPrefix,
488             kTypeExternalRoute,
489         };
490 
491         void  Publish(const Ip6::Prefix &aPrefix, uint16_t aNewFlags, Type aNewType, Requester aRequester);
492         void  Add(void);
493         Error AddOnMeshPrefix(void);
494         Error AddExternalRoute(void);
495         void  Remove(State aNextState);
496         void  Process(void);
497         void  CountOnMeshPrefixEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
498         void  CountExternalRouteEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
499 
500         Type        mType;
501         Requester   mRequester;
502         Ip6::Prefix mPrefix;
503         uint16_t    mFlags;
504     };
505 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
506 
507 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
IsADnsSrpServiceEntry(const Entry & aEntry) const508     bool IsADnsSrpServiceEntry(const Entry &aEntry) const { return (&aEntry == &mDnsSrpServiceEntry); }
509 #endif
510 
511 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
512     PrefixEntry       *FindOrAllocatePrefixEntry(const Ip6::Prefix &aPrefix, Requester aRequester);
513     PrefixEntry       *FindMatchingPrefixEntry(const Ip6::Prefix &aPrefix);
514     const PrefixEntry *FindMatchingPrefixEntry(const Ip6::Prefix &aPrefix) const;
515     bool               IsAPrefixEntry(const Entry &aEntry) const;
516     void               NotifyPrefixEntryChange(Event aEvent, const Ip6::Prefix &aPrefix) const;
517 #endif
518 
GetTimer(void)519     TimerMilli &GetTimer(void) { return mTimer; }
520     void        HandleNotifierEvents(Events aEvents);
521     void        HandleTimer(void);
522 
523     using PublisherTimer = TimerMilliIn<Publisher, &Publisher::HandleTimer>;
524 
525 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
526     DnsSrpServiceEntry mDnsSrpServiceEntry;
527 #endif
528 
529 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
530     PrefixEntry              mPrefixEntries[kMaxUserPrefixEntries + kMaxRoutingManagerPrefixEntries];
531     Callback<PrefixCallback> mPrefixCallback;
532 #endif
533 
534     PublisherTimer mTimer;
535 };
536 
537 } // namespace NetworkData
538 } // namespace ot
539 
540 #endif // OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
541 
542 #endif // NETWORK_DATA_PUBLISHER_HPP_
543