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 /**
30  * @file
31  *   This file includes definitions for SRP server.
32  */
33 
34 #ifndef NET_SRP_SERVER_HPP_
35 #define NET_SRP_SERVER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
40 
41 #if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
42 #error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE"
43 #endif
44 
45 #if !OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
46 #error "OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE"
47 #endif
48 
49 #if !OPENTHREAD_CONFIG_ECDSA_ENABLE
50 #error "OPENTHREAD_CONFIG_ECDSA_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE"
51 #endif
52 
53 #include <openthread/ip6.h>
54 #include <openthread/srp_server.h>
55 
56 #include "common/array.hpp"
57 #include "common/as_core_type.hpp"
58 #include "common/callback.hpp"
59 #include "common/clearable.hpp"
60 #include "common/heap.hpp"
61 #include "common/heap_allocatable.hpp"
62 #include "common/heap_array.hpp"
63 #include "common/heap_data.hpp"
64 #include "common/heap_string.hpp"
65 #include "common/linked_list.hpp"
66 #include "common/locator.hpp"
67 #include "common/non_copyable.hpp"
68 #include "common/notifier.hpp"
69 #include "common/num_utils.hpp"
70 #include "common/numeric_limits.hpp"
71 #include "common/retain_ptr.hpp"
72 #include "common/timer.hpp"
73 #include "crypto/ecdsa.hpp"
74 #include "net/dns_types.hpp"
75 #include "net/ip6.hpp"
76 #include "net/ip6_address.hpp"
77 #include "net/udp6.hpp"
78 #include "thread/network_data_publisher.hpp"
79 
80 struct otSrpServerHost
81 {
82 };
83 
84 struct otSrpServerService
85 {
86 };
87 
88 namespace ot {
89 
90 namespace Dns {
91 namespace ServiceDiscovery {
92 class Server;
93 }
94 } // namespace Dns
95 
96 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
97 namespace BorderRouter {
98 class RoutingManager;
99 }
100 #endif
101 
102 namespace Srp {
103 
104 /**
105  * This class implements the SRP server.
106  *
107  */
108 class Server : public InstanceLocator, private NonCopyable
109 {
110     friend class NetworkData::Publisher;
111     friend class UpdateMetadata;
112     friend class Service;
113     friend class Host;
114     friend class Dns::ServiceDiscovery::Server;
115 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
116     friend class BorderRouter::RoutingManager;
117 #endif
118 
119     enum RetainName : bool
120     {
121         kDeleteName = false,
122         kRetainName = true,
123     };
124 
125     enum NotifyMode : bool
126     {
127         kDoNotNotifyServiceHandler = false,
128         kNotifyServiceHandler      = true,
129     };
130 
131 public:
132     static constexpr uint16_t kUdpPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN; ///< The reserved min port.
133     static constexpr uint16_t kUdpPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX; ///< The reserved max port.
134 
135     static_assert(kUdpPortMin <= kUdpPortMax, "invalid port range");
136 
137     /**
138      * The ID of SRP service update transaction.
139      *
140      */
141     typedef otSrpServerServiceUpdateId ServiceUpdateId;
142 
143     /**
144      * The SRP server lease information of a host/service.
145      *
146      */
147     typedef otSrpServerLeaseInfo LeaseInfo;
148 
149     /**
150      * This enumeration represents the address mode used by the SRP server.
151      *
152      * Address mode specifies how the address and port number are determined by the SRP server and how this info ins
153      * published in the Thread Network Data.
154      *
155      */
156     enum AddressMode : uint8_t
157     {
158         kAddressModeUnicast = OT_SRP_SERVER_ADDRESS_MODE_UNICAST, ///< Unicast address mode.
159         kAddressModeAnycast = OT_SRP_SERVER_ADDRESS_MODE_ANYCAST, ///< Anycast address mode.
160     };
161 
162     class Host;
163 
164     /**
165      * This enumeration represents the state of SRP server.
166      *
167      */
168     enum State : uint8_t
169     {
170         kStateDisabled = OT_SRP_SERVER_STATE_DISABLED, ///< Server is disabled.
171         kStateRunning  = OT_SRP_SERVER_STATE_RUNNING,  ///< Server is enabled and running.
172         kStateStopped  = OT_SRP_SERVER_STATE_STOPPED,  ///< Server is enabled but stopped.
173     };
174 
175     /**
176      * This class implements a server-side SRP service.
177      *
178      */
179     class Service : public otSrpServerService,
180                     public LinkedListEntry<Service>,
181                     private Heap::Allocatable<Service>,
182                     private NonCopyable
183     {
184         friend class Server;
185         friend class LinkedList<Service>;
186         friend class LinkedListEntry<Service>;
187         friend class Heap::Allocatable<Service>;
188 
189     public:
190         /**
191          * This type represents the flags which indicates which services to include or exclude when searching in (or
192          * iterating over) the list of SRP services.
193          *
194          */
195         typedef otSrpServerServiceFlags Flags;
196 
197         /**
198          * This `Flags` constant indicates to include base services (not a sub-type).
199          *
200          */
201         static constexpr Flags kFlagBaseType = OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE;
202 
203         /**
204          * This `Flags` constant indicates to include sub-type services.
205          *
206          */
207         static constexpr Flags kFlagSubType = OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE;
208 
209         /**
210          * This `Flags` constant indicates to include active (not deleted) services.
211          *
212          */
213         static constexpr Flags kFlagActive = OT_SRP_SERVER_SERVICE_FLAG_ACTIVE;
214 
215         /**
216          * This `Flags` constant indicates to include deleted services.
217          *
218          */
219         static constexpr Flags kFlagDeleted = OT_SRP_SERVER_SERVICE_FLAG_DELETED;
220 
221         /**
222          * This method tells if the SRP service has been deleted.
223          *
224          * A SRP service can be deleted but retains its name for future uses.
225          * In this case, the service instance is not removed from the SRP server/registry.
226          * It is guaranteed that all services are deleted if the host is deleted.
227          *
228          * @returns  TRUE if the service has been deleted, FALSE if not.
229          *
230          */
IsDeleted(void) const231         bool IsDeleted(void) const { return mIsDeleted; }
232 
233         /**
234          * This method indicates whether the SRP service is a sub-type.
235          *
236          * @retval TRUE    If the service is a sub-type.
237          * @retval FALSE   If the service is not a sub-type.
238          *
239          */
IsSubType(void) const240         bool IsSubType(void) const { return mIsSubType; }
241 
242         /**
243          * This method gets the full service instance name of the service.
244          *
245          * @returns  A pointer service instance name (as a null-terminated C string).
246          *
247          */
GetInstanceName(void) const248         const char *GetInstanceName(void) const { return mDescription->mInstanceName.AsCString(); }
249 
250         /**
251          * This method gets the full service name of the service.
252          *
253          * @returns  A pointer service name (as a null-terminated C string).
254          *
255          */
GetServiceName(void) const256         const char *GetServiceName(void) const { return mServiceName.AsCString(); }
257 
258         /**
259          * This method gets the sub-type label from service name.
260          *
261          * The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This
262          * method copies the `<sub-label>` into the @p aLabel buffer.
263          *
264          * The @p aLabel is ensured to always be null-terminated after returning even in case of failure.
265          *
266          * @param[out] aLabel        A pointer to a buffer to copy the sub-type label name.
267          * @param[in]  aMaxSize      Maximum size of @p aLabel buffer.
268          *
269          * @retval kErrorNone         @p aLabel was updated successfully.
270          * @retval kErrorNoBufs       The sub-type label could not fit in @p aLabel buffer (number of chars from label
271          *                            that could fit are copied in @p aLabel ensuring it is null-terminated).
272          * @retval kErrorInvalidArgs  SRP service is not a sub-type.
273          *
274          */
275         Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
276 
277         /**
278          * This method returns the TTL of the service instance.
279          *
280          * @returns The TTL of the service instance.
281          *
282          */
GetTtl(void) const283         uint32_t GetTtl(void) const { return mDescription->mTtl; }
284 
285         /**
286          * This method returns the port of the service instance.
287          *
288          * @returns  The port of the service.
289          *
290          */
GetPort(void) const291         uint16_t GetPort(void) const { return mDescription->mPort; }
292 
293         /**
294          * This method returns the weight of the service instance.
295          *
296          * @returns  The weight of the service.
297          *
298          */
GetWeight(void) const299         uint16_t GetWeight(void) const { return mDescription->mWeight; }
300 
301         /**
302          * This method returns the priority of the service instance.
303          *
304          * @returns  The priority of the service.
305          *
306          */
GetPriority(void) const307         uint16_t GetPriority(void) const { return mDescription->mPriority; }
308 
309         /**
310          * This method returns the TXT record data of the service instance.
311          *
312          * @returns A pointer to the buffer containing the TXT record data.
313          *
314          */
GetTxtData(void) const315         const uint8_t *GetTxtData(void) const { return mDescription->mTxtData.GetBytes(); }
316 
317         /**
318          * This method returns the TXT record data length of the service instance.
319          *
320          * @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`).
321          *
322          */
GetTxtDataLength(void) const323         uint16_t GetTxtDataLength(void) const { return mDescription->mTxtData.GetLength(); }
324 
325         /**
326          * This method returns the host which the service instance reside on.
327          *
328          * @returns  A reference to the host instance.
329          *
330          */
GetHost(void) const331         const Host &GetHost(void) const { return *mDescription->mHost; }
332 
333         /**
334          * This method returns the LEASE time of the service.
335          *
336          * @returns  The LEASE time in seconds.
337          *
338          */
GetLease(void) const339         uint32_t GetLease(void) const { return mDescription->mLease; }
340 
341         /**
342          * This method returns the KEY-LEASE time of the key of the service.
343          *
344          * @returns  The KEY-LEASE time in seconds.
345          *
346          */
GetKeyLease(void) const347         uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; }
348 
349         /**
350          * This method returns the expire time (in milliseconds) of the service.
351          *
352          * @returns  The service expire time in milliseconds.
353          *
354          */
355         TimeMilli GetExpireTime(void) const;
356 
357         /**
358          * This method returns the key expire time (in milliseconds) of the service.
359          *
360          * @returns  The service key expire time in milliseconds.
361          *
362          */
363         TimeMilli GetKeyExpireTime(void) const;
364 
365         /**
366          * This method gets the LEASE and KEY-LEASE information of a given service.
367          *
368          * @param[out]  aLeaseInfo  A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
369          *                          remaining LEASE time and the remaining KEY-LEASE time.
370          *
371          */
372         void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
373 
374         /**
375          * This method indicates whether this service matches a given service instance name.
376          *
377          * @param[in]  aInstanceName  The service instance name.
378          *
379          * @retval  TRUE   If the service matches the service instance name.
380          * @retval  FALSE  If the service does not match the service instance name.
381          *
382          */
383         bool MatchesInstanceName(const char *aInstanceName) const;
384 
385         /**
386          * This method tells whether this service matches a given service name.
387          *
388          * @param[in] aServiceName  The full service name to match.
389          *
390          * @retval  TRUE   If the service matches the full service name.
391          * @retval  FALSE  If the service does not match the full service name.
392          *
393          */
394         bool MatchesServiceName(const char *aServiceName) const;
395 
396     private:
397         struct Description : public LinkedListEntry<Description>,
398                              public Heap::Allocatable<Description>,
399                              public RetainCountable,
400                              private NonCopyable
401         {
402             Error       Init(const char *aInstanceName, Host &aHost);
GetInstanceNameot::Srp::Server::Service::Description403             const char *GetInstanceName(void) const { return mInstanceName.AsCString(); }
404             bool        Matches(const char *aInstanceName) const;
405             void        ClearResources(void);
406             void        TakeResourcesFrom(Description &aDescription);
407             Error       SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
408 
409             Description *mNext;
410             Heap::String mInstanceName;
411             Host        *mHost;
412             Heap::Data   mTxtData;
413             uint16_t     mPriority;
414             uint16_t     mWeight;
415             uint16_t     mPort;
416             uint32_t     mTtl;      // The TTL in seconds.
417             uint32_t     mLease;    // The LEASE time in seconds.
418             uint32_t     mKeyLease; // The KEY-LEASE time in seconds.
419             TimeMilli    mUpdateTime;
420         };
421 
422         enum Action : uint8_t
423         {
424             kAddNew,
425             kUpdateExisting,
426             kRemoveButRetainName,
427             kFullyRemove,
428             kLeaseExpired,
429             kKeyLeaseExpired,
430         };
431 
432         Error Init(const char *aServiceName, Description &aDescription, bool aIsSubType, TimeMilli aUpdateTime);
433         bool  MatchesFlags(Flags aFlags) const;
GetUpdateTime(void) const434         const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; }
435         void             Log(Action aAction) const;
436 
437         Heap::String           mServiceName;
438         RetainPtr<Description> mDescription;
439         Service               *mNext;
440         TimeMilli              mUpdateTime;
441         bool                   mIsDeleted : 1;
442         bool                   mIsSubType : 1;
443         bool                   mIsCommitted : 1;
444     };
445 
446     /**
447      * This class implements the Host which registers services on the SRP server.
448      *
449      */
450     class Host : public otSrpServerHost,
451                  public InstanceLocator,
452                  public LinkedListEntry<Host>,
453                  private Heap::Allocatable<Host>,
454                  private NonCopyable
455     {
456         friend class Server;
457         friend class LinkedListEntry<Host>;
458         friend class Heap::Allocatable<Host>;
459 
460     public:
461         /**
462          * This method tells whether the Host object has been deleted.
463          *
464          * The Host object retains event if the host has been deleted by the SRP client,
465          * because the host name may retain.
466          *
467          * @returns  TRUE if the host is deleted, FALSE if the host is not deleted.
468          *
469          */
IsDeleted(void) const470         bool IsDeleted(void) const { return (mLease == 0); }
471 
472         /**
473          * This method returns the full name of the host.
474          *
475          * @returns  A pointer to the null-terminated full host name.
476          *
477          */
GetFullName(void) const478         const char *GetFullName(void) const { return mFullName.AsCString(); }
479 
480         /**
481          * This method returns addresses of the host.
482          *
483          * @param[out]  aAddressesNum  The number of the addresses.
484          *
485          * @returns  A pointer to the addresses array or `nullptr` if no addresses.
486          *
487          */
GetAddresses(uint8_t & aAddressesNum) const488         const Ip6::Address *GetAddresses(uint8_t &aAddressesNum) const
489         {
490             aAddressesNum = ClampToUint8(mAddresses.GetLength());
491 
492             return mAddresses.AsCArray();
493         }
494 
495         /**
496          * This method returns the TTL of the host.
497          *
498          * @returns The TTL of the host.
499          *
500          */
GetTtl(void) const501         uint32_t GetTtl(void) const { return mTtl; }
502 
503         /**
504          * This method returns the LEASE time of the host.
505          *
506          * @returns  The LEASE time in seconds.
507          *
508          */
GetLease(void) const509         uint32_t GetLease(void) const { return mLease; }
510 
511         /**
512          * This method returns the KEY-LEASE time of the key of the host.
513          *
514          * @returns  The KEY-LEASE time in seconds.
515          *
516          */
GetKeyLease(void) const517         uint32_t GetKeyLease(void) const { return mKeyLease; }
518 
519         /**
520          * This method gets the LEASE and KEY-LEASE information of a given host.
521          *
522          * @param[out]  aLeaseInfo  A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
523          *                          remaining LEASE time and the remaining KEY-LEASE time.
524          *
525          */
526         void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
527 
528         /**
529          * This method returns the KEY resource record of the host.
530          *
531          * @returns  A pointer to the ECDSA P 256 public key resource record
532          *           if there is valid one. `nullptr` if no valid key exists.
533          *
534          */
GetKeyRecord(void) const535         const Dns::Ecdsa256KeyRecord *GetKeyRecord(void) const { return mKeyRecord.IsValid() ? &mKeyRecord : nullptr; }
536 
537         /**
538          * This method returns the expire time (in milliseconds) of the host.
539          *
540          * @returns  The expire time in milliseconds.
541          *
542          */
543         TimeMilli GetExpireTime(void) const;
544 
545         /**
546          * This method returns the expire time (in milliseconds) of the key of the host.
547          *
548          * @returns  The expire time of the key in milliseconds.
549          *
550          */
551         TimeMilli GetKeyExpireTime(void) const;
552 
553         /**
554          * This method returns the `Service` linked list associated with the host.
555          *
556          * @returns The `Service` linked list.
557          *
558          */
GetServices(void) const559         const LinkedList<Service> &GetServices(void) const { return mServices; }
560 
561         /**
562          * This method finds the next matching service on the host.
563          *
564          * @param[in] aPrevService   A pointer to the previous service or `nullptr` to start from beginning of the list.
565          * @param[in] aFlags         Flags indicating which services to include (base/sub-type, active/deleted).
566          * @param[in] aServiceName   The service name to match. Set to `nullptr` to accept any name.
567          * @param[in] aInstanceName  The service instance name to match. Set to `nullptr` to accept any name.
568          *
569          * @returns  A pointer to the next matching service or `nullptr` if no matching service could be found.
570          *
571          */
572         const Service *FindNextService(const Service *aPrevService,
573                                        Service::Flags aFlags        = kFlagsAnyService,
574                                        const char    *aServiceName  = nullptr,
575                                        const char    *aInstanceName = nullptr) const;
576 
577         /**
578          * This method tells whether the host matches a given full name.
579          *
580          * @param[in]  aFullName  The full name.
581          *
582          * @returns  A boolean that indicates whether the host matches the given name.
583          *
584          */
585         bool Matches(const char *aFullName) const;
586 
587     private:
588         Host(Instance &aInstance, TimeMilli aUpdateTime);
589         ~Host(void);
590 
591         Error SetFullName(const char *aFullName);
592         void  SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
SetTtl(uint32_t aTtl)593         void  SetTtl(uint32_t aTtl) { mTtl = aTtl; }
SetLease(uint32_t aLease)594         void  SetLease(uint32_t aLease) { mLease = aLease; }
SetKeyLease(uint32_t aKeyLease)595         void  SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
SetUseShortLeaseOption(bool aUse)596         void  SetUseShortLeaseOption(bool aUse) { mUseShortLeaseOption = aUse; }
ShouldUseShortLeaseOption(void) const597         bool  ShouldUseShortLeaseOption(void) const { return mUseShortLeaseOption; }
598         Error ProcessTtl(uint32_t aTtl);
599 
GetServices(void)600         LinkedList<Service> &GetServices(void) { return mServices; }
601         Service             *AddNewService(const char *aServiceName,
602                                            const char *aInstanceName,
603                                            bool        aIsSubType,
604                                            TimeMilli   aUpdateTime);
605         void                 RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
606         Error                AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime);
607         void                 FreeAllServices(void);
608         void                 ClearResources(void);
609         Error                MergeServicesAndResourcesFrom(Host &aHost);
610         Error                AddIp6Address(const Ip6::Address &aIp6Address);
611         bool                 HasServiceInstance(const char *aInstanceName) const;
612         RetainPtr<Service::Description>       FindServiceDescription(const char *aInstanceName);
613         const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
614         Service                              *FindService(const char *aServiceName, const char *aInstanceName);
615         const Service                        *FindService(const char *aServiceName, const char *aInstanceName) const;
616         Service                              *FindBaseService(const char *aInstanceName);
617         const Service                        *FindBaseService(const char *aInstanceName) const;
618 
619         Host                     *mNext;
620         Heap::String              mFullName;
621         Heap::Array<Ip6::Address> mAddresses;
622 
623         // TODO(wgtdkp): there is no necessary to save the entire resource
624         // record, saving only the ECDSA-256 public key should be enough.
625         Dns::Ecdsa256KeyRecord mKeyRecord;
626         uint32_t               mTtl;      // The TTL in seconds.
627         uint32_t               mLease;    // The LEASE time in seconds.
628         uint32_t               mKeyLease; // The KEY-LEASE time in seconds.
629         TimeMilli              mUpdateTime;
630         LinkedList<Service>    mServices;
631         bool                   mUseShortLeaseOption; // Use short lease option (lease only - 4 byte) when responding.
632     };
633 
634     /**
635      * This class handles TTL configuration.
636      *
637      */
638     class TtlConfig : public otSrpServerTtlConfig
639     {
640         friend class Server;
641 
642     public:
643         /**
644          * This constructor initializes to default TTL configuration.
645          *
646          */
647         TtlConfig(void);
648 
649     private:
IsValid(void) const650         bool     IsValid(void) const { return mMinTtl <= mMaxTtl; }
651         uint32_t GrantTtl(uint32_t aLease, uint32_t aTtl) const;
652     };
653 
654     /**
655      * This class handles LEASE and KEY-LEASE configurations.
656      *
657      */
658     class LeaseConfig : public otSrpServerLeaseConfig
659     {
660         friend class Server;
661 
662     public:
663         /**
664          * This constructor initialize to default LEASE and KEY-LEASE configurations.
665          *
666          */
667         LeaseConfig(void);
668 
669     private:
670         bool     IsValid(void) const;
671         uint32_t GrantLease(uint32_t aLease) const;
672         uint32_t GrantKeyLease(uint32_t aKeyLease) const;
673     };
674 
675     /**
676      * This constant defines a `Service::Flags` combination accepting any service (base/sub-type, active/deleted).
677      *
678      */
679     static constexpr Service::Flags kFlagsAnyService = OT_SRP_SERVER_FLAGS_ANY_SERVICE;
680 
681     /**
682      * This constant defines a `Service::Flags` combination accepting base services only.
683      *
684      */
685     static constexpr Service::Flags kFlagsBaseTypeServiceOnly = OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY;
686 
687     /**
688      * This constant defines a `Service::Flags` combination accepting sub-type services only.
689      *
690      */
691     static constexpr Service::Flags kFlagsSubTypeServiceOnly = OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY;
692 
693     /**
694      * This constant defines a `Service::Flags` combination accepting any active services (not deleted).
695      *
696      */
697     static constexpr Service::Flags kFlagsAnyTypeActiveService = OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE;
698 
699     /**
700      * This constant defines a `Service::Flags` combination accepting any deleted services.
701      *
702      */
703     static constexpr Service::Flags kFlagsAnyTypeDeletedService = OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE;
704 
705     /**
706      * This constructor initializes the SRP server object.
707      *
708      * @param[in]  aInstance  A reference to the OpenThread instance.
709      *
710      */
711     explicit Server(Instance &aInstance);
712 
713     /**
714      * This method sets the SRP service events handler.
715      *
716      * @param[in]  aServiceHandler         A service events handler.
717      * @param[in]  aServiceHandlerContext  A pointer to arbitrary context information.
718      *
719      * @note  The handler SHOULD call HandleServiceUpdateResult to report the result of its processing.
720      *        Otherwise, a SRP update will be considered failed.
721      *
722      * @sa  HandleServiceUpdateResult
723      *
724      */
SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler,void * aServiceHandlerContext)725     void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext)
726     {
727         mServiceUpdateHandler.Set(aServiceHandler, aServiceHandlerContext);
728     }
729 
730     /**
731      * This method returns the domain authorized to the SRP server.
732      *
733      * If the domain if not set by SetDomain, "default.service.arpa." will be returned.
734      * A trailing dot is always appended even if the domain is set without it.
735      *
736      * @returns A pointer to the dot-joined domain string.
737      *
738      */
GetDomain(void) const739     const char *GetDomain(void) const { return mDomain.AsCString(); }
740 
741     /**
742      * This method sets the domain on the SRP server.
743      *
744      * A trailing dot will be appended to @p aDomain if it is not already there.
745      * This method should only be called before the SRP server is enabled.
746      *
747      * @param[in]  aDomain  The domain to be set. MUST NOT be `nullptr`.
748      *
749      * @retval  kErrorNone          Successfully set the domain to @p aDomain.
750      * @retval  kErrorInvalidState  The SRP server is already enabled and the Domain cannot be changed.
751      * @retval  kErrorInvalidArgs   The argument @p aDomain is not a valid DNS domain name.
752      * @retval  kErrorNoBufs        There is no memory to store content of @p aDomain.
753      *
754      */
755     Error SetDomain(const char *aDomain);
756 
757     /**
758      * This method returns the address mode being used by the SRP server.
759      *
760      * @returns The SRP server's address mode.
761      *
762      */
GetAddressMode(void) const763     AddressMode GetAddressMode(void) const { return mAddressMode; }
764 
765     /**
766      * This method sets the address mode to be used by the SRP server.
767      *
768      * @param[in] aMode      The address mode to use.
769      *
770      * @retval kErrorNone           Successfully set the address mode.
771      * @retval kErrorInvalidState   The SRP server is enabled and the address mode cannot be changed.
772      *
773      */
774     Error SetAddressMode(AddressMode aMode);
775 
776     /**
777      * This method gets the sequence number used with anycast address mode.
778      *
779      * The sequence number is included in "DNS/SRP Service Anycast Address" entry published in the Network Data.
780      *
781      * @returns The anycast sequence number.
782      *
783      */
GetAnycastModeSequenceNumber(void) const784     uint8_t GetAnycastModeSequenceNumber(void) const { return mAnycastSequenceNumber; }
785 
786     /**
787      * This method sets the sequence number used with anycast address mode.
788      *
789      * @param[in] aSequenceNumber  The sequence number to use.
790      *
791      * @retval kErrorNone           Successfully set the address mode.
792      * @retval kErrorInvalidState   The SRP server is enabled and the sequence number cannot be changed.
793      *
794      */
795     Error SetAnycastModeSequenceNumber(uint8_t aSequenceNumber);
796 
797     /**
798      * This method returns the state of the SRP server.
799      *
800      * @returns  The state of the server.
801      *
802      */
GetState(void) const803     State GetState(void) const { return mState; }
804 
805     /**
806      * This method tells the port the SRP server is listening to.
807      *
808      * @returns  The port of the server or 0 if the SRP server is not running.
809      *
810      */
GetPort(void) const811     uint16_t GetPort(void) const { return (mState == kStateRunning) ? mPort : 0; }
812 
813     /**
814      * This method enables/disables the SRP server.
815      *
816      * @param[in]  aEnabled  A boolean to enable/disable the SRP server.
817      *
818      */
819     void SetEnabled(bool aEnabled);
820 
821 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
822     /**
823      * This method enables/disables the auto-enable mode on SRP server.
824      *
825      * When this mode is enabled, the Border Routing Manager controls if/when to enable or disable the SRP server.
826      * SRP sever is auto-enabled if/when Border Routing is started it is done with the initial prefix and route
827      * configurations (when the OMR and on-link prefixes are determined, advertised in emitted Router Advert message on
828      * infrastructure side and published in the Thread Network Data). The SRP server is auto-disabled when BR is
829      * stopped (e.g., if the infrastructure network interface is brought down or if BR gets detached).
830      *
831      * This mode can be disabled by a `SetAutoEnableMode(false)` call or if the SRP server is explicitly enabled or
832      * disabled by a call to `SetEnabled()` method. Disabling auto-enable mode using `SetAutoEnableMode(false` call
833      * will not change the current state of SRP sever (e.g., if it is enabled it stays enabled).
834      *
835      * @param[in] aEnabled    A boolean to enable/disable the auto-enable mode.
836      *
837      */
838     void SetAutoEnableMode(bool aEnabled);
839 
840     /**
841      * This method indicates whether the auto-enable mode is enabled or disabled.
842      *
843      * @retval TRUE   The auto-enable mode is enabled.
844      * @retval FALSE  The auto-enable mode is disabled.
845      *
846      */
IsAutoEnableMode(void) const847     bool IsAutoEnableMode(void) const { return mAutoEnable; }
848 #endif
849 
850     /**
851      * This method returns the TTL configuration.
852      *
853      * @param[out]  aTtlConfig  A reference to the `TtlConfig` instance.
854      *
855      */
GetTtlConfig(TtlConfig & aTtlConfig) const856     void GetTtlConfig(TtlConfig &aTtlConfig) const { aTtlConfig = mTtlConfig; }
857 
858     /**
859      * This method sets the TTL configuration.
860      *
861      * @param[in]  aTtlConfig  A reference to the `TtlConfig` instance.
862      *
863      * @retval  kErrorNone         Successfully set the TTL configuration
864      * @retval  kErrorInvalidArgs  The TTL range is not valid.
865      *
866      */
867     Error SetTtlConfig(const TtlConfig &aTtlConfig);
868 
869     /**
870      * This method returns the LEASE and KEY-LEASE configurations.
871      *
872      * @param[out]  aLeaseConfig  A reference to the `LeaseConfig` instance.
873      *
874      */
GetLeaseConfig(LeaseConfig & aLeaseConfig) const875     void GetLeaseConfig(LeaseConfig &aLeaseConfig) const { aLeaseConfig = mLeaseConfig; }
876 
877     /**
878      * This method sets the LEASE and KEY-LEASE configurations.
879      *
880      * When a LEASE time is requested from a client, the granted value will be
881      * limited in range [aMinLease, aMaxLease]; and a KEY-LEASE will be granted
882      * in range [aMinKeyLease, aMaxKeyLease].
883      *
884      * @param[in]  aLeaseConfig  A reference to the `LeaseConfig` instance.
885      *
886      * @retval  kErrorNone         Successfully set the LEASE and KEY-LEASE ranges.
887      * @retval  kErrorInvalidArgs  The LEASE or KEY-LEASE range is not valid.
888      *
889      */
890     Error SetLeaseConfig(const LeaseConfig &aLeaseConfig);
891 
892     /**
893      * This method returns the next registered SRP host.
894      *
895      * @param[in]  aHost  The current SRP host; use `nullptr` to get the first SRP host.
896      *
897      * @returns  A pointer to the next SRP host or `nullptr` if no more SRP hosts can be found.
898      *
899      */
900     const Host *GetNextHost(const Host *aHost);
901 
902     /**
903      * This method returns the response counters of the SRP server.
904      *
905      * @returns  A pointer to the response counters of the SRP server.
906      *
907      */
GetResponseCounters(void) const908     const otSrpServerResponseCounters *GetResponseCounters(void) const { return &mResponseCounters; }
909 
910     /**
911      * This method receives the service update result from service handler set by
912      * SetServiceHandler.
913      *
914      * @param[in]  aId     The ID of the service update transaction.
915      * @param[in]  aError  The service update result.
916      *
917      */
918     void HandleServiceUpdateResult(ServiceUpdateId aId, Error aError);
919 
920 private:
921     static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
922 
923     static constexpr uint32_t kDefaultMinLease             = 30;          // 30 seconds.
924     static constexpr uint32_t kDefaultMaxLease             = 27u * 3600;  // 27 hours (in seconds).
925     static constexpr uint32_t kDefaultMinKeyLease          = 30;          // 30 seconds.
926     static constexpr uint32_t kDefaultMaxKeyLease          = 189u * 3600; // 189 hours (in seconds).
927     static constexpr uint32_t kDefaultMinTtl               = kDefaultMinLease;
928     static constexpr uint32_t kDefaultMaxTtl               = kDefaultMaxLease;
929     static constexpr uint32_t kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT;
930 
931     static constexpr AddressMode kDefaultAddressMode =
932         static_cast<AddressMode>(OPENTHREAD_CONFIG_SRP_SERVER_DEFAULT_ADDRESS_MODE);
933 
934     static constexpr uint16_t kAnycastAddressModePort = 53;
935 
936     // Metadata for a received SRP Update message.
937     struct MessageMetadata
938     {
939         // Indicates whether the `Message` is received directly from a
940         // client or from an SRPL partner.
IsDirectRxFromClientot::Srp::Server::MessageMetadata941         bool IsDirectRxFromClient(void) const { return (mMessageInfo != nullptr); }
942 
943         Dns::UpdateHeader       mDnsHeader;
944         Dns::Zone               mDnsZone;
945         uint16_t                mOffset;
946         TimeMilli               mRxTime;
947         TtlConfig               mTtlConfig;
948         LeaseConfig             mLeaseConfig;
949         const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL.
950     };
951 
952     // This class includes metadata for processing a SRP update (register, deregister)
953     // and sending DNS response to the client.
954     class UpdateMetadata : public InstanceLocator,
955                            public LinkedListEntry<UpdateMetadata>,
956                            public Heap::Allocatable<UpdateMetadata>
957     {
958         friend class LinkedListEntry<UpdateMetadata>;
959         friend class Heap::Allocatable<UpdateMetadata>;
960 
961     public:
GetExpireTime(void) const962         TimeMilli                GetExpireTime(void) const { return mExpireTime; }
GetDnsHeader(void) const963         const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
GetId(void) const964         ServiceUpdateId          GetId(void) const { return mId; }
GetTtlConfig(void) const965         const TtlConfig         &GetTtlConfig(void) const { return mTtlConfig; }
GetLeaseConfig(void) const966         const LeaseConfig       &GetLeaseConfig(void) const { return mLeaseConfig; }
GetHost(void)967         Host                    &GetHost(void) { return mHost; }
GetMessageInfo(void) const968         const Ip6::MessageInfo  &GetMessageInfo(void) const { return mMessageInfo; }
IsDirectRxFromClient(void) const969         bool                     IsDirectRxFromClient(void) const { return mIsDirectRxFromClient; }
Matches(ServiceUpdateId aId) const970         bool                     Matches(ServiceUpdateId aId) const { return mId == aId; }
971 
972     private:
973         UpdateMetadata(Instance &aInstance, Host &aHost, const MessageMetadata &aMessageMetadata);
974 
975         UpdateMetadata   *mNext;
976         TimeMilli         mExpireTime;
977         Dns::UpdateHeader mDnsHeader;
978         ServiceUpdateId   mId;          // The ID of this service update transaction.
979         TtlConfig         mTtlConfig;   // TTL config to use when processing the message.
980         LeaseConfig       mLeaseConfig; // Lease config to use when processing the message.
981         Host             &mHost;        // The `UpdateMetadata` has no ownership of this host.
982         Ip6::MessageInfo  mMessageInfo; // Valid when `mIsDirectRxFromClient` is true.
983         bool              mIsDirectRxFromClient;
984     };
985 
986     void              Enable(void);
987     void              Disable(void);
988     void              Start(void);
989     void              Stop(void);
990     void              SelectPort(void);
991     void              PrepareSocket(void);
992     Ip6::Udp::Socket &GetSocket(void);
993 
994 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
995     void  HandleDnssdServerStateChange(void);
996     Error HandleDnssdServerUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
997 #endif
998 
999     void HandleNetDataPublisherEvent(NetworkData::Publisher::Event aEvent);
1000 
AllocateId(void)1001     ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; }
1002 
1003     void  InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata);
1004     void  CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata);
1005     void  CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata);
1006     void  CommitSrpUpdate(Error                    aError,
1007                           Host                    &aHost,
1008                           const Dns::UpdateHeader &aDnsHeader,
1009                           const Ip6::MessageInfo  *aMessageInfo,
1010                           const TtlConfig         &aTtlConfig,
1011                           const LeaseConfig       &aLeaseConfig);
1012     Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1013     Error ProcessMessage(Message                &aMessage,
1014                          TimeMilli               aRxTime,
1015                          const TtlConfig        &aTtlConfig,
1016                          const LeaseConfig      &aLeaseConfig,
1017                          const Ip6::MessageInfo *aMessageInfo);
1018     void  ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata);
1019     Error ProcessUpdateSection(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
1020     Error ProcessAdditionalSection(Host *aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
1021     Error VerifySignature(const Dns::Ecdsa256KeyRecord &aKeyRecord,
1022                           const Message                &aMessage,
1023                           Dns::UpdateHeader             aDnsHeader,
1024                           uint16_t                      aSigOffset,
1025                           uint16_t                      aSigRdataOffset,
1026                           uint16_t                      aSigRdataLength,
1027                           const char                   *aSignerName) const;
1028     Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata);
1029     Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
1030     Error ProcessHostDescriptionInstruction(Host                  &aHost,
1031                                             const Message         &aMessage,
1032                                             const MessageMetadata &aMetadata) const;
1033     Error ProcessServiceDiscoveryInstructions(Host                  &aHost,
1034                                               const Message         &aMessage,
1035                                               const MessageMetadata &aMetadata) const;
1036     Error ProcessServiceDescriptionInstructions(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
1037 
1038     static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord);
1039 
1040     void        HandleUpdate(Host &aHost, const MessageMetadata &aMetadata);
1041     void        AddHost(Host &aHost);
1042     void        RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
1043     bool        HasNameConflictsWith(Host &aHost) const;
1044     void        SendResponse(const Dns::UpdateHeader    &aHeader,
1045                              Dns::UpdateHeader::Response aResponseCode,
1046                              const Ip6::MessageInfo     &aMessageInfo);
1047     void        SendResponse(const Dns::UpdateHeader &aHeader,
1048                              uint32_t                 aLease,
1049                              uint32_t                 aKeyLease,
1050                              bool                     mUseShortLeaseOption,
1051                              const Ip6::MessageInfo  &aMessageInfo);
1052     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
1053     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1054     void        HandleLeaseTimer(void);
1055     static void HandleOutstandingUpdatesTimer(Timer &aTimer);
1056     void        HandleOutstandingUpdatesTimer(void);
1057 
1058     void                  HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError);
1059     const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const;
1060     static const char    *AddressModeToString(AddressMode aMode);
1061 
1062     void UpdateResponseCounters(Dns::Header::Response aResponseCode);
1063 
1064     using LeaseTimer  = TimerMilliIn<Server, &Server::HandleLeaseTimer>;
1065     using UpdateTimer = TimerMilliIn<Server, &Server::HandleOutstandingUpdatesTimer>;
1066 
1067     Ip6::Udp::Socket mSocket;
1068 
1069     Callback<otSrpServerServiceUpdateHandler> mServiceUpdateHandler;
1070 
1071     Heap::String mDomain;
1072 
1073     TtlConfig   mTtlConfig;
1074     LeaseConfig mLeaseConfig;
1075 
1076     LinkedList<Host> mHosts;
1077     LeaseTimer       mLeaseTimer;
1078 
1079     UpdateTimer                mOutstandingUpdatesTimer;
1080     LinkedList<UpdateMetadata> mOutstandingUpdates;
1081 
1082     ServiceUpdateId mServiceUpdateId;
1083     uint16_t        mPort;
1084     State           mState;
1085     AddressMode     mAddressMode;
1086     uint8_t         mAnycastSequenceNumber;
1087     bool            mHasRegisteredAnyService : 1;
1088 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
1089     bool mAutoEnable : 1;
1090 #endif
1091 
1092     otSrpServerResponseCounters mResponseCounters;
1093 };
1094 
1095 } // namespace Srp
1096 
1097 DefineCoreType(otSrpServerTtlConfig, Srp::Server::TtlConfig);
1098 DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig);
1099 DefineCoreType(otSrpServerHost, Srp::Server::Host);
1100 DefineCoreType(otSrpServerService, Srp::Server::Service);
1101 DefineMapEnum(otSrpServerState, Srp::Server::State);
1102 DefineMapEnum(otSrpServerAddressMode, Srp::Server::AddressMode);
1103 
1104 } // namespace ot
1105 
1106 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
1107 #endif // NET_SRP_SERVER_HPP_
1108