• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
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/clearable.hpp"
59 #include "common/heap.hpp"
60 #include "common/heap_allocatable.hpp"
61 #include "common/heap_array.hpp"
62 #include "common/heap_data.hpp"
63 #include "common/heap_string.hpp"
64 #include "common/linked_list.hpp"
65 #include "common/locator.hpp"
66 #include "common/non_copyable.hpp"
67 #include "common/notifier.hpp"
68 #include "common/numeric_limits.hpp"
69 #include "common/retain_ptr.hpp"
70 #include "common/timer.hpp"
71 #include "crypto/ecdsa.hpp"
72 #include "net/dns_types.hpp"
73 #include "net/ip6.hpp"
74 #include "net/ip6_address.hpp"
75 #include "net/udp6.hpp"
76 #include "thread/network_data_publisher.hpp"
77 
78 struct otSrpServerHost
79 {
80 };
81 
82 struct otSrpServerService
83 {
84 };
85 
86 namespace ot {
87 
88 namespace Dns {
89 namespace ServiceDiscovery {
90 class Server;
91 }
92 } // namespace Dns
93 
94 namespace Srp {
95 
96 /**
97  * This class implements the SRP server.
98  *
99  */
100 class Server : public InstanceLocator, private NonCopyable
101 {
102     friend class NetworkData::Publisher;
103     friend class UpdateMetadata;
104     friend class Service;
105     friend class Host;
106     friend class Dns::ServiceDiscovery::Server;
107 
108     enum RetainName : bool
109     {
110         kDeleteName = false,
111         kRetainName = true,
112     };
113 
114     enum NotifyMode : bool
115     {
116         kDoNotNotifyServiceHandler = false,
117         kNotifyServiceHandler      = true,
118     };
119 
120 public:
121     static constexpr uint16_t kUdpPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN; ///< The reserved min port.
122     static constexpr uint16_t kUdpPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX; ///< The reserved max port.
123 
124     static_assert(kUdpPortMin <= kUdpPortMax, "invalid port range");
125 
126     /**
127      * The ID of SRP service update transaction.
128      *
129      */
130     typedef otSrpServerServiceUpdateId ServiceUpdateId;
131 
132     /**
133      * The SRP server lease information of a host/service.
134      *
135      */
136     typedef otSrpServerLeaseInfo LeaseInfo;
137 
138     /**
139      * This enumeration represents the address mode used by the SRP server.
140      *
141      * Address mode specifies how the address and port number are determined by the SRP server and how this info ins
142      * published in the Thread Network Data.
143      *
144      */
145     enum AddressMode : uint8_t
146     {
147         kAddressModeUnicast = OT_SRP_SERVER_ADDRESS_MODE_UNICAST, ///< Unicast address mode.
148         kAddressModeAnycast = OT_SRP_SERVER_ADDRESS_MODE_ANYCAST, ///< Anycast address mode.
149     };
150 
151     class Host;
152 
153     enum State : uint8_t
154     {
155         kStateDisabled = OT_SRP_SERVER_STATE_DISABLED,
156         kStateRunning  = OT_SRP_SERVER_STATE_RUNNING,
157         kStateStopped  = OT_SRP_SERVER_STATE_STOPPED,
158     };
159 
160     /**
161      * This class implements a server-side SRP service.
162      *
163      */
164     class Service : public otSrpServerService,
165                     public LinkedListEntry<Service>,
166                     private Heap::Allocatable<Service>,
167                     private NonCopyable
168     {
169         friend class Server;
170         friend class LinkedList<Service>;
171         friend class LinkedListEntry<Service>;
172         friend class Heap::Allocatable<Service>;
173 
174     public:
175         /**
176          * This type represents the flags which indicates which services to include or exclude when searching in (or
177          * iterating over) the list of SRP services.
178          *
179          */
180         typedef otSrpServerServiceFlags Flags;
181 
182         /**
183          * This `Flags` constant indicates to include base services (not a sub-type).
184          *
185          */
186         static constexpr Flags kFlagBaseType = OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE;
187 
188         /**
189          * This `Flags` constant indicates to include sub-type services.
190          *
191          */
192         static constexpr Flags kFlagSubType = OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE;
193 
194         /**
195          * This `Flags` constant indicates to include active (not deleted) services.
196          *
197          */
198         static constexpr Flags kFlagActive = OT_SRP_SERVER_SERVICE_FLAG_ACTIVE;
199 
200         /**
201          * This `Flags` constant indicates to include deleted services.
202          *
203          */
204         static constexpr Flags kFlagDeleted = OT_SRP_SERVER_SERVICE_FLAG_DELETED;
205 
206         /**
207          * This method tells if the SRP service has been deleted.
208          *
209          * A SRP service can be deleted but retains its name for future uses.
210          * In this case, the service instance is not removed from the SRP server/registry.
211          * It is guaranteed that all services are deleted if the host is deleted.
212          *
213          * @returns  TRUE if the service has been deleted, FALSE if not.
214          *
215          */
IsDeleted(void) const216         bool IsDeleted(void) const { return mIsDeleted; }
217 
218         /**
219          * This method indicates whether the SRP service is a sub-type.
220          *
221          * @retval TRUE    If the service is a sub-type.
222          * @retval FALSE   If the service is not a sub-type.
223          *
224          */
IsSubType(void) const225         bool IsSubType(void) const { return mIsSubType; }
226 
227         /**
228          * This method gets the full service instance name of the service.
229          *
230          * @returns  A pointer service instance name (as a null-terminated C string).
231          *
232          */
GetInstanceName(void) const233         const char *GetInstanceName(void) const { return mDescription->mInstanceName.AsCString(); }
234 
235         /**
236          * This method gets the full service name of the service.
237          *
238          * @returns  A pointer service name (as a null-terminated C string).
239          *
240          */
GetServiceName(void) const241         const char *GetServiceName(void) const { return mServiceName.AsCString(); }
242 
243         /**
244          * This method gets the sub-type label from service name.
245          *
246          * The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This
247          * method copies the `<sub-label>` into the @p aLabel buffer.
248          *
249          * The @p aLabel is ensured to always be null-terminated after returning even in case of failure.
250          *
251          * @param[out] aLabel        A pointer to a buffer to copy the sub-type label name.
252          * @param[in]  aMaxSize      Maximum size of @p aLabel buffer.
253          *
254          * @retval kErrorNone         @p aLabel was updated successfully.
255          * @retval kErrorNoBufs       The sub-type label could not fit in @p aLabel buffer (number of chars from label
256          *                            that could fit are copied in @p aLabel ensuring it is null-terminated).
257          * @retval kErrorInvalidArgs  SRP service is not a sub-type.
258          *
259          */
260         Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
261 
262         /**
263          * This method returns the TTL of the service instance.
264          *
265          * @returns The TTL of the service instance.
266          *
267          */
GetTtl(void) const268         uint32_t GetTtl(void) const { return mDescription->mTtl; }
269 
270         /**
271          * This method returns the port of the service instance.
272          *
273          * @returns  The port of the service.
274          *
275          */
GetPort(void) const276         uint16_t GetPort(void) const { return mDescription->mPort; }
277 
278         /**
279          * This method returns the weight of the service instance.
280          *
281          * @returns  The weight of the service.
282          *
283          */
GetWeight(void) const284         uint16_t GetWeight(void) const { return mDescription->mWeight; }
285 
286         /**
287          * This method returns the priority of the service instance.
288          *
289          * @returns  The priority of the service.
290          *
291          */
GetPriority(void) const292         uint16_t GetPriority(void) const { return mDescription->mPriority; }
293 
294         /**
295          * This method returns the TXT record data of the service instance.
296          *
297          * @returns A pointer to the buffer containing the TXT record data.
298          *
299          */
GetTxtData(void) const300         const uint8_t *GetTxtData(void) const { return mDescription->mTxtData.GetBytes(); }
301 
302         /**
303          * This method returns the TXT record data length of the service instance.
304          *
305          * @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`).
306          *
307          */
GetTxtDataLength(void) const308         uint16_t GetTxtDataLength(void) const { return mDescription->mTxtData.GetLength(); }
309 
310         /**
311          * This method returns the host which the service instance reside on.
312          *
313          * @returns  A reference to the host instance.
314          *
315          */
GetHost(void) const316         const Host &GetHost(void) const { return *mDescription->mHost; }
317 
318         /**
319          * This method returns the LEASE time of the service.
320          *
321          * @returns  The LEASE time in seconds.
322          *
323          */
GetLease(void) const324         uint32_t GetLease(void) const { return mDescription->mLease; }
325 
326         /**
327          * This method returns the KEY-LEASE time of the key of the service.
328          *
329          * @returns  The KEY-LEASE time in seconds.
330          *
331          */
GetKeyLease(void) const332         uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; }
333 
334         /**
335          * This method returns the expire time (in milliseconds) of the service.
336          *
337          * @returns  The service expire time in milliseconds.
338          *
339          */
340         TimeMilli GetExpireTime(void) const;
341 
342         /**
343          * This method returns the key expire time (in milliseconds) of the service.
344          *
345          * @returns  The service key expire time in milliseconds.
346          *
347          */
348         TimeMilli GetKeyExpireTime(void) const;
349 
350         /**
351          * This method gets the LEASE and KEY-LEASE information of a given service.
352          *
353          * @param[out]  aLeaseInfo  A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
354          *                          remaining LEASE time and the remaining KEY-LEASE time.
355          *
356          */
357         void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
358 
359         /**
360          * This method indicates whether this service matches a given service instance name.
361          *
362          * @param[in]  aInstanceName  The service instance name.
363          *
364          * @retval  TRUE   If the service matches the service instance name.
365          * @retval  FALSE  If the service does not match the service instance name.
366          *
367          */
368         bool MatchesInstanceName(const char *aInstanceName) const;
369 
370         /**
371          * This method tells whether this service matches a given service name.
372          *
373          * @param[in] aServiceName  The full service name to match.
374          *
375          * @retval  TRUE   If the service matches the full service name.
376          * @retval  FALSE  If the service does not match the full service name.
377          *
378          */
379         bool MatchesServiceName(const char *aServiceName) const;
380 
381     private:
382         struct Description : public LinkedListEntry<Description>,
383                              public Heap::Allocatable<Description>,
384                              public RetainCountable,
385                              private NonCopyable
386         {
387             Error       Init(const char *aInstanceName, Host &aHost);
GetInstanceNameot::Srp::Server::Service::Description388             const char *GetInstanceName(void) const { return mInstanceName.AsCString(); }
389             bool        Matches(const char *aInstanceName) const;
390             void        ClearResources(void);
391             void        TakeResourcesFrom(Description &aDescription);
392             Error       SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
393 
394             Description *mNext;
395             Heap::String mInstanceName;
396             Host *       mHost;
397             Heap::Data   mTxtData;
398             uint16_t     mPriority;
399             uint16_t     mWeight;
400             uint16_t     mPort;
401             uint32_t     mTtl;      // The TTL in seconds.
402             uint32_t     mLease;    // The LEASE time in seconds.
403             uint32_t     mKeyLease; // The KEY-LEASE time in seconds.
404             TimeMilli    mUpdateTime;
405         };
406 
407         enum Action : uint8_t
408         {
409             kAddNew,
410             kUpdateExisting,
411             kRemoveButRetainName,
412             kFullyRemove,
413             kLeaseExpired,
414             kKeyLeaseExpired,
415         };
416 
417         Error Init(const char *aServiceName, Description &aDescription, bool aIsSubType, TimeMilli aUpdateTime);
418         bool  MatchesFlags(Flags aFlags) const;
GetUpdateTime(void) const419         const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; }
420         void             Log(Action aAction) const;
421 
422         Heap::String           mServiceName;
423         RetainPtr<Description> mDescription;
424         Service *              mNext;
425         TimeMilli              mUpdateTime;
426         bool                   mIsDeleted : 1;
427         bool                   mIsSubType : 1;
428         bool                   mIsCommitted : 1;
429     };
430 
431     /**
432      * This class implements the Host which registers services on the SRP server.
433      *
434      */
435     class Host : public otSrpServerHost,
436                  public InstanceLocator,
437                  public LinkedListEntry<Host>,
438                  private Heap::Allocatable<Host>,
439                  private NonCopyable
440     {
441         friend class Server;
442         friend class LinkedListEntry<Host>;
443         friend class Heap::Allocatable<Host>;
444 
445     public:
446         /**
447          * This method tells whether the Host object has been deleted.
448          *
449          * The Host object retains event if the host has been deleted by the SRP client,
450          * because the host name may retain.
451          *
452          * @returns  TRUE if the host is deleted, FALSE if the host is not deleted.
453          *
454          */
IsDeleted(void) const455         bool IsDeleted(void) const { return (mLease == 0); }
456 
457         /**
458          * This method returns the full name of the host.
459          *
460          * @returns  A pointer to the null-terminated full host name.
461          *
462          */
GetFullName(void) const463         const char *GetFullName(void) const { return mFullName.AsCString(); }
464 
465         /**
466          * This method returns addresses of the host.
467          *
468          * @param[out]  aAddressesNum  The number of the addresses.
469          *
470          * @returns  A pointer to the addresses array or `nullptr` if no addresses.
471          *
472          */
GetAddresses(uint8_t & aAddressesNum) const473         const Ip6::Address *GetAddresses(uint8_t &aAddressesNum) const
474         {
475             aAddressesNum = static_cast<uint8_t>(OT_MIN(mAddresses.GetLength(), NumericLimits<uint8_t>::kMax));
476             return mAddresses.AsCArray();
477         }
478 
479         /**
480          * This method returns the TTL of the host.
481          *
482          * @returns The TTL of the host.
483          *
484          */
GetTtl(void) const485         uint32_t GetTtl(void) const { return mTtl; }
486 
487         /**
488          * This method returns the LEASE time of the host.
489          *
490          * @returns  The LEASE time in seconds.
491          *
492          */
GetLease(void) const493         uint32_t GetLease(void) const { return mLease; }
494 
495         /**
496          * This method returns the KEY-LEASE time of the key of the host.
497          *
498          * @returns  The KEY-LEASE time in seconds.
499          *
500          */
GetKeyLease(void) const501         uint32_t GetKeyLease(void) const { return mKeyLease; }
502 
503         /**
504          * This method gets the LEASE and KEY-LEASE information of a given host.
505          *
506          * @param[out]  aLeaseInfo  A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
507          *                          remaining LEASE time and the remaining KEY-LEASE time.
508          *
509          */
510         void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
511 
512         /**
513          * This method returns the KEY resource record of the host.
514          *
515          * @returns  A pointer to the ECDSA P 256 public key resource record
516          *           if there is valid one. `nullptr` if no valid key exists.
517          *
518          */
GetKeyRecord(void) const519         const Dns::Ecdsa256KeyRecord *GetKeyRecord(void) const { return mKeyRecord.IsValid() ? &mKeyRecord : nullptr; }
520 
521         /**
522          * This method returns the expire time (in milliseconds) of the host.
523          *
524          * @returns  The expire time in milliseconds.
525          *
526          */
527         TimeMilli GetExpireTime(void) const;
528 
529         /**
530          * This method returns the expire time (in milliseconds) of the key of the host.
531          *
532          * @returns  The expire time of the key in milliseconds.
533          *
534          */
535         TimeMilli GetKeyExpireTime(void) const;
536 
537         /**
538          * This method returns the `Service` linked list associated with the host.
539          *
540          * @returns The `Service` linked list.
541          *
542          */
GetServices(void) const543         const LinkedList<Service> &GetServices(void) const { return mServices; }
544 
545         /**
546          * This method finds the next matching service on the host.
547          *
548          * @param[in] aPrevService   A pointer to the previous service or `nullptr` to start from beginning of the list.
549          * @param[in] aFlags         Flags indicating which services to include (base/sub-type, active/deleted).
550          * @param[in] aServiceName   The service name to match. Set to `nullptr` to accept any name.
551          * @param[in] aInstanceName  The service instance name to match. Set to `nullptr` to accept any name.
552          *
553          * @returns  A pointer to the next matching service or `nullptr` if no matching service could be found.
554          *
555          */
556         const Service *FindNextService(const Service *aPrevService,
557                                        Service::Flags aFlags        = kFlagsAnyService,
558                                        const char *   aServiceName  = nullptr,
559                                        const char *   aInstanceName = nullptr) const;
560 
561         /**
562          * This method tells whether the host matches a given full name.
563          *
564          * @param[in]  aFullName  The full name.
565          *
566          * @returns  A boolean that indicates whether the host matches the given name.
567          *
568          */
569         bool Matches(const char *aFullName) const;
570 
571     private:
572         Host(Instance &aInstance, TimeMilli aUpdateTime);
573         ~Host(void);
574 
575         Error SetFullName(const char *aFullName);
576         void  SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
SetTtl(uint32_t aTtl)577         void  SetTtl(uint32_t aTtl) { mTtl = aTtl; }
SetLease(uint32_t aLease)578         void  SetLease(uint32_t aLease) { mLease = aLease; }
SetKeyLease(uint32_t aKeyLease)579         void  SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
580         Error ProcessTtl(uint32_t aTtl);
581 
GetServices(void)582         LinkedList<Service> &GetServices(void) { return mServices; }
583         Service *            AddNewService(const char *aServiceName,
584                                            const char *aInstanceName,
585                                            bool        aIsSubType,
586                                            TimeMilli   aUpdateTime);
587         void                 RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
588         Error                AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime);
589         void                 FreeAllServices(void);
590         void                 ClearResources(void);
591         Error                MergeServicesAndResourcesFrom(Host &aHost);
592         Error                AddIp6Address(const Ip6::Address &aIp6Address);
593         bool                 HasServiceInstance(const char *aInstanceName) const;
594         RetainPtr<Service::Description>       FindServiceDescription(const char *aInstanceName);
595         const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
596         Service *                             FindService(const char *aServiceName, const char *aInstanceName);
597         const Service *                       FindService(const char *aServiceName, const char *aInstanceName) const;
598         Service *                             FindBaseService(const char *aInstanceName);
599         const Service *                       FindBaseService(const char *aInstanceName) const;
600 
601         Host *                    mNext;
602         Heap::String              mFullName;
603         Heap::Array<Ip6::Address> mAddresses;
604 
605         // TODO(wgtdkp): there is no necessary to save the entire resource
606         // record, saving only the ECDSA-256 public key should be enough.
607         Dns::Ecdsa256KeyRecord mKeyRecord;
608         uint32_t               mTtl;      // The TTL in seconds.
609         uint32_t               mLease;    // The LEASE time in seconds.
610         uint32_t               mKeyLease; // The KEY-LEASE time in seconds.
611         TimeMilli              mUpdateTime;
612         LinkedList<Service>    mServices;
613     };
614 
615     /**
616      * This class handles TTL configuration.
617      *
618      */
619     class TtlConfig : public otSrpServerTtlConfig
620     {
621         friend class Server;
622 
623     public:
624         /**
625          * This constructor initializes to default TTL configuration.
626          *
627          */
628         TtlConfig(void);
629 
630     private:
IsValid(void) const631         bool     IsValid(void) const { return mMinTtl <= mMaxTtl; }
632         uint32_t GrantTtl(uint32_t aLease, uint32_t aTtl) const;
633     };
634 
635     /**
636      * This class handles LEASE and KEY-LEASE configurations.
637      *
638      */
639     class LeaseConfig : public otSrpServerLeaseConfig
640     {
641         friend class Server;
642 
643     public:
644         /**
645          * This constructor initialize to default LEASE and KEY-LEASE configurations.
646          *
647          */
648         LeaseConfig(void);
649 
650     private:
651         bool     IsValid(void) const;
652         uint32_t GrantLease(uint32_t aLease) const;
653         uint32_t GrantKeyLease(uint32_t aKeyLease) const;
654     };
655 
656     /**
657      * This constant defines a `Service::Flags` combination accepting any service (base/sub-type, active/deleted).
658      *
659      */
660     static constexpr Service::Flags kFlagsAnyService = OT_SRP_SERVER_FLAGS_ANY_SERVICE;
661 
662     /**
663      * This constant defines a `Service::Flags` combination accepting base services only.
664      *
665      */
666     static constexpr Service::Flags kFlagsBaseTypeServiceOnly = OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY;
667 
668     /**
669      * This constant defines a `Service::Flags` combination accepting sub-type services only.
670      *
671      */
672     static constexpr Service::Flags kFlagsSubTypeServiceOnly = OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY;
673 
674     /**
675      * This constant defines a `Service::Flags` combination accepting any active services (not deleted).
676      *
677      */
678     static constexpr Service::Flags kFlagsAnyTypeActiveService = OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE;
679 
680     /**
681      * This constant defines a `Service::Flags` combination accepting any deleted services.
682      *
683      */
684     static constexpr Service::Flags kFlagsAnyTypeDeletedService = OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE;
685 
686     /**
687      * This constructor initializes the SRP server object.
688      *
689      * @param[in]  aInstance  A reference to the OpenThread instance.
690      *
691      */
692     explicit Server(Instance &aInstance);
693 
694     /**
695      * This method sets the SRP service events handler.
696      *
697      * @param[in]  aServiceHandler         A service events handler.
698      * @param[in]  aServiceHandlerContext  A pointer to arbitrary context information.
699      *
700      * @note  The handler SHOULD call HandleServiceUpdateResult to report the result of its processing.
701      *        Otherwise, a SRP update will be considered failed.
702      *
703      * @sa  HandleServiceUpdateResult
704      *
705      */
706     void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext);
707 
708     /**
709      * This method returns the domain authorized to the SRP server.
710      *
711      * If the domain if not set by SetDomain, "default.service.arpa." will be returned.
712      * A trailing dot is always appended even if the domain is set without it.
713      *
714      * @returns A pointer to the dot-joined domain string.
715      *
716      */
GetDomain(void) const717     const char *GetDomain(void) const { return mDomain.AsCString(); }
718 
719     /**
720      * This method sets the domain on the SRP server.
721      *
722      * A trailing dot will be appended to @p aDomain if it is not already there.
723      * This method should only be called before the SRP server is enabled.
724      *
725      * @param[in]  aDomain  The domain to be set. MUST NOT be `nullptr`.
726      *
727      * @retval  kErrorNone          Successfully set the domain to @p aDomain.
728      * @retval  kErrorInvalidState  The SRP server is already enabled and the Domain cannot be changed.
729      * @retval  kErrorInvalidArgs   The argument @p aDomain is not a valid DNS domain name.
730      * @retval  kErrorNoBufs        There is no memory to store content of @p aDomain.
731      *
732      */
733     Error SetDomain(const char *aDomain);
734 
735     /**
736      * This method returns the address mode being used by the SRP server.
737      *
738      * @returns The SRP server's address mode.
739      *
740      */
GetAddressMode(void) const741     AddressMode GetAddressMode(void) const { return mAddressMode; }
742 
743     /**
744      * This method sets the address mode to be used by the SRP server.
745      *
746      * @param[in] aMode      The address mode to use.
747      *
748      * @retval kErrorNone           Successfully set the address mode.
749      * @retval kErrorInvalidState   The SRP server is enabled and the address mode cannot be changed.
750      *
751      */
752     Error SetAddressMode(AddressMode aMode);
753 
754     /**
755      * This method gets the sequence number used with anycast address mode.
756      *
757      * The sequence number is included in "DNS/SRP Service Anycast Address" entry published in the Network Data.
758      *
759      * @returns The anycast sequence number.
760      *
761      */
GetAnycastModeSequenceNumber(void) const762     uint8_t GetAnycastModeSequenceNumber(void) const { return mAnycastSequenceNumber; }
763 
764     /**
765      * This method sets the sequence number used with anycast address mode.
766      *
767      * @param[in] aSequenceNumber  The sequence number to use.
768      *
769      * @retval kErrorNone           Successfully set the address mode.
770      * @retval kErrorInvalidState   The SRP server is enabled and the sequence number cannot be changed.
771      *
772      */
773     Error SetAnycastModeSequenceNumber(uint8_t aSequenceNumber);
774 
775     /**
776      * This method tells whether the SRP server is currently running.
777      *
778      * @returns  A boolean that indicates whether the server is running.
779      *
780      */
IsRunning(void) const781     bool IsRunning(void) const { return (mState == kStateRunning); }
782 
783     /**
784      * This method tells the state of the SRP server.
785      *
786      * @returns  An enum that represents the state of the server.
787      *
788      */
GetState(void) const789     State GetState(void) const { return mState; }
790 
791     /**
792      * This method tells the port the SRP server is listening to.
793      *
794      * @returns  An integer that represents the port of the server. It returns 0 if the SRP server is not running.
795      *
796      */
GetPort(void) const797     uint16_t GetPort(void) const { return IsRunning() ? mPort : 0; }
798 
799     /**
800      * This method enables/disables the SRP server.
801      *
802      * @param[in]  aEnabled  A boolean to enable/disable the SRP server.
803      *
804      */
805     void SetEnabled(bool aEnabled);
806 
807     /**
808      * This method returns the TTL configuration.
809      *
810      * @param[out]  aTtlConfig  A reference to the `TtlConfig` instance.
811      *
812      */
GetTtlConfig(TtlConfig & aTtlConfig) const813     void GetTtlConfig(TtlConfig &aTtlConfig) const { aTtlConfig = mTtlConfig; }
814 
815     /**
816      * This method sets the TTL configuration.
817      *
818      * @param[in]  aTtlConfig  A reference to the `TtlConfig` instance.
819      *
820      * @retval  kErrorNone         Successfully set the TTL configuration
821      * @retval  kErrorInvalidArgs  The TTL range is not valid.
822      *
823      */
824     Error SetTtlConfig(const TtlConfig &aTtlConfig);
825 
826     /**
827      * This method returns the LEASE and KEY-LEASE configurations.
828      *
829      * @param[out]  aLeaseConfig  A reference to the `LeaseConfig` instance.
830      *
831      */
GetLeaseConfig(LeaseConfig & aLeaseConfig) const832     void GetLeaseConfig(LeaseConfig &aLeaseConfig) const { aLeaseConfig = mLeaseConfig; }
833 
834     /**
835      * This method sets the LEASE and KEY-LEASE configurations.
836      *
837      * When a LEASE time is requested from a client, the granted value will be
838      * limited in range [aMinLease, aMaxLease]; and a KEY-LEASE will be granted
839      * in range [aMinKeyLease, aMaxKeyLease].
840      *
841      * @param[in]  aLeaseConfig  A reference to the `LeaseConfig` instance.
842      *
843      * @retval  kErrorNone         Successfully set the LEASE and KEY-LEASE ranges.
844      * @retval  kErrorInvalidArgs  The LEASE or KEY-LEASE range is not valid.
845      *
846      */
847     Error SetLeaseConfig(const LeaseConfig &aLeaseConfig);
848 
849     /**
850      * This method returns the next registered SRP host.
851      *
852      * @param[in]  aHost  The current SRP host; use `nullptr` to get the first SRP host.
853      *
854      * @returns  A pointer to the next SRP host or `nullptr` if no more SRP hosts can be found.
855      *
856      */
857     const Host *GetNextHost(const Host *aHost);
858 
859     /**
860      * This method returns the response counters of the SRP server.
861      *
862      * @returns  A pointer to the response counters of the SRP server.
863      *
864      */
GetResponseCounters(void) const865     const otSrpServerResponseCounters *GetResponseCounters(void) const { return &mResponseCounters; }
866 
867     /**
868      * This method receives the service update result from service handler set by
869      * SetServiceHandler.
870      *
871      * @param[in]  aId     The ID of the service update transaction.
872      * @param[in]  aError  The service update result.
873      *
874      */
875     void HandleServiceUpdateResult(ServiceUpdateId aId, Error aError);
876 
877 private:
878     static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
879 
880     static constexpr uint32_t kDefaultMinTtl               = 60u;             // 1 min (in seconds).
881     static constexpr uint32_t kDefaultMaxTtl               = 3600u * 2;       // 2 hours (in seconds).
882     static constexpr uint32_t kDefaultMinLease             = 60u * 30;        // 30 min (in seconds).
883     static constexpr uint32_t kDefaultMaxLease             = 3600u * 2;       // 2 hours (in seconds).
884     static constexpr uint32_t kDefaultMinKeyLease          = 3600u * 24;      // 1 day (in seconds).
885     static constexpr uint32_t kDefaultMaxKeyLease          = 3600u * 24 * 14; // 14 days (in seconds).
886     static constexpr uint32_t kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT;
887 
888     static constexpr AddressMode kDefaultAddressMode =
889         static_cast<AddressMode>(OPENTHREAD_CONFIG_SRP_SERVER_DEFAULT_ADDDRESS_MODE);
890 
891     static constexpr uint16_t kAnycastAddressModePort = 53;
892 
893     // Metdata for a received SRP Update message.
894     struct MessageMetadata
895     {
896         // Indicates whether the `Message` is received directly from a
897         // client or from an SRPL partner.
IsDirectRxFromClientot::Srp::Server::MessageMetadata898         bool IsDirectRxFromClient(void) const { return (mMessageInfo != nullptr); }
899 
900         Dns::UpdateHeader       mDnsHeader;
901         Dns::Zone               mDnsZone;
902         uint16_t                mOffset;
903         TimeMilli               mRxTime;
904         TtlConfig               mTtlConfig;
905         LeaseConfig             mLeaseConfig;
906         const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL.
907     };
908 
909     // This class includes metadata for processing a SRP update (register, deregister)
910     // and sending DNS response to the client.
911     class UpdateMetadata : public InstanceLocator,
912                            public LinkedListEntry<UpdateMetadata>,
913                            public Heap::Allocatable<UpdateMetadata>
914     {
915         friend class LinkedListEntry<UpdateMetadata>;
916         friend class Heap::Allocatable<UpdateMetadata>;
917 
918     public:
GetExpireTime(void) const919         TimeMilli                GetExpireTime(void) const { return mExpireTime; }
GetDnsHeader(void) const920         const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
GetId(void) const921         ServiceUpdateId          GetId(void) const { return mId; }
GetTtlConfig(void) const922         const TtlConfig &        GetTtlConfig(void) const { return mTtlConfig; }
GetLeaseConfig(void) const923         const LeaseConfig &      GetLeaseConfig(void) const { return mLeaseConfig; }
GetHost(void)924         Host &                   GetHost(void) { return mHost; }
GetMessageInfo(void) const925         const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; }
IsDirectRxFromClient(void) const926         bool                     IsDirectRxFromClient(void) const { return mIsDirectRxFromClient; }
Matches(ServiceUpdateId aId) const927         bool                     Matches(ServiceUpdateId aId) const { return mId == aId; }
928 
929     private:
930         UpdateMetadata(Instance &aInstance, Host &aHost, const MessageMetadata &aMessageMetadata);
931 
932         UpdateMetadata *  mNext;
933         TimeMilli         mExpireTime;
934         Dns::UpdateHeader mDnsHeader;
935         ServiceUpdateId   mId;          // The ID of this service update transaction.
936         TtlConfig         mTtlConfig;   // TTL config to use when processing the message.
937         LeaseConfig       mLeaseConfig; // Lease config to use when processing the message.
938         Host &            mHost;        // The `UpdateMetadata` has no ownership of this host.
939         Ip6::MessageInfo  mMessageInfo; // Valid when `mIsDirectRxFromClient` is true.
940         bool              mIsDirectRxFromClient;
941     };
942 
943     void              Start(void);
944     void              Stop(void);
945     void              SelectPort(void);
946     void              PrepareSocket(void);
947     Ip6::Udp::Socket &GetSocket(void);
948 
949 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
950     void  HandleDnssdServerStateChange(void);
951     Error HandleDnssdServerUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
952 #endif
953 
954     void HandleNetDataPublisherEvent(NetworkData::Publisher::Event aEvent);
955 
AllocateId(void)956     ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; }
957 
958     void  InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata);
959     void  CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata);
960     void  CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata);
961     void  CommitSrpUpdate(Error                    aError,
962                           Host &                   aHost,
963                           const Dns::UpdateHeader &aDnsHeader,
964                           const Ip6::MessageInfo * aMessageInfo,
965                           const TtlConfig &        aTtlConfig,
966                           const LeaseConfig &      aLeaseConfig);
967     Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
968     Error ProcessMessage(Message &               aMessage,
969                          TimeMilli               aRxTime,
970                          const TtlConfig &       aTtlConfig,
971                          const LeaseConfig &     aLeaseConfig,
972                          const Ip6::MessageInfo *aMessageInfo);
973     void  ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata);
974     Error ProcessUpdateSection(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
975     Error ProcessAdditionalSection(Host *aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
976     Error VerifySignature(const Dns::Ecdsa256KeyRecord &aKeyRecord,
977                           const Message &               aMessage,
978                           Dns::UpdateHeader             aDnsHeader,
979                           uint16_t                      aSigOffset,
980                           uint16_t                      aSigRdataOffset,
981                           uint16_t                      aSigRdataLength,
982                           const char *                  aSignerName) const;
983     Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata);
984     Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
985     Error ProcessHostDescriptionInstruction(Host &                 aHost,
986                                             const Message &        aMessage,
987                                             const MessageMetadata &aMetadata) const;
988     Error ProcessServiceDiscoveryInstructions(Host &                 aHost,
989                                               const Message &        aMessage,
990                                               const MessageMetadata &aMetadata) const;
991     Error ProcessServiceDescriptionInstructions(Host &aHost, const Message &aMessage, MessageMetadata &aMetadata) const;
992 
993     static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord);
994 
995     void        HandleUpdate(Host &aHost, const MessageMetadata &aMetadata);
996     void        AddHost(Host &aHost);
997     void        RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
998     bool        HasNameConflictsWith(Host &aHost) const;
999     void        SendResponse(const Dns::UpdateHeader &   aHeader,
1000                              Dns::UpdateHeader::Response aResponseCode,
1001                              const Ip6::MessageInfo &    aMessageInfo);
1002     void        SendResponse(const Dns::UpdateHeader &aHeader,
1003                              uint32_t                 aLease,
1004                              uint32_t                 aKeyLease,
1005                              const Ip6::MessageInfo & aMessageInfo);
1006     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
1007     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1008     static void HandleLeaseTimer(Timer &aTimer);
1009     void        HandleLeaseTimer(void);
1010     static void HandleOutstandingUpdatesTimer(Timer &aTimer);
1011     void        HandleOutstandingUpdatesTimer(void);
1012 
1013     void                  HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError);
1014     const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const;
1015     static const char *   AddressModeToString(AddressMode aMode);
1016 
1017     void UpdateResponseCounters(Dns::Header::Response aResponseCode);
1018 
1019     Ip6::Udp::Socket                mSocket;
1020     otSrpServerServiceUpdateHandler mServiceUpdateHandler;
1021     void *                          mServiceUpdateHandlerContext;
1022 
1023     Heap::String mDomain;
1024 
1025     TtlConfig   mTtlConfig;
1026     LeaseConfig mLeaseConfig;
1027 
1028     LinkedList<Host> mHosts;
1029     TimerMilli       mLeaseTimer;
1030 
1031     TimerMilli                 mOutstandingUpdatesTimer;
1032     LinkedList<UpdateMetadata> mOutstandingUpdates;
1033 
1034     ServiceUpdateId mServiceUpdateId;
1035     uint16_t        mPort;
1036     State           mState;
1037     AddressMode     mAddressMode;
1038     uint8_t         mAnycastSequenceNumber;
1039     bool            mHasRegisteredAnyService : 1;
1040 
1041     otSrpServerResponseCounters mResponseCounters;
1042 };
1043 
1044 } // namespace Srp
1045 
1046 DefineCoreType(otSrpServerTtlConfig, Srp::Server::TtlConfig);
1047 DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig);
1048 DefineCoreType(otSrpServerHost, Srp::Server::Host);
1049 DefineCoreType(otSrpServerService, Srp::Server::Service);
1050 DefineMapEnum(otSrpServerState, Srp::Server::State);
1051 DefineMapEnum(otSrpServerAddressMode, Srp::Server::AddressMode);
1052 
1053 } // namespace ot
1054 
1055 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
1056 #endif // NET_SRP_SERVER_HPP_
1057