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