• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020, 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 #ifndef SRP_CLIENT_HPP_
30 #define SRP_CLIENT_HPP_
31 
32 #include "openthread-core-config.h"
33 
34 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
35 
36 #include <openthread/srp_client.h>
37 
38 #include "common/as_core_type.hpp"
39 #include "common/callback.hpp"
40 #include "common/clearable.hpp"
41 #include "common/linked_list.hpp"
42 #include "common/locator.hpp"
43 #include "common/log.hpp"
44 #include "common/message.hpp"
45 #include "common/non_copyable.hpp"
46 #include "common/notifier.hpp"
47 #include "common/numeric_limits.hpp"
48 #include "common/owned_ptr.hpp"
49 #include "common/timer.hpp"
50 #include "crypto/ecdsa.hpp"
51 #include "net/dns_types.hpp"
52 #include "net/ip6.hpp"
53 #include "net/netif.hpp"
54 #include "net/udp6.hpp"
55 #include "thread/network_data_service.hpp"
56 
57 /**
58  * @file
59  *   This file includes definitions for the SRP (Service Registration Protocol) client.
60  */
61 
62 namespace ot {
63 namespace Srp {
64 
65 #if !OPENTHREAD_CONFIG_ECDSA_ENABLE
66 #error "SRP Client feature requires ECDSA support (OPENTHREAD_CONFIG_ECDSA_ENABLE)."
67 #endif
68 
69 /**
70  * Implements SRP client.
71  */
72 class Client : public InstanceLocator, private NonCopyable
73 {
74     friend class ot::Notifier;
75     friend class ot::Ip6::Netif;
76 
77     using DnsSrpUnicastInfo = NetworkData::Service::DnsSrpUnicastInfo;
78     using DnsSrpUnicastType = NetworkData::Service::DnsSrpUnicastType;
79     using DnsSrpAnycastInfo = NetworkData::Service::DnsSrpAnycastInfo;
80 
81 public:
82     /**
83      * Types represents an SRP client item (service or host info) state.
84      */
85     enum ItemState : uint8_t
86     {
87         kToAdd      = OT_SRP_CLIENT_ITEM_STATE_TO_ADD,     ///< Item to be added/registered.
88         kAdding     = OT_SRP_CLIENT_ITEM_STATE_ADDING,     ///< Item is being added/registered.
89         kToRefresh  = OT_SRP_CLIENT_ITEM_STATE_TO_REFRESH, ///< Item to be refreshed (renew lease).
90         kRefreshing = OT_SRP_CLIENT_ITEM_STATE_REFRESHING, ///< Item is being refreshed.
91         kToRemove   = OT_SRP_CLIENT_ITEM_STATE_TO_REMOVE,  ///< Item to be removed.
92         kRemoving   = OT_SRP_CLIENT_ITEM_STATE_REMOVING,   ///< Item is being removed.
93         kRegistered = OT_SRP_CLIENT_ITEM_STATE_REGISTERED, ///< Item is registered with server.
94         kRemoved    = OT_SRP_CLIENT_ITEM_STATE_REMOVED,    ///< Item is removed.
95     };
96 
97     /**
98      * Pointer type defines the callback used by SRP client to notify user of a changes/events/errors.
99      *
100      * Please see `otSrpClientCallback` for more details.
101      */
102     typedef otSrpClientCallback ClientCallback;
103 
104     /**
105      * Represents an SRP client host info.
106      */
107     class HostInfo : public otSrpClientHostInfo, private Clearable<HostInfo>
108     {
109         friend class Client;
110         friend class Clearable<HostInfo>;
111 
112     public:
113         /**
114          * Initializes the `HostInfo` object.
115          */
116         void Init(void);
117 
118         /**
119          * Clears the `HostInfo` object.
120          */
121         void Clear(void);
122 
123         /**
124          * Gets the host name (label) string.
125          *
126          * @returns The host name (label) string, or `nullptr` if not yet set.
127          */
GetName(void) const128         const char *GetName(void) const { return mName; }
129 
130         /**
131          * Indicates whether or not the host auto address mode is enabled.
132          *
133          * @retval TRUE  If the auto address mode is enabled.
134          * @retval FALSE If the auto address mode is disabled.
135          */
IsAutoAddressEnabled(void) const136         bool IsAutoAddressEnabled(void) const { return mAutoAddress; }
137 
138         /**
139          * Gets the number of host IPv6 addresses.
140          *
141          * @returns The number of host IPv6 addresses.
142          */
GetNumAddresses(void) const143         uint8_t GetNumAddresses(void) const { return mNumAddresses; }
144 
145         /**
146          * Gets the host IPv6 address at a given index.
147          *
148          * @param[in] aIndex  The index to get (MUST be smaller than `GetNumAddresses()`).
149          *
150          * @returns  The host IPv6 address at index @p aIndex.
151          */
GetAddress(uint8_t aIndex) const152         const Ip6::Address &GetAddress(uint8_t aIndex) const { return AsCoreType(&mAddresses[aIndex]); }
153 
154         /**
155          * Gets the state of `HostInfo`.
156          *
157          * @returns The `HostInfo` state.
158          */
GetState(void) const159         ItemState GetState(void) const { return static_cast<ItemState>(mState); }
160 
161     private:
SetName(const char * aName)162         void SetName(const char *aName) { mName = aName; }
163         bool SetState(ItemState aState);
164         void SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
165         void EnableAutoAddress(void);
166     };
167 
168     /**
169      * Represents an SRP client service.
170      */
171     class Service : public otSrpClientService, public LinkedListEntry<Service>
172     {
173         friend class Client;
174         friend class LinkedList<Service>;
175 
176     public:
177         /**
178          * Initializes and validates the `Service` object and its fields.
179          *
180          * @retval kErrorNone         Successfully initialized and validated the `Service` object.
181          * @retval kErrorInvalidArgs  The info in `Service` object is not valid (e.g. null name or bad `TxtEntry`).
182          */
183         Error Init(void);
184 
185         /**
186          * Gets the service name labels string.
187          *
188          * @returns The service name label string (e.g., "_chip._udp", not the full domain name).
189          */
GetName(void) const190         const char *GetName(void) const { return mName; }
191 
192         /**
193          * Gets the service instance name label (not the full name).
194          *
195          * @returns The service instance name label string.
196          */
GetInstanceName(void) const197         const char *GetInstanceName(void) const { return mInstanceName; }
198 
199         /**
200          * Indicates whether or not the service has any subtypes.
201          *
202          * @retval TRUE   The service has at least one subtype.
203          * @retval FALSE  The service does not have any subtype.
204          */
HasSubType(void) const205         bool HasSubType(void) const { return (mSubTypeLabels != nullptr); }
206 
207         /**
208          * Gets the subtype label at a given index.
209          *
210          * MUST be used only after `HasSubType()` indicates that service has a subtype.
211          *
212          * @param[in] aIndex  The index into list of subtype labels.
213          *
214          * @returns A pointer to subtype label at @p aIndex, or `nullptr` if there is no label (@p aIndex is after the
215          *          end of the subtype list).
216          */
GetSubTypeLabelAt(uint16_t aIndex) const217         const char *GetSubTypeLabelAt(uint16_t aIndex) const { return mSubTypeLabels[aIndex]; }
218 
219         /**
220          * Gets the service port number.
221          *
222          * @returns The service port number.
223          */
GetPort(void) const224         uint16_t GetPort(void) const { return mPort; }
225 
226         /**
227          * Gets the service priority.
228          *
229          * @returns The service priority.
230          */
GetPriority(void) const231         uint16_t GetPriority(void) const { return mPriority; }
232 
233         /**
234          * Gets the service weight.
235          *
236          * @returns The service weight.
237          */
GetWeight(void) const238         uint16_t GetWeight(void) const { return mWeight; }
239 
240         /**
241          * Gets the array of service TXT entries.
242          *
243          * @returns A pointer to an array of service TXT entries.
244          */
GetTxtEntries(void) const245         const Dns::TxtEntry *GetTxtEntries(void) const { return AsCoreTypePtr(mTxtEntries); }
246 
247         /**
248          * Gets the number of entries in the service TXT entry array.
249          *
250          * @returns The number of entries in the service TXT entry array.
251          */
GetNumTxtEntries(void) const252         uint8_t GetNumTxtEntries(void) const { return mNumTxtEntries; }
253 
254         /**
255          * Gets the state of service.
256          *
257          * @returns The service state.
258          */
GetState(void) const259         ItemState GetState(void) const { return static_cast<ItemState>(mState); }
260 
261         /**
262          * Gets the desired lease interval to request when registering this service.
263          *
264          * @returns The desired lease interval in sec. Zero indicates to use default.
265          */
GetLease(void) const266         uint32_t GetLease(void) const { return (mLease & kLeaseMask); }
267 
268         /**
269          * Gets the desired key lease interval to request when registering this service.
270          *
271          * @returns The desired lease interval in sec. Zero indicates to use default.
272          */
GetKeyLease(void) const273         uint32_t GetKeyLease(void) const { return mKeyLease; }
274 
275     private:
276         // We use the high (MSB) bit of `mLease` as flag to indicate
277         // whether or not the service is appended in the message.
278         // This is then used when updating the service state. Note that
279         // we guarantee that `mLease` is not greater than `kMaxLease`
280         // which ensures that the last bit is unused.
281 
282         static constexpr uint32_t kAppendedInMsgFlag = (1U << 31);
283         static constexpr uint32_t kLeaseMask         = ~kAppendedInMsgFlag;
284 
285         bool      SetState(ItemState aState);
GetLeaseRenewTime(void) const286         TimeMilli GetLeaseRenewTime(void) const { return TimeMilli(mData); }
SetLeaseRenewTime(TimeMilli aTime)287         void      SetLeaseRenewTime(TimeMilli aTime) { mData = aTime.GetValue(); }
IsAppendedInMessage(void) const288         bool      IsAppendedInMessage(void) const { return mLease & kAppendedInMsgFlag; }
MarkAsAppendedInMessage(void)289         void      MarkAsAppendedInMessage(void) { mLease |= kAppendedInMsgFlag; }
ClearAppendedInMessageFlag(void)290         void      ClearAppendedInMessageFlag(void) { mLease &= ~kAppendedInMsgFlag; }
291         bool      Matches(const Service &aOther) const;
Matches(ItemState aState) const292         bool      Matches(ItemState aState) const { return GetState() == aState; }
293     };
294 
295     /**
296      * Initializes the SRP `Client` object.
297      *
298      * @param[in]  aInstance  A reference to the OpenThread instance.
299      */
300     explicit Client(Instance &aInstance);
301 
302     /**
303      * Starts the SRP client operation.
304      *
305      * SRP client will prepare and send "SRP Update" message to the SRP server once all the following conditions are
306      * met:
307      *
308      *  - The SRP client is started - `Start()` is called
309      *  - Host name is set - `SetHostName()` is called.
310      *  - At least one host IPv6 address is set - `SetHostAddresses()` is called.
311      *  - At least one service is added - `AddService()` is called.
312      *
313      * It does not matter in which order these methods are called. When all conditions are met, the SRP client will
314      * wait for a short delay before preparing an "SRP Update" message and sending it to server. This delay allows for
315      * user to add multiple services and/or IPv6 addresses before the first SRP Update message is sent (ensuring a
316      * single SRP Update is sent containing all the info).
317      *
318      * @param[in] aServerSockAddr  The socket address (IPv6 address and port number) of the SRP server.
319      *
320      * @retval kErrorNone     SRP client operation started successfully or it is already running with same server
321      *                        socket address and callback.
322      * @retval kErrorBusy     SRP client is busy running with a different socket address.
323      * @retval kErrorFailed   Failed to open/connect the client's UDP socket.
324      */
Start(const Ip6::SockAddr & aServerSockAddr)325     Error Start(const Ip6::SockAddr &aServerSockAddr) { return Start(aServerSockAddr, kRequesterUser); }
326 
327     /**
328      * Stops the SRP client operation.
329      *
330      * Stops any further interactions with the SRP server. Note that it does not remove or clear host info
331      * and/or list of services. It marks all services to be added/removed again once the client is started again.
332      *
333      * If `OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE` (auto-start feature) is enabled, a call to this method
334      * also disables the auto-start mode.
335      */
Stop(void)336     void Stop(void) { Stop(kRequesterUser, kResetRetryInterval); }
337 
338 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
339     /**
340      * Pointer type defines the callback used by SRP client to notify user when it is auto-started or
341      * stopped.
342      */
343     typedef otSrpClientAutoStartCallback AutoStartCallback;
344 
345     /**
346      * Enables the auto-start mode.
347      *
348      * Config option `OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_DEFAULT_MODE` specifies the default auto-start mode
349      * (whether it is enabled or disabled at the start of OT stack).
350      *
351      * When auto-start is enabled, the SRP client will monitor the Thread Network Data to discover SRP servers and
352      * select the preferred server and automatically start and stop the client when an SRP server is detected.
353      *
354      * There are three categories of Network Data entries indicating presence of SRP sever. They are preferred in the
355      * following order:
356      *
357      *   1) Preferred unicast entries where server address is included in the service data. If there are multiple
358      *      options, the one with numerically lowest IPv6 address is preferred.
359      *
360      *   2) Anycast entries each having a seq number. A larger sequence number in the sense specified by Serial Number
361      *      Arithmetic logic in RFC-1982 is considered more recent and therefore preferred. The largest seq number
362      *      using serial number arithmetic is preferred if it is well-defined (i.e., the seq number is larger than all
363      *      other seq numbers). If it is not well-defined, then the numerically largest seq number is preferred.
364      *
365      *   3) Unicast entries where the server address info is included in server data. If there are multiple options,
366      *      the one with numerically lowest IPv6 address is preferred.
367      *
368      * When there is a change in the Network Data entries, client will check that the currently selected server is
369      * still present in the Network Data and is still the preferred one. Otherwise the client will switch to the new
370      * preferred server or stop if there is none.
371      *
372      * When the SRP client is explicitly started through a successful call to `Start()`, the given SRP server address
373      * in `Start()` will continue to be used regardless of the state of auto-start mode and whether the same SRP
374      * server address is discovered or not in the Thread Network Data. In this case, only an explicit `Stop()` call
375      * will stop the client.
376      *
377      * @param[in] aCallback   A callback to notify when client is auto-started/stopped. Can be `nullptr` if not needed.
378      * @param[in] aContext    A context to be passed when invoking @p aCallback.
379      */
380     void EnableAutoStartMode(AutoStartCallback aCallback, void *aContext);
381 
382     /**
383      * Disables the auto-start mode.
384      *
385      * Disabling the auto-start mode will not stop the client if it is already running but the client stops monitoring
386      * the Thread Network Data to verify that the selected SRP server is still present in it.
387      *
388      * Note that a call to `Stop()` will also disable the auto-start mode.
389      */
DisableAutoStartMode(void)390     void DisableAutoStartMode(void) { mAutoStart.SetState(AutoStart::kDisabled); }
391 
392     /**
393      * Indicates the current state of auto-start mode (enabled or disabled).
394      *
395      * @returns TRUE if the auto-start mode is enabled, FALSE otherwise.
396      */
IsAutoStartModeEnabled(void) const397     bool IsAutoStartModeEnabled(void) const { return mAutoStart.GetState() != AutoStart::kDisabled; }
398 
399     /**
400      * Indicates whether or not the current SRP server's address is selected by auto-start.
401      *
402      * @returns TRUE if the SRP server's address is selected by auto-start, FALSE otherwise.
403      */
IsServerSelectedByAutoStart(void) const404     bool IsServerSelectedByAutoStart(void) const { return mAutoStart.HasSelectedServer(); }
405 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
406 
407     /**
408      * Indicates whether the SRP client is running or not.
409      *
410      * @returns TRUE if the SRP client is running, FALSE otherwise.
411      */
IsRunning(void) const412     bool IsRunning(void) const { return (mState != kStateStopped); }
413 
414     /**
415      * Gets the socket address (IPv6 address and port number) of the SRP server which is being used by SRP
416      * client.
417      *
418      * If the client is not running, the address is unspecified (all zero) with zero port number.
419      *
420      * @returns The SRP server's socket address.
421      */
GetServerAddress(void) const422     const Ip6::SockAddr &GetServerAddress(void) const { return mSocket.GetPeerName(); }
423 
424     /**
425      * Sets the callback used to notify caller of events/changes.
426      *
427      * The SRP client allows a single callback to be registered. So consecutive calls to this method will overwrite any
428      * previously set callback functions.
429      *
430      * @param[in] aCallback        The callback to notify of events and changes. Can be `nullptr` if not needed.
431      * @param[in] aContext         An arbitrary context used with @p aCallback.
432      */
SetCallback(ClientCallback aCallback,void * aContext)433     void SetCallback(ClientCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
434 
435     /**
436      * Gets the TTL used in SRP update requests.
437      *
438      * Note that this is the TTL requested by the SRP client. The server may choose to accept a different TTL.
439      *
440      * By default, the TTL will equal the lease interval. Passing 0 or a value larger than the lease interval via
441      * `otSrpClientSetTtl()` will also cause the TTL to equal the lease interval.
442      *
443      * @returns The TTL (in seconds).
444      */
GetTtl(void) const445     uint32_t GetTtl(void) const { return mTtl; }
446 
447     /**
448      * Sets the TTL used in SRP update requests.
449      *
450      * Changing the TTL does not impact the TTL of already registered services/host-info.
451      * It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
452      *
453      * @param[in] aTtl  The TTL (in seconds). If value is zero or greater than lease interval, the TTL is set to the
454      *                  lease interval.
455      */
SetTtl(uint32_t aTtl)456     void SetTtl(uint32_t aTtl) { mTtl = aTtl; }
457 
458     /**
459      * Gets the lease interval used in SRP update requests.
460      *
461      * Note that this is lease duration that would be requested by the SRP client. Server may choose to accept a
462      * different lease interval.
463      *
464      * @returns The lease interval (in seconds).
465      */
GetLeaseInterval(void) const466     uint32_t GetLeaseInterval(void) const { return mDefaultLease; }
467 
468     /**
469      * Sets the lease interval used in SRP update requests.
470      *
471      * Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
472      * It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
473      *
474      * @param[in] aInterval  The lease interval (in seconds). If zero, the default value `kDefaultLease` would be used.
475      */
SetLeaseInterval(uint32_t aInterval)476     void SetLeaseInterval(uint32_t aInterval) { mDefaultLease = DetermineLeaseInterval(aInterval, kDefaultLease); }
477 
478     /**
479      * Gets the key lease interval used in SRP update requests.
480      *
481      * @returns The key lease interval (in seconds).
482      */
GetKeyLeaseInterval(void) const483     uint32_t GetKeyLeaseInterval(void) const { return mDefaultKeyLease; }
484 
485     /**
486      * Sets the key lease interval used in SRP update requests.
487      *
488      * Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
489      * It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
490      *
491      * @param[in] aInterval The key lease interval (in seconds). If zero, the default value `kDefaultKeyLease` would be
492      *                      used.
493      */
SetKeyLeaseInterval(uint32_t aInterval)494     void SetKeyLeaseInterval(uint32_t aInterval)
495     {
496         mDefaultKeyLease = DetermineLeaseInterval(aInterval, kDefaultKeyLease);
497     }
498 
499     /**
500      * Gets the host info.
501      *
502      * @returns A reference to host info structure.
503      */
GetHostInfo(void) const504     const HostInfo &GetHostInfo(void) const { return mHostInfo; }
505 
506     /**
507      * Sets the host name label.
508      *
509      * After a successful call to this method, `Callback` will be called to report the status of host info
510      *  registration with SRP server.
511      *
512      * The host name can be set before client is started or after start but before host info is registered with server
513      * (host info should be in either `kToAdd` or `kRemoved`).
514      *
515      * @param[in] aName       A pointer to host name label string (MUST NOT be NULL). Pointer the string buffer MUST
516      *                        persist and remain valid and constant after return from this method.
517      *
518      * @retval kErrorNone           The host name label was set successfully.
519      * @retval kErrorInvalidArgs    The @p aName is NULL.
520      * @retval kErrorInvalidState   The host name is already set and registered with the server.
521      */
522     Error SetHostName(const char *aName);
523 
524     /**
525      * Enables auto host address mode.
526      *
527      * When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread
528      * netif excluding the link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID
529      * address is added. The SRP client will automatically re-register when/if addresses on Thread netif are updated
530      * (new addresses are added or existing addresses are removed).
531      *
532      * The auto host address mode can be enabled before start or during operation of SRP client except when the host
533      * info is being removed (client is busy handling a remove request from an call to `RemoveHostAndServices()` and
534      * host info still being in  either `kStateToRemove` or `kStateRemoving` states).
535      *
536      * After auto host address mode is enabled, it can be disabled by a call to `SetHostAddresses()` which then
537      * explicitly sets the host addresses.
538      *
539      * @retval kErrorNone          Successfully enabled auto host address mode.
540      * @retval kErrorInvalidState  Host is being removed and therefore cannot enable auto host address mode.
541      */
542     Error EnableAutoHostAddress(void);
543 
544     /**
545      * Sets/updates the list of host IPv6 address.
546      *
547      * Host IPv6 addresses can be set/changed before start or even during operation of SRP client (e.g. to add/remove
548      * or change a previously registered host address), except when the host info is being removed (client is busy
549      * handling a remove request from an earlier call to `RemoveHostAndServices()` and host info still being in either
550      * `kStateToRemove` or `kStateRemoving` states).
551      *
552      * After a successful call to this method, `Callback` will be called to report the status of the address
553      * registration with SRP server.
554      *
555      * Calling this method disables auto host address mode if it was previously enabled from a successful call to
556      * `EnableAutoHostAddress()`.
557      *
558      * @param[in] aAddresses          A pointer to the an array containing the host IPv6 addresses.
559      * @param[in] aNumAddresses       The number of addresses in the @p aAddresses array.
560      *
561      * @retval kErrorNone           The host IPv6 address list change started successfully. The `Callback` will be
562      *                              called to report the status of registering addresses with server.
563      * @retval kErrorInvalidArgs    The address list is invalid (e.g., must contain at least one address).
564      * @retval kErrorInvalidState   Host is being removed and therefore cannot change host address.
565      */
566     Error SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
567 
568     /**
569      * Adds a service to be registered with server.
570      *
571      * After a successful call to this method, `Callback` will be called to report the status of the service
572      * addition/registration with SRP server.
573      *
574      * @param[in] aService         A `Service` to add (the instance must persist and remain unchanged after
575      *                             successful return from this method).
576      *
577      * @retval kErrorNone          The addition of service started successfully. The `Callback` will be called to
578      *                             report the status.
579      * @retval kErrorAlready       A service with the same service and instance names is already in the list.
580      * @retval kErrorInvalidArgs   The service structure is invalid (e.g., bad service name or `TxEntry`).
581      */
582     Error AddService(Service &aService);
583 
584     /**
585      * Removes a service to be unregistered with server.
586      *
587      * @param[in] aService         A `Service` to remove (the instance must persist and remain unchanged after
588      *                             successful return from this method).
589      *
590      * @retval kErrorNone      The removal of service started successfully. The `Callback` will be called to report
591      *                         the status.
592      * @retval kErrorNotFound  The service could not be found in the list.
593      */
594 
595     Error RemoveService(Service &aService);
596 
597     /**
598      * Clears a service, immediately removing it from the client service list.
599      *
600      * Unlike `RemoveService()` which sends an update message to the server to remove the service, this method clears
601      * the service from the client's service list without any interaction with the server. On a successful call
602      * to this method, the `Callback` will NOT be called and the @p aService entry can be reclaimed and re-used by the
603      * caller immediately.
604      *
605      * @param[in] aService     A service to delete from the list.
606      *
607      * @retval kErrorNone      The @p aService is cleared successfully. It can be reclaimed and re-used immediately.
608      * @retval kErrorNotFound  The service could not be found in the list.
609      */
610     Error ClearService(Service &aService);
611 
612     /**
613      * Gets the list of services being managed by client.
614      *
615      * @returns The list of services.
616      */
GetServices(void) const617     const LinkedList<Service> &GetServices(void) const { return mServices; }
618 
619     /**
620      * Starts the remove process of the host info and all services.
621      *
622      * After returning from this method, `Callback` will be called to report the status of remove request with
623      * SRP server.
624      *
625      * If the host info is to be permanently removed from server, @p aRemoveKeyLease should be set to `true` which
626      * removes the key lease associated with host on server. Otherwise, the key lease record is kept as before, which
627      * ensures that the server holds the host name in reserve for when the client once again able to provide and
628      * register its service(s).
629      *
630      * The @p aSendUnregToServer determines the behavior when the host info is not yet registered with the server. If
631      * @p aSendUnregToServer is set to `false` (which is the default/expected value) then the SRP client will
632      * immediately remove the host info and services without sending an update message to server (no need to update the
633      * server if nothing is yet registered with it). If @p aSendUnregToServer is set to `true` then the SRP client will
634      * send an update message to the server. Note that if the host info is registered then the value of
635      * @p aSendUnregToServer does not matter and the SRP client will always send an update message to server requesting
636      * removal of all info.
637      *
638      * One situation where @p aSendUnregToServer can be useful is on a device reset/reboot, caller may want to remove
639      * any previously registered services with the server. In this case, caller can `SetHostName()` and then request
640      * `RemoveHostAndServices()` with `aSendUnregToServer` as `true`.
641      *
642      * @param[in] aShouldRemoveKeyLease  A boolean indicating whether or not the host key lease should also be removed.
643      * @param[in] aSendUnregToServer     A boolean indicating whether to send update to server when host info is not
644      *                                   registered.
645      *
646      * @retval kErrorNone      The removal of host and services started successfully. The `Callback` will be called
647      *                         to report the status.
648      * @retval kErrorAlready   The host is already removed.
649      */
650     Error RemoveHostAndServices(bool aShouldRemoveKeyLease, bool aSendUnregToServer = false);
651 
652     /**
653      * Clears all host info and all the services.
654      *
655      * Unlike `RemoveHostAndServices()` which sends an update message to the server to remove all the info, this method
656      * clears all the info immediately without any interaction with the server.
657      */
658     void ClearHostAndServices(void);
659 
660 #if OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
661     /**
662      * Gets the domain name being used by SRP client.
663      *
664      * If domain name is not set, "default.service.arpa" will be used.
665      *
666      * @returns The domain name string.
667      */
GetDomainName(void) const668     const char *GetDomainName(void) const { return mDomainName; }
669 
670     /**
671      * Sets the domain name to be used by SRP client.
672      *
673      * This is an optional method. If not set "default.service.arpa" will be used.
674      *
675      * The domain name can be set before client is started or after start but before host info is registered with server
676      * (host info should be in either `kToAdd` or `kToRemove`).
677      *
678      * @param[in] aName      A pointer to the domain name string. If NULL sets it to default "default.service.arpa".
679      *
680      * @retval kErrorNone           The domain name label was set successfully.
681      * @retval kErrorInvalidState   The host info is already registered with server.
682      */
683     Error SetDomainName(const char *aName);
684 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
685 
686     /**
687      * Converts a `ItemState` to a string.
688      *
689      * @param[in] aState   An `ItemState`.
690      *
691      * @returns A string representation of @p aState.
692      */
693     static const char *ItemStateToString(ItemState aState);
694 
695 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
696     /**
697      * Enables/disables "service key record inclusion" mode.
698      *
699      * When enabled, SRP client will include KEY record in Service Description Instructions in the SRP update messages
700      * that it sends.
701      *
702      * @note KEY record is optional in Service Description Instruction (it is required and always included in the Host
703      * Description Instruction). The default behavior of SRP client is to not include it. This method is added under
704      * `REFERENCE_DEVICE` config and is intended to override the default behavior for testing only.
705      *
706      * @param[in] aEnabled   TRUE to enable, FALSE to disable the "service key record inclusion" mode.
707      */
SetServiceKeyRecordEnabled(bool aEnabled)708     void SetServiceKeyRecordEnabled(bool aEnabled) { mServiceKeyRecordEnabled = aEnabled; }
709 
710     /**
711      * Indicates whether the "service key record inclusion" mode is enabled or disabled.
712      *
713      * @returns TRUE if "service key record inclusion" mode is enabled, FALSE otherwise.
714      */
IsServiceKeyRecordEnabled(void) const715     bool IsServiceKeyRecordEnabled(void) const { return mServiceKeyRecordEnabled; }
716 
717     /**
718      * Enables/disables "use short Update Lease Option" behavior.
719      *
720      * When enabled, the SRP client will use the short variant format of Update Lease Option in its message. The short
721      * format only includes the lease interval.
722      *
723      * Is added under `REFERENCE_DEVICE` config and is intended to override the default behavior for
724      * testing only.
725      *
726      * @param[in] aUseShort    TRUE to enable, FALSE to disable the "use short Update Lease Option" mode.
727      */
SetUseShortLeaseOption(bool aUseShort)728     void SetUseShortLeaseOption(bool aUseShort) { mUseShortLeaseOption = aUseShort; }
729 
730     /**
731      * Gets the current "use short Update Lease Option" mode.
732      *
733      * @returns TRUE if "use short Update Lease Option" mode is enabled, FALSE otherwise.
734      */
GetUseShortLeaseOption(void) const735     bool GetUseShortLeaseOption(void) const { return mUseShortLeaseOption; }
736 
737     /**
738      * Set the next DNS message ID for client to use.
739      *
740      * This is intended for testing only.
741      *
742      * @pram[in] aMessageId  A message ID.
743      */
SetNextMessageId(uint16_t aMessageId)744     void SetNextMessageId(uint16_t aMessageId) { mNextMessageId = aMessageId; }
745 
746 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
747 
748 private:
749     // Number of fast data polls after SRP Update tx (11x 188ms = ~2 seconds)
750     static constexpr uint8_t kFastPollsAfterUpdateTx = 11;
751 
752 #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE
753     static constexpr uint8_t kMaxTimeoutFailuresToSwitchServer =
754         OPENTHREAD_CONFIG_SRP_CLIENT_MAX_TIMEOUT_FAILURES_TO_SWITCH_SERVER;
755 #endif
756 
757     static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
758 
759     // -------------------------------
760     // Lease related constants
761 
762     static constexpr uint32_t kDefaultLease    = OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE;     // in seconds.
763     static constexpr uint32_t kDefaultKeyLease = OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE; // in seconds.
764 
765     // The guard interval determines how much earlier (relative to
766     // the lease expiration time) the client will send an update
767     // to renew the lease. Value is in seconds.
768     static constexpr uint32_t kLeaseRenewGuardInterval = OPENTHREAD_CONFIG_SRP_CLIENT_LEASE_RENEW_GUARD_INTERVAL;
769 
770     // Lease renew time jitter (in msec).
771     static constexpr uint16_t kLeaseRenewJitter = 15 * 1000; // 15 second
772 
773     // Max allowed lease time to avoid timer roll-over (~24.8 days).
774     static constexpr uint32_t kMaxLease = (Timer::kMaxDelay / 1000) - 1;
775 
776     // Opportunistic early refresh: When sending an SRP update, the
777     // services that are not yet expired but are close, are allowed
778     // to refresh early and are included in the SRP update. This
779     // helps place more services on the same lease refresh schedule
780     // reducing number of messages sent to the SRP server. The
781     // "early lease renewal interval" is used to determine if a
782     // service can renew early. The interval is calculated by
783     // multiplying the accepted lease interval by the"early lease
784     // renewal factor" which is given as a fraction (numerator and
785     // denominator).
786     //
787     // If the factor is set to zero (numerator=0, denominator=1),
788     // the opportunistic early refresh behavior is disabled. If
789     // denominator is set to zero (the factor is set to infinity),
790     // then all services (including previously registered ones)
791     // are always included in SRP update message.
792 
793     static constexpr uint32_t kEarlyLeaseRenewFactorNumerator =
794         OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR;
795     static constexpr uint32_t kEarlyLeaseRenewFactorDenominator =
796         OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_DENOMINATOR;
797 
798     // -------------------------------
799     // TX jitter constants
800     //
801     // When changes trigger a new SRP update message transmission a random
802     // jitter delay is applied before sending the update message to server.
803     // This can occur due to changes in client services or host info,
804     // or `AutoStart` selecting a server for the first time or switching
805     // to a new server thus requiring re-registration.
806     //
807     // The constants below specify jitter ranges applied based on
808     // different trigger reasons. All values are in milliseconds.
809     // Also see `TxJitter` class.
810 
811     static constexpr uint32_t kMinTxJitter                  = 10;
812     static constexpr uint32_t kMaxTxJitterDefault           = 500;
813     static constexpr uint32_t kMaxTxJitterOnDeviceReboot    = 700;
814     static constexpr uint32_t kMaxTxJitterOnServerStart     = 10 * Time::kOneSecondInMsec;
815     static constexpr uint32_t kMaxTxJitterOnServerRestart   = 10 * Time::kOneSecondInMsec;
816     static constexpr uint32_t kMaxTxJitterOnServerSwitch    = 10 * Time::kOneSecondInMsec;
817     static constexpr uint32_t kMaxTxJitterOnSlaacAddrAdd    = 10 * Time::kOneSecondInMsec;
818     static constexpr uint32_t kMaxTxJitterOnSlaacAddrRemove = 10 * Time::kOneSecondInMsec;
819 
820     static constexpr uint32_t kGuardTimeAfterAttachToUseShorterTxJitter = 1000;
821 
822     // -------------------------------
823     // Retry related constants
824     //
825     // If the preparation or transmission of an SRP update message
826     // fails (e.g., no buffer to allocate the message), SRP client
827     // will retry after a short interval `kTxFailureRetryInterval`
828     // up to `kMaxTxFailureRetries` attempts. After this, the retry
829     // wait interval will be used (which keeps growing on each failure
830     // - please see below).
831     //
832     // If the update message is sent successfully but there is no
833     // response from server or if server rejects the update, the
834     // client will retransmit the update message after some wait
835     // interval. The wait interval starts from the minimum value and
836     // is increased by the growth factor on back-to-back failures up
837     // to the max value. The growth factor is given as a fraction
838     // (e.g., for 1.5, we can use 15 as the numerator and 10 as the
839     // denominator). A random jitter is added to the retry interval.
840     // If the current wait interval value is smaller than the jitter
841     // interval, then wait interval value itself is used as the
842     // jitter value. For example, with jitter interval of 2 seconds
843     // if the current retry interval is 800ms, then a random wait
844     // interval in [0,2*800] ms will be used.
845 
846     static constexpr uint32_t kTxFailureRetryInterval = 250; // in ms
847     static constexpr uint32_t kMaxTxFailureRetries    = 8;   // num of quick retries after tx failure
848     static constexpr uint32_t kMinRetryWaitInterval   = OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL; // in ms
849     static constexpr uint32_t kMaxRetryWaitInterval   = OPENTHREAD_CONFIG_SRP_CLIENT_MAX_RETRY_WAIT_INTERVAL; // in ms
850     static constexpr uint32_t kRetryIntervalGrowthFactorNumerator =
851         OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_NUMERATOR;
852     static constexpr uint32_t kRetryIntervalGrowthFactorDenominator =
853         OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_DENOMINATOR;
854 
855     static constexpr uint16_t kTxFailureRetryJitter = 10;                                                      // in ms
856     static constexpr uint16_t kRetryIntervalJitter  = OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_WAIT_INTERVAL_JITTER; // in ms
857 
858     static_assert(kDefaultLease <= static_cast<uint32_t>(kMaxLease), "kDefaultLease is larger than max");
859     static_assert(kDefaultKeyLease <= static_cast<uint32_t>(kMaxLease), "kDefaultKeyLease is larger than max");
860 
861     enum State : uint8_t
862     {
863         kStateStopped,  // Client is stopped.
864         kStatePaused,   // Client is paused (due to device being detached).
865         kStateToUpdate, // Waiting to send SRP update
866         kStateUpdating, // SRP update is sent, waiting for response from server.
867         kStateUpdated,  // SRP update response received from server.
868         kStateToRetry,  // SRP update tx failed, waiting to retry.
869     };
870 
871     static constexpr bool kAutoStartDefaultMode = OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_DEFAULT_MODE;
872     static constexpr bool kDisallowSwitchOnRegisteredHost =
873         OPENTHREAD_CONFIG_SRP_CLIENT_DISALLOW_SERVER_SWITCH_WITH_REGISTERED_HOST;
874 
875     // Port number to use when server is discovered using "network data anycast service".
876     static constexpr uint16_t kAnycastServerPort = 53;
877 
878     static constexpr uint32_t kUnspecifiedInterval = 0; // Used for lease/key-lease intervals.
879 
880     // This enumeration type is used by the private `Start()` and
881     // `Stop()` methods to indicate whether it is being requested by the
882     // user or by the auto-start feature.
883     enum Requester : uint8_t
884     {
885         kRequesterUser,
886 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
887         kRequesterAuto,
888 #endif
889     };
890 
891     // This enumeration is used as an input to private `Stop()` to
892     // indicate whether to reset the retry interval or keep it as is.
893     enum StopMode : uint8_t
894     {
895         kResetRetryInterval,
896         kKeepRetryInterval,
897     };
898 
899     // Used in `ChangeHostAndServiceStates()`
900     enum ServiceStateChangeMode : uint8_t
901     {
902         kForAllServices,
903         kForServicesAppendedInMessage,
904     };
905 
906 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
907     typedef Crypto::Ecdsa::P256::KeyPairAsRef KeyInfo;
908 #else
909     typedef Crypto::Ecdsa::P256::KeyPair KeyInfo;
910 #endif
911 
912     class TxJitter : public Clearable<TxJitter>
913     {
914         // Manages the random TX jitter to use when sending SRP update
915         // messages.
916 
917     public:
918         enum Reason
919         {
920             kOnDeviceReboot,
921             kOnServerStart,
922             kOnServerRestart,
923             kOnServerSwitch,
924             kOnSlaacAddrAdd,
925             kOnSlaacAddrRemove,
926         };
927 
TxJitter(void)928         TxJitter(void) { Clear(); }
929         void     Request(Reason aReason);
930         uint32_t DetermineDelay(void);
931 
932     private:
933         static const uint32_t kMaxJitters[];
934 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
935         static const char *ReasonToString(Reason aReason);
936 #endif
937 
938         uint32_t  mRequestedMax;
939         TimeMilli mRequestTime;
940     };
941 
942 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
943     class AutoStart : public Clearable<AutoStart>
944     {
945     public:
946         enum State : uint8_t{
947             kDisabled,                 // Disabled.
948             kFirstTimeSelecting,       // Trying to select a server for the first time since AutoStart was enabled.
949             kReselecting,              // Trying to select a server again (previously selected server was removed).
950             kSelectedUnicastPreferred, // Has selected a preferred unicast entry (address in service data).
951             kSelectedAnycast,          // Has selected an anycast entry with `mAnycastSeqNum`.
952             kSelectedUnicast,          // Has selected a unicast entry (address in server data).
953         };
954 
955         AutoStart(void);
956         bool    HasSelectedServer(void) const;
GetState(void) const957         State   GetState(void) const { return mState; }
958         void    SetState(State aState);
GetAnycastSeqNum(void) const959         uint8_t GetAnycastSeqNum(void) const { return mAnycastSeqNum; }
SetAnycastSeqNum(uint8_t aAnycastSeqNum)960         void    SetAnycastSeqNum(uint8_t aAnycastSeqNum) { mAnycastSeqNum = aAnycastSeqNum; }
SetCallback(AutoStartCallback aCallback,void * aContext)961         void    SetCallback(AutoStartCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
962         void    InvokeCallback(const Ip6::SockAddr *aServerSockAddr) const;
963 
964 #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE
GetTimeoutFailureCount(void) const965         uint8_t GetTimeoutFailureCount(void) const { return mTimeoutFailureCount; }
ResetTimeoutFailureCount(void)966         void    ResetTimeoutFailureCount(void) { mTimeoutFailureCount = 0; }
IncrementTimeoutFailureCount(void)967         void    IncrementTimeoutFailureCount(void)
968         {
969             if (mTimeoutFailureCount < NumericLimits<uint8_t>::kMax)
970             {
971                 mTimeoutFailureCount++;
972             }
973         }
974 #endif
975 
976     private:
977         static constexpr bool kDefaultMode = OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_DEFAULT_MODE;
978 
979         static const char *StateToString(State aState);
980 
981         Callback<AutoStartCallback> mCallback;
982         State                       mState;
983         uint8_t                     mAnycastSeqNum;
984 #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE
985         uint8_t mTimeoutFailureCount; // Number of no-response timeout failures with the currently selected server.
986 #endif
987     };
988 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
989 
990     struct MsgInfo
991     {
992         static constexpr uint16_t kUnknownOffset = 0;
993 
994         OwnedPtr<Message> mMessage;
995         uint16_t          mDomainNameOffset;
996         uint16_t          mHostNameOffset;
997         uint16_t          mRecordCount;
998         KeyInfo           mKeyInfo;
999     };
1000 
1001     Error        Start(const Ip6::SockAddr &aServerSockAddr, Requester aRequester);
1002     void         Stop(Requester aRequester, StopMode aMode);
1003     void         Resume(void);
1004     void         Pause(void);
1005     void         HandleNotifierEvents(Events aEvents);
1006     void         HandleRoleChanged(void);
1007     void         HandleUnicastAddressEvent(Ip6::Netif::AddressEvent aEvent, const Ip6::Netif::UnicastAddress &aAddress);
1008     bool         ShouldUpdateHostAutoAddresses(void) const;
1009     bool         ShouldHostAutoAddressRegister(const Ip6::Netif::UnicastAddress &aUnicastAddress) const;
1010     Error        UpdateHostInfoStateOnAddressChange(void);
1011     void         UpdateServiceStateToRemove(Service &aService);
GetState(void) const1012     State        GetState(void) const { return mState; }
1013     void         SetState(State aState);
1014     bool         ChangeHostAndServiceStates(const ItemState *aNewStates, ServiceStateChangeMode aMode);
1015     void         InvokeCallback(Error aError) const;
1016     void         InvokeCallback(Error aError, const HostInfo &aHostInfo, const Service *aRemovedServices) const;
1017     void         HandleHostInfoOrServiceChange(void);
1018     void         SendUpdate(void);
1019     Error        PrepareUpdateMessage(MsgInfo &aInfo);
1020     Error        ReadOrGenerateKey(KeyInfo &aKeyInfo);
1021     Error        AppendServiceInstructions(MsgInfo &aInfo);
1022     bool         CanAppendService(const Service &aService);
1023     Error        AppendServiceInstruction(Service &aService, MsgInfo &aInfo);
1024     Error        AppendHostDescriptionInstruction(MsgInfo &aInfo);
1025     Error        AppendKeyRecord(MsgInfo &aInfo) const;
1026     Error        AppendDeleteAllRrsets(MsgInfo &aInfo) const;
1027     Error        AppendHostName(MsgInfo &aInfo, bool aDoNotCompress = false) const;
1028     Error        AppendAaaaRecord(const Ip6::Address &aAddress, MsgInfo &aInfo) const;
1029     Error        AppendUpdateLeaseOptRecord(MsgInfo &aInfo);
1030     Error        AppendSignature(MsgInfo &aInfo);
1031     void         UpdateRecordLengthInMessage(Dns::ResourceRecord &aRecord, uint16_t aOffset, Message &aMessage) const;
1032     void         HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1033     void         ProcessResponse(Message &aMessage);
1034     bool         IsResponseMessageIdValid(uint16_t aId) const;
1035     void         HandleUpdateDone(void);
1036     void         GetRemovedServices(LinkedList<Service> &aRemovedServices);
1037     static Error ReadResourceRecord(const Message &aMessage, uint16_t &aOffset, Dns::ResourceRecord &aRecord);
1038     Error        ProcessOptRecord(const Message &aMessage, uint16_t aOffset, const Dns::OptRecord &aOptRecord);
1039     void         UpdateState(void);
GetRetryWaitInterval(void) const1040     uint32_t     GetRetryWaitInterval(void) const { return mRetryWaitInterval; }
ResetRetryWaitInterval(void)1041     void         ResetRetryWaitInterval(void) { mRetryWaitInterval = kMinRetryWaitInterval; }
1042     void         GrowRetryWaitInterval(void);
1043     uint32_t     DetermineLeaseInterval(uint32_t aInterval, uint32_t aDefaultInterval) const;
1044     uint32_t     DetermineTtl(void) const;
1045     bool         ShouldRenewEarly(const Service &aService) const;
1046     void         HandleTimer(void);
1047 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
1048     void  ApplyAutoStartGuardOnAttach(void);
1049     void  ProcessAutoStart(void);
1050     Error SelectUnicastEntry(DnsSrpUnicastType aType, DnsSrpUnicastInfo &aInfo) const;
HandleGuardTimer(void)1051     void  HandleGuardTimer(void) {}
1052 #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE
1053     void SelectNextServer(bool aDisallowSwitchOnRegisteredHost);
1054 #endif
1055 #endif
1056 
1057 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
1058     static const char *StateToString(State aState);
1059     void               LogRetryWaitInterval(void) const;
1060 #else
LogRetryWaitInterval(void) const1061     void                                 LogRetryWaitInterval(void) const {}
1062 #endif
1063 
1064     static const char kDefaultDomainName[];
1065 
1066     static_assert(kMaxTxFailureRetries < 16, "kMaxTxFailureRetries exceed the range of mTxFailureRetryCount (4-bit)");
1067 
1068     using DelayTimer   = TimerMilliIn<Client, &Client::HandleTimer>;
1069     using ClientSocket = Ip6::Udp::SocketIn<Client, &Client::HandleUdpReceive>;
1070 
1071 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
1072     using GuardTimer = TimerMilliIn<Client, &Client::HandleGuardTimer>;
1073 #endif
1074 
1075     State   mState;
1076     uint8_t mTxFailureRetryCount : 4;
1077     bool    mShouldRemoveKeyLease : 1;
1078     bool    mSingleServiceMode : 1;
1079 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
1080     bool mServiceKeyRecordEnabled : 1;
1081     bool mUseShortLeaseOption : 1;
1082 #endif
1083 
1084     uint16_t mNextMessageId;
1085     uint16_t mResponseMessageId;
1086     uint16_t mAutoHostAddressCount;
1087     uint32_t mRetryWaitInterval;
1088 
1089     TimeMilli mLeaseRenewTime;
1090     uint32_t  mTtl;
1091     uint32_t  mLease;
1092     uint32_t  mKeyLease;
1093     uint32_t  mDefaultLease;
1094     uint32_t  mDefaultKeyLease;
1095     TxJitter  mTxJitter;
1096 
1097     ClientSocket mSocket;
1098 
1099     Callback<ClientCallback> mCallback;
1100     const char              *mDomainName;
1101     HostInfo                 mHostInfo;
1102     LinkedList<Service>      mServices;
1103     DelayTimer               mTimer;
1104 #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
1105     GuardTimer mGuardTimer;
1106     AutoStart  mAutoStart;
1107 #endif
1108 };
1109 
1110 } // namespace Srp
1111 
1112 DefineCoreType(otSrpClientHostInfo, Srp::Client::HostInfo);
1113 DefineCoreType(otSrpClientService, Srp::Client::Service);
1114 DefineMapEnum(otSrpClientItemState, Srp::Client::ItemState);
1115 
1116 } // namespace ot
1117 
1118 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
1119 
1120 #endif // SRP_CLIENT_HPP_
1121