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