mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 01:17:46 +00:00
[net] SRP client implementation (#6038)
This commit adds support for SRP (Service Registration Protocol) client in OpenThread. The implementation allows a user to provide host info (host name and a list of host IPv6 addresses) along with a list of services to be registered with an SRP server. Services and/or host addresses can be added or removed during operation of client. Users can get the list of services and host info and their current state (indicating, for example, if service is registered with server, being registered or being removed, etc). Users can also provide a callback to get notified whenever there is change or an error. When there is a new request (e.g., a new service is added/removed) that requires an update, the SRP client will wait for a short delay before preparing and sending an SRP update message to server. This allows user to provide more changes that are then all sent in the same update message. The implementation handles retries in case of different errors and failures. An exponentially increasing retry wait interval (with configurable min, max, and growth factor) is implemented. The implementation also manages the lease renew time for each service and refreshes (re-registers) services with server before lease is expired. It supports "opportunistic early refresh" mechanism such that when sending an SRP update, the services that are not yet expired but are close, are allowed to refresh early and are included in the SRP update. This helps place more services on the same lease refresh schedule reducing number of messages sent to the SRP server. This behavior (whether to allow early refresh or not, and its related parameters) can be controlled through a set of OT config definitions.
This commit is contained in:
committed by
Jonathan Hui
parent
de62590edb
commit
966baf5e6b
@@ -186,6 +186,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/api/random_crypto_api.cpp \
|
||||
src/core/api/random_noncrypto_api.cpp \
|
||||
src/core/api/server_api.cpp \
|
||||
src/core/api/srp_client_api.cpp \
|
||||
src/core/api/tasklet_api.cpp \
|
||||
src/core/api/thread_api.cpp \
|
||||
src/core/api/thread_ftd_api.cpp \
|
||||
@@ -262,6 +263,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/net/ip6_headers.cpp \
|
||||
src/core/net/ip6_mpl.cpp \
|
||||
src/core/net/netif.cpp \
|
||||
src/core/net/srp_client.cpp \
|
||||
src/core/net/udp6.cpp \
|
||||
src/core/radio/radio.cpp \
|
||||
src/core/radio/radio_callbacks.cpp \
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
* @defgroup api-dns DNSv6
|
||||
* @defgroup api-icmp6 ICMPv6
|
||||
* @defgroup api-ip6 IPv6
|
||||
* @defgroup api-srp SRP
|
||||
* @defgroup api-udp-group UDP
|
||||
*
|
||||
* @{
|
||||
|
||||
@@ -167,6 +167,11 @@ if(OT_ECDSA)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ECDSA_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_SRP_CLIENT "enable SRP client support")
|
||||
if (OT_SRP_CLIENT)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_DUA "enable Domain Unicast Address feature for Thread 1.2")
|
||||
if(OT_DUA)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DUA_ENABLE=1")
|
||||
|
||||
@@ -56,6 +56,7 @@ This page lists the available common switches with description. Unless stated ot
|
||||
| SLAAC | OT_SLAAC | Enables support for adding auto-configured SLAAC addresses by OpenThread. This feature is enabled by default. |
|
||||
| SNTP_CLIENT | OT_SNTP_CLIENT | Enables support for SNTP Client. |
|
||||
| SPINEL_ENCRYPTER_LIBS | not implemented | Specifies library files (absolute paths) for implementing the NCP Spinel Encrypter. |
|
||||
| SRP_CLIENT | OT_SRP_CLIENT | Enable support for SRP client. |
|
||||
| THREAD_VERSION | OT_THREAD_VERSION | Enables the chosen Thread version (1.1 (default) / 1.2). For example, set to `1.2` for Thread 1.2. |
|
||||
| TIME_SYNC | OT_TIME_SYNC | Enables the time synchronization service feature. **Note: Enabling this feature breaks conformance to the Thread Specification.** | |
|
||||
| UDP_FORWARD | OT_UDP_FORWARD | Enables support for UDP forward. | Enable this switch on the Border Router device (running on the NCP design) with External Commissioning support to service Thread Commissioner packets on the NCP side. |
|
||||
|
||||
@@ -76,6 +76,7 @@ SETTINGS_RAM ?= 0
|
||||
# SLAAC is enabled by default
|
||||
SLAAC ?= 1
|
||||
SNTP_CLIENT ?= 0
|
||||
SRP_CLIENT ?= 0
|
||||
THREAD_VERSION ?= 1.1
|
||||
TIME_SYNC ?= 0
|
||||
UDP_FORWARD ?= 0
|
||||
@@ -268,6 +269,10 @@ ifeq ($(SNTP_CLIENT),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(SRP_CLIENT),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(THREAD_VERSION),1.1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
|
||||
else ifeq ($(THREAD_VERSION),1.2)
|
||||
|
||||
@@ -74,6 +74,7 @@ openthread_headers = \
|
||||
openthread/random_noncrypto.h \
|
||||
openthread/server.h \
|
||||
openthread/sntp.h \
|
||||
openthread/srp_client.h \
|
||||
openthread/tasklet.h \
|
||||
openthread/thread.h \
|
||||
openthread/thread_ftd.h \
|
||||
|
||||
@@ -114,6 +114,7 @@ source_set("openthread") {
|
||||
"random_noncrypto.h",
|
||||
"server.h",
|
||||
"sntp.h",
|
||||
"srp_client.h",
|
||||
"tasklet.h",
|
||||
"thread.h",
|
||||
"thread_ftd.h",
|
||||
|
||||
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file defines the OpenThread SRP (Service Registration Protocol) client APIs.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_SRP_CLIENT_H_
|
||||
#define OPENTHREAD_SRP_CLIENT_H_
|
||||
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-srp
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions that control SRP client behavior.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This structure represents a TXT record entry representing a key/value pair (RFC 6763 - section 6.3).
|
||||
*
|
||||
* The strings buffers pointed to by `mKey` and `mValue` MUST persist and remain unchanged after an instance of such a
|
||||
* structure is passed to OpenThread (as part of `otSrpClientService` instance).
|
||||
*
|
||||
* An array of `otSrpTxtEntry` entries is used in `otSrpClientService` to specify the full TXT record (a list of
|
||||
* entries).
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpTxtEntry
|
||||
{
|
||||
/**
|
||||
* The TXT record key string.
|
||||
*
|
||||
* If `mKey` is not NULL, then the entry is treated as key/value pair with `mValue` buffer providing the value.
|
||||
* - The entry is encoded as follows:
|
||||
* - A single string length byte followed by "key=value" format (without the quotation marks).
|
||||
- In this case, the overall encoded length must be 255 bytes or less.
|
||||
* - If `mValue` is NULL, then key is treated as a boolean attribute and encoded as "key" (with no `=`).
|
||||
* - If `mValue` is not NULL but `mValueLength` is zero, then it is treated as empty value and encoded as "key=".
|
||||
*
|
||||
* If `mKey` is NULL, then `mValue` buffer is treated as an already encoded TXT-DATA and is appended as is in the
|
||||
* DNS message.
|
||||
*
|
||||
*/
|
||||
const char * mKey;
|
||||
const uint8_t *mValue; ///< The TXT record value or already encoded TXT-DATA (depending on `mKey`).
|
||||
uint16_t mValueLength; ///< Number of bytes in `mValue` buffer.
|
||||
} otSrpTxtEntry;
|
||||
|
||||
/**
|
||||
* This enumeration specifies an SRP client item (service or host info) state.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_SRP_CLIENT_ITEM_STATE_TO_ADD, ///< Item to be added/registered.
|
||||
OT_SRP_CLIENT_ITEM_STATE_ADDING, ///< Item is being added/registered.
|
||||
OT_SRP_CLIENT_ITEM_STATE_TO_REFRESH, ///< Item to be refreshed (re-register to renew lease).
|
||||
OT_SRP_CLIENT_ITEM_STATE_REFRESHING, ///< Item is being refreshed.
|
||||
OT_SRP_CLIENT_ITEM_STATE_TO_REMOVE, ///< Item to be removed.
|
||||
OT_SRP_CLIENT_ITEM_STATE_REMOVING, ///< Item is being removed.
|
||||
OT_SRP_CLIENT_ITEM_STATE_REGISTERED, ///< Item is registered with server.
|
||||
OT_SRP_CLIENT_ITEM_STATE_REMOVED, ///< Item is removed.
|
||||
} otSrpClientItemState;
|
||||
|
||||
/**
|
||||
* This structure represents an SRP client host info.
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpClientHostInfo
|
||||
{
|
||||
const char * mName; ///< Host name (label) string (NULL if not yet set).
|
||||
const otIp6Address * mAddresses; ///< Pointer to an array of host IPv6 addresses (NULL if not yet set).
|
||||
uint8_t mNumAddresses; ///< Number of IPv6 addresses in `mAddresses` array.
|
||||
otSrpClientItemState mState; ///< Host info state.
|
||||
} otSrpClientHostInfo;
|
||||
|
||||
/**
|
||||
* This structure represents an SRP client service.
|
||||
*
|
||||
* The values in this structure, including the string buffers for the names and the TXT record entries, MUST persist
|
||||
* and stay constant after an instance of this structure is passed to OpenThread from `otSrpClientAddService()` or
|
||||
* `otSrpClientRemoveService()`.
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpClientService
|
||||
{
|
||||
const char * mName; ///< The service name labels (e.g., "_chip._udp", not the full domain name).
|
||||
const char * mInstanceName; ///< The service instance name label (not the full name).
|
||||
const otSrpTxtEntry *mTxtEntries; ///< Array of TXT entries (number of entries is given by `mNumTxtEntries`).
|
||||
uint16_t mPort; ///< The service port number.
|
||||
uint16_t mPriority; ///< The service priority.
|
||||
uint16_t mWeight; ///< The service weight.
|
||||
uint8_t mNumTxtEntries; ///< Number of entries in the `mTxtEntries` array.
|
||||
|
||||
/**
|
||||
* @note The following fields are used/managed by OT core only. Their values do not matter and are ignored when an
|
||||
* instance of `otSrpClientService` is passed in `otSrpClientAddService()` or `otSrpClientRemoveService()`. The
|
||||
* user should not modify these fields.
|
||||
*
|
||||
*/
|
||||
|
||||
otSrpClientItemState mState; ///< Service state (managed by OT core).
|
||||
uint32_t mData; ///< Internal data (used by OT core).
|
||||
struct otSrpClientService *mNext; ///< Pointer to next entry in a linked-list (managed by OT core).
|
||||
} otSrpClientService;
|
||||
|
||||
/**
|
||||
* This function pointer type defines the callback used by SRP client to notify user of changes/events/errors.
|
||||
*
|
||||
* This callback is invoked on a successful registration of an update (i.e., add/remove of host-info and/or some
|
||||
* service(s)) with the SRP server, or if there is a failure or error (e.g., server rejects a update request or client
|
||||
* times out waiting for response, etc).
|
||||
*
|
||||
* In case of a successful reregistration of an update, `aError` parameter would be `OT_ERROR_NONE` and the host info
|
||||
* and the full list of services is provided as input parameters to the callback. Note that host info and services each
|
||||
* track its own state in the corresponding `mState` member variable of the related data structure (the state
|
||||
* indicating whether the host-info/service is registered or removed or still being added/removed, etc).
|
||||
*
|
||||
* The list of removed services is passed as its own linked-list `aRemovedServices` in the callback. Note that when the
|
||||
* callback is invoked, the SRP client (OpenThread implementation) is done with the removed service instances listed in
|
||||
* `aRemovedServices` and no longer tracks/stores them (i.e., if from the callback we call `otSrpClientGetServices()`
|
||||
* the removed services will not be present in the returned list). Providing a separate list of removed services in
|
||||
* the callback helps indicate to user which items are now removed and allow user to re-claim/reuse the instances.
|
||||
*
|
||||
* If the server rejects an SRP update request, the DNS response code (RFC 2136) is mapped to the following errors:
|
||||
*
|
||||
* (0) NOERROR Success (no error condition) -> OT_ERROR_NONE
|
||||
* (1) FORMERR Server unable to interpret due to format error -> OT_ERROR_PARSE
|
||||
* (2) SERVFAIL Server encountered an internal failure -> OT_ERROR_FAILED
|
||||
* (3) NXDOMAIN Name that ought to exist, does not exist -> OT_ERROR_NOT_FOUND
|
||||
* (4) NOTIMP Server does not support the query type (OpCode) -> OT_ERROR_NOT_IMPLEMENTED
|
||||
* (5) REFUSED Server refused for policy/security reasons -> OT_ERROR_SECURITY
|
||||
* (6) YXDOMAIN Some name that ought not to exist, does exist -> OT_ERROR_DUPLICATED
|
||||
* (7) YXRRSET Some RRset that ought not to exist, does exist -> OT_ERROR_DUPLICATED
|
||||
* (8) NXRRSET Some RRset that ought to exist, does not exist -> OT_ERROR_NOT_FOUND
|
||||
* (9) NOTAUTH Service is not authoritative for zone -> OT_ERROR_SECURITY
|
||||
* (10) NOTZONE A name is not in the zone -> OT_ERROR_PARSE
|
||||
* (20) BADNAME Bad name -> OT_ERROR_PARSE
|
||||
* (21) BADALG Bad algorithm -> OT_ERROR_SECURITY
|
||||
* (22) BADTRUN Bad truncation -> OT_ERROR_PARSE
|
||||
* Other response codes -> OT_ERROR_FAILED
|
||||
*
|
||||
* The following errors are also possible:
|
||||
*
|
||||
* OT_ERROR_RESPONSE_TIMEOUT : Timed out waiting for response from server (client would continue to retry).
|
||||
* OT_ERROR_INVALID_ARGS : The provided service structure is invalid (e.g., bad service name or `otSrpTxtEntry`).
|
||||
* OT_ERROR_NO_BUFS : Insufficient buffer to prepare or send the update message.
|
||||
*
|
||||
* Note that in case of any failure, the client continues the operation, i.e. it prepares and (re)transmits the SRP
|
||||
* update message to the server, after some wait interval. The retry wait interval starts from the minimum value and
|
||||
* is increased by the growth factor every failure up to the max value (please see configuration parameter
|
||||
* `OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL` and the related ones for more details).
|
||||
*
|
||||
* @param[in] aError The error (see above).
|
||||
* @param[in] aHostInfo A pointer to host info.
|
||||
* @param[in] aService The head of linked-list containing all services (excluding the ones removed). NULL if
|
||||
* the list is empty.
|
||||
* @param[in] aRemovedServices The head of linked-list containing all removed services. NULL if the list is empty.
|
||||
* @param[in] aContext A pointer to an arbitrary context (provided when callback was registered).
|
||||
*
|
||||
*/
|
||||
typedef void (*otSrpClientCallback)(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
const otSrpClientService * aRemovedServices,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function starts the SRP client operation.
|
||||
*
|
||||
* SRP client will prepare and send "SRP Update" message to the SRP server once all the following conditions are met:
|
||||
*
|
||||
* - The SRP client is started - `otSrpClientStart()` is called.
|
||||
* - Host name is set - `otSrpClientSetHostName()` is called.
|
||||
* - At least one host IPv6 address is set - `otSrpClientSetHostName()` is called.
|
||||
* - At least one service is added - `otSrpClientAddService()` is called.
|
||||
*
|
||||
* It does not matter in which order these functions are called. When all conditions are met, the SRP client will
|
||||
* wait for a short delay before preparing an "SRP Update" message and sending it to server. This delay allows for user
|
||||
* to add multiple services and/or IPv6 addresses before the first SRP Update message is sent (ensuring a single SRP
|
||||
* Update is sent containing all the info). The config `OPENTHREAD_CONFIG_SRP_CLIENT_UPDATE_TX_DELAY` specifies the
|
||||
* delay interval.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aServerSockAddr The socket address (IPv6 address and port number) of the SRP server.
|
||||
* @param[in] aCallback The callback which is used to notify events and changes. Can be NULL if not needed.
|
||||
* @param[in] aContext An arbitrary context used with @p aCallback.
|
||||
*
|
||||
* @retval OT_ERROR_NONE SRP client operation started successfully or it is already running with same server
|
||||
* socket address and callback.
|
||||
* @retval OT_ERROR_BUSY SRP client is busy running with a different socket address and/or callback.
|
||||
* @retval OT_ERROR_FAILED Failed to open/connect the client's UDP socket.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientStart(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
otSrpClientCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function stops the SRP client operation.
|
||||
*
|
||||
* This function stops any further interactions with the SRP server. Note that it does not remove or clear host info
|
||||
* and/or list of services. It marks all services to be added/removed again once the client is (re)started.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otSrpClientStop(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function gets the lease interval used in SRP update requests.
|
||||
*
|
||||
* Note that this is the lease duration requested by the SRP client. The server may choose to accept a different lease
|
||||
* interval.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns The lease interval (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the lease interval used in SRP update requests.
|
||||
*
|
||||
* Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
|
||||
* It only affects any future SRP update messages (i.e., adding new services and/or refreshes of the existing services).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aInterval The lease interval (in seconds). If zero, the default value specified by
|
||||
* `OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE` would be used.
|
||||
*
|
||||
*/
|
||||
void otSrpClientSetLeaseInterval(otInstance *aInstance, uint32_t aInterval);
|
||||
|
||||
/**
|
||||
* This function gets the key lease interval used in SRP update requests.
|
||||
*
|
||||
* Note that this is the lease duration requested by the SRP client. The server may choose to accept a different lease
|
||||
* interval.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns The key lease interval (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t otSrpClientGetKeyLeaseInterval(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the key lease interval used in SRP update requests.
|
||||
*
|
||||
* Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
|
||||
* It only affects any future SRP update messages (i.e., adding new services and/or refreshes of existing services).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aInterval The key lease interval (in seconds). If zero, the default value specified by
|
||||
* `OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE` would be used.
|
||||
*
|
||||
*/
|
||||
void otSrpClientSetKeyLeaseInterval(otInstance *aInstance, uint32_t aInterval);
|
||||
|
||||
/**
|
||||
* This function gets the host info.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to host info structure.
|
||||
*
|
||||
*/
|
||||
const otSrpClientHostInfo *otSrpClientGetHostInfo(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the host name label.
|
||||
*
|
||||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of host info
|
||||
* registration with SRP server.
|
||||
*
|
||||
* The name string buffer pointed to by @p aName MUST persist and stay unchanged after returning from this function.
|
||||
* OpenThread will keep the pointer to the string.
|
||||
*
|
||||
* The host name can be set before client is started or after start but before host info is registered with server
|
||||
* (host info should be in either `STATE_TO_ADD` or `STATE_REMOVED`).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aName A pointer to host name label string (MUST NOT be NULL). Pointer to the string buffer MUST
|
||||
* persist and remain valid and constant after return from this function.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host name label was set successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aName is NULL.
|
||||
* @retval OT_ERROR_INVALID_STATE The host name is already set and registered with the server.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
||||
|
||||
/**
|
||||
* This function sets/updates the list of host IPv6 address.
|
||||
*
|
||||
* Host IPv6 addresses can be set/changed before start or during operation of SRP client (e.g. to add/remove or change
|
||||
* a previously registered host address), except when the host info is being removed (client is busy handling a remove
|
||||
* request from an earlier call to `otSrpClientRemoveHostAndServices()` and host info still being in either
|
||||
* `STATE_TO_REMOVE` or `STATE_REMOVING` states).
|
||||
*
|
||||
* The host IPv6 address array pointed to by @p aAddresses MUST persist and remain unchanged after returning from this
|
||||
* function (with `OT_ERROR_NONE`). OpenThread will save the pointer to the array.
|
||||
*
|
||||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of the address
|
||||
* registration with SRP server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aAddresses A pointer to the an array containing the host IPv6 addresses.
|
||||
* @param[in] aNumAddresses The number of addresses in the @p aAddresses array.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host IPv6 address list change started successfully. The `otSrpClientCallback`
|
||||
* will be called to report the status of registering addresses with server.
|
||||
* @retval OT_ERROR_INVALID_ARGS The address list is invalid (e.g., must contain at least one address).
|
||||
* @retval OT_ERROR_INVALID_STATE Host is being removed and therefore cannot change host address.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientSetHostAddresses(otInstance *aInstance, const otIp6Address *aIp6Addresses, uint8_t aNumAddresses);
|
||||
|
||||
/**
|
||||
* This function adds a service to be registered with server.
|
||||
*
|
||||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of the service
|
||||
* addition/registration with SRP server.
|
||||
*
|
||||
* The `otSrpClientService` instance being pointed to by @p aService MUST persist and remain unchanged after returning
|
||||
* from this function (with `OT_ERROR_NONE`). OpenThread will save the pointer to the service instance.
|
||||
*
|
||||
* The `otSrpClientService` instance is not longer tracked by OpenThread and can be reclaimed only when
|
||||
*
|
||||
* - It is removed explicitly by a call to `otSrpClientRemoveService()` or removed along with other services by a
|
||||
* call to `otSrpClientRemoveHostAndServices() and only after the `otSrpClientCallback` is called indicating the
|
||||
* service was removed. Or,
|
||||
* - A call to `otSrpClientClearHostAndServices()` which removes the host and all related services immediately.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aService A pointer to a `otSrpClientService` instance to add.
|
||||
|
||||
* @retval OT_ERROR_NONE The addition of service started successfully. The `otSrpClientCallback` will be
|
||||
* called to report the status.
|
||||
* @retval OT_ERROR_ALREADY The same service is already in the list.
|
||||
* @retval OT_ERROR_INVALID_ARGS The service structure is invalid (e.g., bad service name or `otSrpTxtEntry`).
|
||||
*
|
||||
*/
|
||||
otError otSrpClientAddService(otInstance *aInstance, otSrpClientService *aService);
|
||||
|
||||
/**
|
||||
* This function requests a service to be unregistered with server.
|
||||
*
|
||||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of remove
|
||||
* request with SRP server.
|
||||
|
||||
* The `otSrpClientService` instance being pointed to by @p aService MUST persist and remain unchanged after returning
|
||||
* from this function (with `OT_ERROR_NONE`). OpenThread will keep the service instance during the remove process.
|
||||
* Only after the `otSrpClientCallback` is called indicating the service instance is removed from SRP client
|
||||
* service list and can be be freed/reused.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aService A pointer to a `otSrpClientService` instance to remove.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The removal of service started successfully. The `otSrpClientCallback` will be called to
|
||||
* report the status.
|
||||
* @retval OT_ERROR_NOT_FOUND The service could not be found in the list.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientRemoveService(otInstance *aInstance, otSrpClientService *aService);
|
||||
|
||||
/**
|
||||
* This function gets the list of services being managed by client.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to the head of linked-list of all services or NULL if the list is empty.
|
||||
*
|
||||
*/
|
||||
const otSrpClientService *otSrpClientGetServices(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function starts the remove process of the host info and all services.
|
||||
*
|
||||
* After returning from this function, `otSrpClientCallback` will be called to report the status of remove request with
|
||||
* SRP server.
|
||||
*
|
||||
* If the host info is to be permanently removed from server, @p aRemoveKeyLease should be set to `true` which removes
|
||||
* the key lease associated with host on server. Otherwise, the key lease record is kept as before, which ensures
|
||||
* that the server holds the host name in reserve for when the client is once again able to provide and register its
|
||||
* service(s).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aRemoveKeyLease A boolean indicating whether or not the host key lease should also be removed.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The removal of host info and services started successfully. The `otSrpClientCallback`
|
||||
* will be called to report the status.
|
||||
* @retval OT_ERROR_ALREADY The host info is already removed.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientRemoveHostAndServices(otInstance *aInstance, bool aRemoveKeyLease);
|
||||
|
||||
/**
|
||||
* This function clears all host info and all the services.
|
||||
*
|
||||
* Unlike `otSrpClientRemoveHostAndServices()` which sends an update message to server to remove/unregister all the
|
||||
* info, this function clears all the info immediately without any interaction with server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otSrpClientClearHostAndServices(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function gets the domain name being used by SRP client.
|
||||
*
|
||||
* This function requires `OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE` to be enabled.
|
||||
*
|
||||
* If domain name is not set, "default.service.arpa" will be used.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns The domain name string.
|
||||
*
|
||||
*/
|
||||
const char *otSrpClientGetDomainName(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the domain name to be used by SRP client.
|
||||
*
|
||||
* This function requires `OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE` to be enabled.
|
||||
*
|
||||
* If not set "default.service.arpa" will be used.
|
||||
*
|
||||
* The name string buffer pointed to by @p aName MUST persist and stay unchanged after returning from this function.
|
||||
* OpenThread will keep the pointer to the string.
|
||||
*
|
||||
* The domain name can be set before client is started or after start but before host info is registered with server
|
||||
* (host info should be in either `STATE_TO_ADD` or `STATE_TO_REMOVE`).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aName A pointer to the domain name string. If NULL sets it to default "default.service.arpa".
|
||||
*
|
||||
* @retval OT_ERROR_NONE The domain name label was set successfully.
|
||||
* @retval OT_ERROR_INVALID_STATE The host info is already registered with server.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientSetDomainName(otInstance *aInstance, const char *aName);
|
||||
|
||||
/**
|
||||
* This function converts a `otSrpClientItemState` to a string.
|
||||
*
|
||||
* @param[in] aItemState An item state.
|
||||
*
|
||||
* @returns A string representation of @p aItemState.
|
||||
*
|
||||
*/
|
||||
const char *otSrpClientItemStateToString(otSrpClientItemState aItemState);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_SRP_CLIENT_H_
|
||||
@@ -174,6 +174,7 @@ build_nrf52833()
|
||||
"SERVICE=1"
|
||||
"SLAAC=1"
|
||||
"SNTP_CLIENT=1"
|
||||
"SRP_CLIENT=1"
|
||||
"UDP_FORWARD=1"
|
||||
)
|
||||
|
||||
@@ -216,6 +217,7 @@ build_nrf52840()
|
||||
"SERVICE=1"
|
||||
"SLAAC=1"
|
||||
"SNTP_CLIENT=1"
|
||||
"SRP_CLIENT=1"
|
||||
"UDP_FORWARD=1"
|
||||
)
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ do_scan_build()
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
|
||||
|
||||
@@ -80,6 +80,7 @@ build_all_features()
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
|
||||
|
||||
@@ -126,6 +126,7 @@ size_nrf52840_version()
|
||||
"SERVICE=1"
|
||||
"SLAAC=1"
|
||||
"SNTP_CLIENT=1"
|
||||
"SRP_CLIENT=1"
|
||||
"TIME_SYNC=1"
|
||||
"UDP_FORWARD=1"
|
||||
)
|
||||
|
||||
@@ -90,6 +90,7 @@ readonly OT_POSIX_SIM_COMMON_OPTIONS=(
|
||||
"-DOT_REFERENCE_DEVICE=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
"-DOT_SNTP_CLIENT=ON"
|
||||
"-DOT_SRP_CLIENT=ON"
|
||||
"-DOT_COVERAGE=ON"
|
||||
"-DOT_LOG_LEVEL_DYNAMIC=ON"
|
||||
"-DOT_COMPILE_WARNING_AS_ERROR=ON"
|
||||
|
||||
@@ -109,6 +109,7 @@ readonly OT_CLANG_TIDY_BUILD_OPTS=(
|
||||
'-DOT_SERVICE=ON'
|
||||
'-DOT_SLAAC=ON'
|
||||
'-DOT_SNTP_CLIENT=ON'
|
||||
'-DOT_SRP_CLIENT=ON'
|
||||
'-DOT_THREAD_VERSION=1.2'
|
||||
'-DOT_COVERAGE=ON'
|
||||
'-DOT_LOG_LEVEL_DYNAMIC=ON'
|
||||
|
||||
@@ -333,6 +333,7 @@ openthread_core_files = [
|
||||
"api/random_noncrypto_api.cpp",
|
||||
"api/server_api.cpp",
|
||||
"api/sntp_api.cpp",
|
||||
"api/srp_client_api.cpp",
|
||||
"api/tasklet_api.cpp",
|
||||
"api/thread_api.cpp",
|
||||
"api/thread_ftd_api.cpp",
|
||||
@@ -503,6 +504,8 @@ openthread_core_files = [
|
||||
"net/sntp_client.cpp",
|
||||
"net/sntp_client.hpp",
|
||||
"net/socket.hpp",
|
||||
"net/srp_client.cpp",
|
||||
"net/srp_client.hpp",
|
||||
"net/tcp.hpp",
|
||||
"net/udp6.cpp",
|
||||
"net/udp6.hpp",
|
||||
@@ -683,6 +686,7 @@ source_set("libopenthread_core_config") {
|
||||
"config/platform.h",
|
||||
"config/radio_link.h",
|
||||
"config/sntp_client.h",
|
||||
"config/srp_client.h",
|
||||
"config/time_sync.h",
|
||||
"config/tmf.h",
|
||||
"openthread-core-config.h",
|
||||
|
||||
@@ -66,6 +66,7 @@ set(COMMON_SOURCES
|
||||
api/random_noncrypto_api.cpp
|
||||
api/server_api.cpp
|
||||
api/sntp_api.cpp
|
||||
api/srp_client_api.cpp
|
||||
api/tasklet_api.cpp
|
||||
api/thread_api.cpp
|
||||
api/thread_ftd_api.cpp
|
||||
@@ -144,6 +145,7 @@ set(COMMON_SOURCES
|
||||
net/ip6_mpl.cpp
|
||||
net/netif.cpp
|
||||
net/sntp_client.cpp
|
||||
net/srp_client.cpp
|
||||
net/udp6.cpp
|
||||
radio/radio.cpp
|
||||
radio/radio_callbacks.cpp
|
||||
|
||||
@@ -143,6 +143,7 @@ SOURCES_COMMON = \
|
||||
api/random_noncrypto_api.cpp \
|
||||
api/server_api.cpp \
|
||||
api/sntp_api.cpp \
|
||||
api/srp_client_api.cpp \
|
||||
api/tasklet_api.cpp \
|
||||
api/thread_api.cpp \
|
||||
api/thread_ftd_api.cpp \
|
||||
@@ -221,6 +222,7 @@ SOURCES_COMMON = \
|
||||
net/ip6_mpl.cpp \
|
||||
net/netif.cpp \
|
||||
net/sntp_client.cpp \
|
||||
net/srp_client.cpp \
|
||||
net/udp6.cpp \
|
||||
radio/radio.cpp \
|
||||
radio/radio_callbacks.cpp \
|
||||
@@ -412,6 +414,7 @@ HEADERS_COMMON = \
|
||||
config/platform.h \
|
||||
config/radio_link.h \
|
||||
config/sntp_client.h \
|
||||
config/srp_client.h \
|
||||
config/time_sync.h \
|
||||
config/tmf.h \
|
||||
crypto/aes_ccm.hpp \
|
||||
@@ -463,6 +466,7 @@ HEADERS_COMMON = \
|
||||
net/netif.hpp \
|
||||
net/sntp_client.hpp \
|
||||
net/socket.hpp \
|
||||
net/srp_client.hpp \
|
||||
net/tcp.hpp \
|
||||
net/udp6.hpp \
|
||||
radio/radio.hpp \
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the OpenThread SRP client APIs.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/srp_client.h>
|
||||
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "net/srp_client.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
otError otSrpClientStart(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
otSrpClientCallback aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().Start(*static_cast<const Ip6::SockAddr *>(aServerSockAddr), aCallback, aContext);
|
||||
}
|
||||
|
||||
void otSrpClientStop(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().Stop();
|
||||
}
|
||||
|
||||
uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().GetLeaseInterval();
|
||||
}
|
||||
|
||||
void otSrpClientSetLeaseInterval(otInstance *aInstance, uint32_t aInterval)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().SetLeaseInterval(aInterval);
|
||||
}
|
||||
|
||||
uint32_t otSrpClientGetKeyLeaseInterval(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().GetKeyLeaseInterval();
|
||||
}
|
||||
|
||||
void otSrpClientSetKeyLeaseInterval(otInstance *aInstance, uint32_t aInterval)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().SetKeyLeaseInterval(aInterval);
|
||||
}
|
||||
|
||||
const otSrpClientHostInfo *otSrpClientGetHostInfo(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return &instance.Get<Srp::Client>().GetHostInfo();
|
||||
}
|
||||
|
||||
otError otSrpClientSetHostName(otInstance *aInstance, const char *aName)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().SetHostName(aName);
|
||||
}
|
||||
|
||||
otError otSrpClientSetHostAddresses(otInstance *aInstance, const otIp6Address *aIp6Addresses, uint8_t aNumAddresses)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().SetHostAddresses(static_cast<const Ip6::Address *>(aIp6Addresses),
|
||||
aNumAddresses);
|
||||
}
|
||||
|
||||
otError otSrpClientAddService(otInstance *aInstance, otSrpClientService *aService)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().AddService(*static_cast<Srp::Client::Service *>(aService));
|
||||
}
|
||||
|
||||
otError otSrpClientRemoveService(otInstance *aInstance, otSrpClientService *aService)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().RemoveService(*static_cast<Srp::Client::Service *>(aService));
|
||||
}
|
||||
|
||||
const otSrpClientService *otSrpClientGetServices(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().GetServices().GetHead();
|
||||
}
|
||||
|
||||
otError otSrpClientRemoveHostAndServices(otInstance *aInstance, bool aRemoveKeyLease)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().RemoveHostAndServices(aRemoveKeyLease);
|
||||
}
|
||||
|
||||
void otSrpClientClearHostAndServices(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.Get<Srp::Client>().ClearHostAndServices();
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
const char *otSrpClientGetDomainName(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().GetDomainName();
|
||||
}
|
||||
|
||||
otError otSrpClientSetDomainName(otInstance *aInstance, const char *aDomainName)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Srp::Client>().SetDomainName(aDomainName);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
|
||||
const char *otSrpClientItemStateToString(otSrpClientItemState aItemState)
|
||||
{
|
||||
OT_ASSERT(aItemState <= OT_SRP_CLIENT_ITEM_STATE_REMOVED);
|
||||
|
||||
return Srp::Client::ItemStateToString(static_cast<Srp::Client::ItemState>(aItemState));
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
@@ -696,6 +696,13 @@ template <> inline Dns::Client &Instance::Get(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
template <> inline Srp::Client &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mSrpClient;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||
template <> inline NetworkDiagnostic::NetworkDiagnostic &Instance::Get(void)
|
||||
{
|
||||
|
||||
@@ -183,6 +183,9 @@ void Notifier::EmitEvents(void)
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
Get<BorderRouter::RoutingManager>().HandleNotifierEvents(events);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
Get<Srp::Client>().HandleNotifierEvents(events);
|
||||
#endif
|
||||
|
||||
for (ExternalCallback &callback : mExternalCallbacks)
|
||||
{
|
||||
|
||||
@@ -516,6 +516,48 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
otError Settings::SaveSrpKey(const Crypto::Ecdsa::P256::KeyPair &aKeyPair)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = Save(kKeySrpEcdsaKey, aKeyPair.GetDerBytes(), aKeyPair.GetDerLength()));
|
||||
otLogInfoCore("Non-volatile: Saved SRP key");
|
||||
|
||||
exit:
|
||||
LogFailure(error, "saving SRP key", false);
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Settings::ReadSrpKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair) const
|
||||
{
|
||||
otError error;
|
||||
uint16_t length = Crypto::Ecdsa::P256::KeyPair::kMaxDerSize;
|
||||
|
||||
SuccessOrExit(error = Read(kKeySrpEcdsaKey, aKeyPair.GetDerBytes(), length));
|
||||
VerifyOrExit(length <= Crypto::Ecdsa::P256::KeyPair::kMaxDerSize, error = OT_ERROR_NOT_FOUND);
|
||||
aKeyPair.SetDerLength(static_cast<uint8_t>(length));
|
||||
otLogInfoCore("Non-volatile: Read SRP key");
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Settings::DeleteSrpKey(void)
|
||||
{
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = Delete(kKeySrpEcdsaKey));
|
||||
otLogInfoCore("Non-volatile: Deleted SRP key");
|
||||
|
||||
exit:
|
||||
LogFailure(error, "deleting SRP key", true);
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
otError Settings::Read(Key aKey, void *aBuffer, uint16_t &aSize) const
|
||||
{
|
||||
return Get<SettingsDriver>().Get(aKey, 0, reinterpret_cast<uint8_t *>(aBuffer), &aSize);
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
#if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
|
||||
#include "utils/slaac_address.hpp"
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
#include "crypto/ecdsa.hpp"
|
||||
#endif
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -591,6 +594,7 @@ public:
|
||||
kKeyDadInfo = 0x0008, ///< Duplicate Address Detection (DAD) information.
|
||||
kKeyOmrPrefix = 0x0009, ///< Off-mesh routable (OMR) prefix.
|
||||
kKeyOnLinkPrefix = 0x000a, ///< On-link prefix for infrastructure link.
|
||||
kKeySrpEcdsaKey = 0x000b, ///< SRP client ECDSA public/private key pair.
|
||||
};
|
||||
|
||||
protected:
|
||||
@@ -1056,6 +1060,40 @@ public:
|
||||
otError ReadOnLinkPrefix(Ip6::Prefix &aOnLinkPrefix) const;
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
/**
|
||||
* This method saves SRP client ECDSA key pair.
|
||||
*
|
||||
* @param[in] aKeyPair A reference to an SRP ECDSA key-pair to save.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully saved key-pair information in settings.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
|
||||
*
|
||||
*/
|
||||
otError SaveSrpKey(const Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||
|
||||
/**
|
||||
* This method reads SRP client ECDSA key pair.
|
||||
*
|
||||
* @param[out] aKeyPair A reference to a ECDA `KeyPair` to output the read content.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully read key-pair information.
|
||||
* @retval OT_ERROR_NOT_FOUND No corresponding value in the setting store.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
|
||||
*
|
||||
*/
|
||||
otError ReadSrpKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair) const;
|
||||
|
||||
/**
|
||||
* This method deletes SRP client ECDSA key pair from settings.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully deleted the value.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
|
||||
*
|
||||
*/
|
||||
otError DeleteSrpKey(void);
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
private:
|
||||
class ChildInfoIteratorBuilder : public InstanceLocator
|
||||
{
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes compile-time configurations for the SRP (Service Registration Protocol) Client.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SRP_CLIENT_H_
|
||||
#define CONFIG_SRP_CLIENT_H_
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
*
|
||||
* Define to 1 to enable SRP Client support.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
*
|
||||
* Define to 1 for the SRP client implementation to provide APIs that get/set the domain name.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE
|
||||
*
|
||||
* Specifies the default requested lease interval (in seconds). Set to two hours.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE (2 * 60 * 60)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE
|
||||
*
|
||||
* Specifies the default requested key lease interval (in seconds). Set to 14 days.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE (14 * 24 * 60 * 60)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_LEASE_RENEW_GUARD_INTERVAL
|
||||
*
|
||||
* Specifies the guard interval (in seconds) for lease renew time. The guard interval determines how much earlier
|
||||
* (relative to the lease expiration time) the SRP client will send an SRP update for lease renewal.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_LEASE_RENEW_GUARD_INTERVAL
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_LEASE_RENEW_GUARD_INTERVAL 120 // two minutes in seconds
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR
|
||||
*
|
||||
* Specifies the numerator of early lease renewal factor.
|
||||
*
|
||||
* This value is used for opportunistic early refresh behave. When sending an SRP update, the services that are not yet
|
||||
* expired but are close, are allowed to refresh early and are included in the SRP update.
|
||||
*
|
||||
* The "early lease renewal interval" is used to determine if a service can renew early. The interval is calculated by
|
||||
* multiplying the accepted lease interval by the "early lease renewal factor" which is given as a fraction (numerator
|
||||
* and denominator).
|
||||
*
|
||||
* If the factor is set to zero (numerator=0, denominator=1), the opportunistic early refresh behavior is disabled.
|
||||
* If denominator is set to zero (the factor is set to infinity), then all services (including previously registered
|
||||
* ones) are always included in SRP update message.
|
||||
*
|
||||
* Default value is 1/2 (i.e., services that are within half of the lease interval are allowed to refresh early).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_DENOMINATOR
|
||||
*
|
||||
* Specifies the denominator of early lease renewal factor.
|
||||
*
|
||||
* Please see OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_DENOMINATOR
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_DENOMINATOR 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_UPDATE_TX_DELAY
|
||||
*
|
||||
* Specifies the (short) delay (in msec) after an update is required before SRP client sends the update message.
|
||||
*
|
||||
* When there is a change (e.g., a new service is added/removed) that requires an update, the SRP client will wait for
|
||||
* a short delay before preparing and sending an SRP update message to server. This allows user to provide more change
|
||||
* that are then all sent in same update message. The delay is only applied on the first change that triggers an
|
||||
* update message transmission. Subsequent changes (API calls) while waiting for the tx to start will not reset the
|
||||
* delay timer.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_UPDATE_TX_DELAY
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_UPDATE_TX_DELAY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL
|
||||
*
|
||||
* Specifies the minimum wait interval (in msec) between SRP update message retries.
|
||||
*
|
||||
* The update message is retransmitted if there is no response from server or if server rejects the update. The wait
|
||||
* interval starts from the minimum value and is increased by the growth factor every failure up to the max value.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL 1800
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_MAX_RETRY_WAIT_INTERVAL
|
||||
*
|
||||
* Specifies the maximum wait interval (in msec) between SRP update message retries.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_MAX_RETRY_WAIT_INTERVAL
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_MAX_RETRY_WAIT_INTERVAL (1 * 60 * 60 * 1000) // 1 hour in ms.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_WAIT_INTERVAL_JITTER
|
||||
*
|
||||
* Specifies jitter (in msec) for retry wait interval. If the current retry wait interval is smaller than the jitter
|
||||
* then the the wait interval itself is used as jitter (e.g., with jitter 500 msec and if retry interval is 300ms
|
||||
* the retry interval is then randomly selected from [0, 2*300] ms).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_WAIT_INTERVAL_JITTER
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_WAIT_INTERVAL_JITTER 500
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_NUMERATOR
|
||||
*
|
||||
* Specifies the numerator of the retry wait interval growth factor fraction. The growth factor is represented as
|
||||
* a fraction (e.g., for 1.5, we can use 15 as the numerator and 10 as the denominator).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_NUMERATOR
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_NUMERATOR 17
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_DENOMINATOR
|
||||
*
|
||||
* Specifies the denominator of the retry wait interval growth factor fraction.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_DENOMINATOR
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_DENOMINATOR 10
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_SRP_CLIENT_H_
|
||||
@@ -282,6 +282,40 @@ public:
|
||||
*
|
||||
*/
|
||||
const Address &GetAddress(void) const { return *static_cast<const Address *>(&mAddress); }
|
||||
|
||||
/**
|
||||
* This method returns the socket address port number.
|
||||
*
|
||||
* @returns The port number
|
||||
*
|
||||
*/
|
||||
uint16_t GetPort(void) const { return mPort; }
|
||||
|
||||
/**
|
||||
* This method overloads operator `==` to evaluate whether or not two `SockAddr` instances are equal (same address
|
||||
* and port number).
|
||||
*
|
||||
* @param[in] aOther The other `SockAddr` instance to compare with.
|
||||
*
|
||||
* @retval TRUE If the two `SockAddr` instances are equal.
|
||||
* @retval FALSE If the two `SockAddr` instances not equal.
|
||||
*
|
||||
*/
|
||||
bool operator==(const SockAddr &aOther) const
|
||||
{
|
||||
return (GetPort() == aOther.GetPort()) && (GetAddress() == aOther.GetAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overloads operator `!=` to evaluate whether or not two `SockAddr` instances are unequal.
|
||||
*
|
||||
* @param[in] aOther The other `SockAddr` instance to compare with.
|
||||
*
|
||||
* @retval TRUE If the two `SockAddr` instances are not equal.
|
||||
* @retval FALSE If the two `SockAddr` instances are equal.
|
||||
*
|
||||
*/
|
||||
bool operator!=(const SockAddr &aOther) const { return !(*this == aOther); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,732 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SRP_CLIENT_HPP_
|
||||
#define SRP_CLIENT_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/srp_client.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/linked_list.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "crypto/ecdsa.hpp"
|
||||
#include "net/dns_headers.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "net/udp6.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for the SRP (Service Registration Protocol) client.
|
||||
*/
|
||||
|
||||
namespace ot {
|
||||
namespace Srp {
|
||||
|
||||
#if !OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
#error "SRP Client feature requires ECDSA support (OPENTHREAD_CONFIG_ECDSA_ENABLE)."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class implements SRP client.
|
||||
*
|
||||
*/
|
||||
class Client : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend class ot::Notifier;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This enumeration types represents an SRP client item (service or host info) state.
|
||||
*
|
||||
*/
|
||||
enum ItemState : uint8_t
|
||||
{
|
||||
kToAdd = OT_SRP_CLIENT_ITEM_STATE_TO_ADD, ///< Item to be added/registered.
|
||||
kAdding = OT_SRP_CLIENT_ITEM_STATE_ADDING, ///< Item is being added/registered.
|
||||
kToRefresh = OT_SRP_CLIENT_ITEM_STATE_TO_REFRESH, ///< Item to be refreshed (renew lease).
|
||||
kRefreshing = OT_SRP_CLIENT_ITEM_STATE_REFRESHING, ///< Item is being refreshed.
|
||||
kToRemove = OT_SRP_CLIENT_ITEM_STATE_TO_REMOVE, ///< Item to be removed.
|
||||
kRemoving = OT_SRP_CLIENT_ITEM_STATE_REMOVING, ///< Item is being removed.
|
||||
kRegistered = OT_SRP_CLIENT_ITEM_STATE_REGISTERED, ///< Item is registered with server.
|
||||
kRemoved = OT_SRP_CLIENT_ITEM_STATE_REMOVED, ///< Item is removed.
|
||||
};
|
||||
|
||||
/**
|
||||
* This function pointer type defines the callback used by SRP client to notify user of a changes/events/errors.
|
||||
*
|
||||
* Please see `otSrpClientCallback` for more details.
|
||||
*
|
||||
*/
|
||||
typedef otSrpClientCallback Callback;
|
||||
|
||||
/**
|
||||
* This type represents a TXT record entry representing a key/value pair (RFC 6763 - section 6.3).
|
||||
*
|
||||
*/
|
||||
class TxtEntry : public otSrpTxtEntry
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method encodes and appends the `TxtEntry` to a message.
|
||||
*
|
||||
* @param[in] aMessage The message to append to.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Entry was appended successfully to @p aMessage.
|
||||
* @retval OT_ERROR_INVALID_ARGS The `TxEntry` info is not valid.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
otError AppendTo(Message &aMessage) const;
|
||||
|
||||
/**
|
||||
* This static method appends an array of `TxtEntry` items to a message.
|
||||
*
|
||||
* @param[in] aEntries A pointer to array of `TxtEntry` items.
|
||||
* @param[in] aNumEntries The number of entries in @p aEntries array.
|
||||
* @param[in] aMessage The message to append to.
|
||||
*
|
||||
*
|
||||
* @retval OT_ERROR_NONE Entries appended successfully to @p aMessage.
|
||||
* @retval OT_ERROR_INVALID_ARGS The `TxEntry` info is not valid.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
static otError AppendEntries(const TxtEntry *aEntries, uint8_t aNumEntries, Message &aMessage);
|
||||
|
||||
private:
|
||||
enum : char
|
||||
{
|
||||
kKeyValueSeparator = '=',
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
kMinKeyLength = 1,
|
||||
kMaxKeyLength = 9,
|
||||
kMaxKeyValueEncodedSize = 255,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents an SRP client host info.
|
||||
*
|
||||
*/
|
||||
class HostInfo : public otSrpClientHostInfo, public Clearable<HostInfo>
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method initializes the `HostInfo` object.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
/**
|
||||
* This method clears the `HostInfo` object.
|
||||
*
|
||||
*/
|
||||
void Clear(void);
|
||||
|
||||
/**
|
||||
* This method gets the host name (label) string.
|
||||
*
|
||||
* @returns The host name (label) string, or nullptr if not yet set.
|
||||
*
|
||||
*/
|
||||
const char *GetName(void) const { return mName; }
|
||||
|
||||
/**
|
||||
* This method gets the number of host IPv6 addresses.
|
||||
*
|
||||
* @returns The number of host IPv6 addresses.
|
||||
*
|
||||
*/
|
||||
uint8_t GetNumAddresses(void) const { return mNumAddresses; }
|
||||
|
||||
/**
|
||||
* This method gets the host IPv6 address at a given index.
|
||||
*
|
||||
* @param[in] aIndex The index to get (MUST be smaller than `GetNumAddresses()`).
|
||||
*
|
||||
* @returns The host IPv6 address at index @p aIndex.
|
||||
*
|
||||
*/
|
||||
const Ip6::Address &GetAddress(uint8_t aIndex) const
|
||||
{
|
||||
return static_cast<const Ip6::Address &>(mAddresses[aIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the state of `HostInfo`.
|
||||
*
|
||||
* @returns The `HostInfo` state.
|
||||
*
|
||||
*/
|
||||
ItemState GetState(void) const { return static_cast<ItemState>(mState); }
|
||||
|
||||
private:
|
||||
void SetName(const char *aName) { mName = aName; }
|
||||
void SetState(ItemState aState);
|
||||
void SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents an SRP client service.
|
||||
*
|
||||
*/
|
||||
class Service : public otSrpClientService, public LinkedListEntry<Service>
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method initializes and validates the `Service` object and its fields.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully initialized and validated the `Service` object.
|
||||
* @retval OT_ERROR_INVALID_ARGS The info in `Service` object is not valid (e.g. null name or bad `TxtEntry`).
|
||||
*
|
||||
*/
|
||||
otError Init(void);
|
||||
|
||||
/**
|
||||
* This method gets the service name labels string.
|
||||
*
|
||||
* @returns The service name label string (e.g., "_chip._udp", not the full domain name).
|
||||
*
|
||||
*/
|
||||
const char *GetName(void) const { return mName; }
|
||||
|
||||
/**
|
||||
* This method gets the service instance name label (not the full name).
|
||||
*
|
||||
* @returns The service instance name label string.
|
||||
*
|
||||
*/
|
||||
const char *GetInstanceName(void) const { return mInstanceName; }
|
||||
|
||||
/**
|
||||
* This method gets the service port number.
|
||||
*
|
||||
* @returns The service port number.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPort(void) const { return mPort; }
|
||||
|
||||
/**
|
||||
* This method gets the service priority.
|
||||
*
|
||||
* @returns The service priority.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPriority(void) const { return mPriority; }
|
||||
|
||||
/**
|
||||
* This method gets the service weight.
|
||||
*
|
||||
* @returns The service weight.
|
||||
*
|
||||
*/
|
||||
uint16_t GetWeight(void) const { return mWeight; }
|
||||
|
||||
/**
|
||||
* This method gets the array of service TXT entries.
|
||||
*
|
||||
* @returns A pointer to an array of service TXT entries.
|
||||
*
|
||||
*/
|
||||
const TxtEntry *GetTxtEntries(void) const { return static_cast<const TxtEntry *>(mTxtEntries); }
|
||||
|
||||
/**
|
||||
* This method gets the number of entries in the service TXT entry array.
|
||||
*
|
||||
* @returns The number of entries in the service TXT entry array.
|
||||
*
|
||||
*/
|
||||
uint8_t GetNumTxtEntries(void) const { return mNumTxtEntries; }
|
||||
|
||||
/**
|
||||
* This method get the state of service.
|
||||
*
|
||||
* @returns The service state.
|
||||
*
|
||||
*/
|
||||
ItemState GetState(void) const { return static_cast<ItemState>(mState); }
|
||||
|
||||
private:
|
||||
void SetState(ItemState aState);
|
||||
TimeMilli GetLeaseRenewTime(void) const { return TimeMilli(mData); }
|
||||
void SetLeaseRenewTime(TimeMilli aTime) { mData = aTime.GetValue(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the SRP `Client` object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit Client(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method starts the SRP client operation.
|
||||
*
|
||||
* SRP client will prepare and send "SRP Update" message to the SRP server once all the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - The SRP client is started - `Start()` is called
|
||||
* - Host name is set - `SetHostName()` is called.
|
||||
* - At least one host IPv6 address is set - `SetHostAddresses()` is called.
|
||||
* - At least one service is added - `AddService()` is called.
|
||||
*
|
||||
* It does not matter in which order these methods are called. When all conditions are met, the SRP client will
|
||||
* wait for a short delay before preparing an "SRP Update" message and sending it to server. This delay allows for
|
||||
* user to add multiple services and/or IPv6 addresses before the first SRP Update message is sent (ensuring a
|
||||
* single SRP Update is sent containing all the info).
|
||||
*
|
||||
* @param[in] aServerSockAddr The socket address (IPv6 address and port number) of the SRP server.
|
||||
* @param[in] aCallback The callback to notify of events and changes. Can be nullptr if not needed.
|
||||
* @param[in] aContext An arbitrary context used with @p aCallback.
|
||||
*
|
||||
* @retval OT_ERROR_NONE SRP client operation started successfully or it is already running with same server
|
||||
* socket address and callback.
|
||||
* @retval OT_ERROR_BUSY SRP client is busy running with a different socket address and/or callback.
|
||||
* @retval OT_ERROR_FAILED Failed to open/connect the client's UDP socket.
|
||||
*
|
||||
*/
|
||||
otError Start(const Ip6::SockAddr &aServerSockAddr, Callback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method stops the SRP client operation.
|
||||
*
|
||||
* This method stops any further interactions with the SRP server. Note that it does not remove or clear host info
|
||||
* and/or list of services. It marks all services to be added/removed again once the client is started again.
|
||||
*
|
||||
*/
|
||||
void Stop(void);
|
||||
|
||||
/**
|
||||
* This method gets the lease interval used in SRP update requests.
|
||||
*
|
||||
* Note that this is lease duration that would be requested by the SRP client. Server may choose to accept a
|
||||
* different lease interval.
|
||||
*
|
||||
* @returns The lease interval (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t GetLeaseInterval(void) const { return mLeaseInterval; }
|
||||
|
||||
/**
|
||||
* This method sets the lease interval used in SRP update requests.
|
||||
*
|
||||
* Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
|
||||
* It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
|
||||
*
|
||||
* @param[in] The lease interval (in seconds). If zero, the default value `kDefaultLease` would be used.
|
||||
*
|
||||
*/
|
||||
void SetLeaseInterval(uint32_t aInterval) { mLeaseInterval = GetBoundedLeaseInterval(aInterval, kDefaultLease); }
|
||||
|
||||
/**
|
||||
* This method gets the key lease interval used in SRP update requests.
|
||||
*
|
||||
* @returns The key lease interval (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t GetKeyLeaseInterval(void) const { return mKeyLeaseInterval; }
|
||||
|
||||
/**
|
||||
* This method sets the key lease interval used in SRP update requests.
|
||||
*
|
||||
* Changing the lease interval does not impact the accepted lease interval of already registered services/host-info.
|
||||
* It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
|
||||
*
|
||||
* @param[in] The key lease interval (in seconds). If zero, the default value `kDefaultKeyLease` would be used.
|
||||
*
|
||||
*/
|
||||
void SetKeyLeaseInterval(uint32_t aInterval)
|
||||
{
|
||||
mKeyLeaseInterval = GetBoundedLeaseInterval(aInterval, kDefaultKeyLease);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the host info.
|
||||
*
|
||||
* @returns A reference to host info structure.
|
||||
*
|
||||
*/
|
||||
const HostInfo &GetHostInfo(void) const { return mHostInfo; }
|
||||
|
||||
/**
|
||||
* This function sets the host name label.
|
||||
*
|
||||
* After a successful call to this function, `Callback` will be called to report the status of host info
|
||||
* registration with SRP server.
|
||||
*
|
||||
* The host name can be set before client is started or after start but before host info is registered with server
|
||||
* (host info should be in either `kToAdd` or `kRemoved`).
|
||||
*
|
||||
* @param[in] aName A pointer to host name label string (MUST NOT be NULL). Pointer the string buffer MUST
|
||||
* persist and remain valid and constant after return from this function.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host name label was set successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aName is NULL.
|
||||
* @retval OT_ERROR_INVALID_STATE The host name is already set and registered with the server.
|
||||
*
|
||||
*/
|
||||
otError SetHostName(const char *aName);
|
||||
|
||||
/**
|
||||
* This method sets/updates the list of host IPv6 address.
|
||||
*
|
||||
* Host IPv6 addresses can be set/changed before start or even during operation of SRP client (e.g. to add/remove
|
||||
* or change a previously registered host address), except when the host info is being removed (client is busy
|
||||
* handling a remove request from an earlier call to `RemoveHostAndServices()` and host info still being in either
|
||||
* `kStateToRemove` or `kStateRemoving` states).
|
||||
*
|
||||
* After a successful call to this method, `Callback` will be called to report the status of the address
|
||||
* registration with SRP server.
|
||||
*
|
||||
* @param[in] aAddresses A pointer to the an array containing the host IPv6 addresses.
|
||||
* @param[in] aNumAddresses The number of addresses in the @p aAddresses array.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host IPv6 address list change started successfully. The `Callback`
|
||||
* will be called to report the status of registering addresses with server.
|
||||
* @retval OT_ERROR_INVALID_ARGS The address list is invalid (e.g., must contain at least one address).
|
||||
* @retval OT_ERROR_INVALID_STATE Host is being removed and therefore cannot change host address.
|
||||
*
|
||||
*/
|
||||
otError SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
|
||||
|
||||
/**
|
||||
* This method adds a service to be registered with server.
|
||||
*
|
||||
* After a successful call to this method, `Callback` will be called to report the status of the service
|
||||
* addition/registration with SRP server.
|
||||
*
|
||||
* @param[in] aService A `Service` to add (the instance must persist and remain unchanged after
|
||||
* successful return from this method).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The addition of service started successfully. The `Callback` will be
|
||||
* called to report the status.
|
||||
* @retval OT_ERROR_ALREADY The same service is already in the list.
|
||||
* @retval OT_ERROR_INVALID_ARGS The service structure is invalid (e.g., bad service name or `TxEntry`).
|
||||
*
|
||||
*/
|
||||
otError AddService(Service &aService);
|
||||
|
||||
/**
|
||||
* This method removes a service to be unregistered with server.
|
||||
*
|
||||
* @param[in] aService A `Service` to remove (the instance must persist and remain unchanged after
|
||||
* successful return from this method).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The removal of service started successfully. The `Callback` will be called to
|
||||
* report the status.
|
||||
* @retval OT_ERROR_NOT_FOUND The service could not be found in the list.
|
||||
*
|
||||
*/
|
||||
|
||||
otError RemoveService(Service &aService);
|
||||
|
||||
/**
|
||||
* This method gets the list of services being managed by client.
|
||||
*
|
||||
* @returns The list of services.
|
||||
*
|
||||
*/
|
||||
const LinkedList<Service> &GetServices(void) const { return mServices; }
|
||||
|
||||
/**
|
||||
* This method starts the remove process of the host info and all services.
|
||||
*
|
||||
* After retuning from this method, `Callback` will be called to report the status of remove request with
|
||||
* SRP server.
|
||||
*
|
||||
* If the host info is to be permanently removed from server, @p aRemoveKeyLease should be set to `true` which
|
||||
* removes the key lease associated with host on server. Otherwise, the key lease record is kept as before, which
|
||||
* ensures that the server holds the host name in reserve for when the client once again able to provide and
|
||||
* register its service(s).
|
||||
*
|
||||
* @param[in] aRemoveKeyLease A boolean indicating whether or not the host key lease should also be removed.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The removal of host and services started successfully. The `Callback` will be called
|
||||
* to report the status.
|
||||
* @retval OT_ERROR_ALREADY The host is already removed.
|
||||
*
|
||||
*/
|
||||
otError RemoveHostAndServices(bool aShouldRemoveKeyLease);
|
||||
|
||||
/**
|
||||
* This method clears all host info and all the services.
|
||||
*
|
||||
* Unlike `RemoveHostAndServices()` which sends an update message to server to remove/unregister all the info, this
|
||||
* method clears all the info immediately without any interaction with server.
|
||||
*
|
||||
*/
|
||||
void ClearHostAndServices(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
/**
|
||||
* This method gets the domain name being used by SRP client.
|
||||
*
|
||||
* If domain name is not set, "default.service.arpa" will be used.
|
||||
*
|
||||
* @returns The domain name string.
|
||||
*
|
||||
*/
|
||||
const char *GetDomainName(void) const { return mDomainName; }
|
||||
|
||||
/**
|
||||
* This method sets the domain name to be used by SRP client.
|
||||
*
|
||||
* This is an optional method. If not set "default.service.arpa" will be used.
|
||||
*
|
||||
* The domain name can be set before client is started or after start but before host info is registered with server
|
||||
* (host info should be in either `kToAdd` or `kToRemove`).
|
||||
*
|
||||
* @param[in] aName A pointer to the domain name string. If NULL sets it to default "default.service.arpa".
|
||||
*
|
||||
* @retval OT_ERROR_NONE The domain name label was set successfully.
|
||||
* @retval OT_ERROR_INVALID_STATE The host info is already registered with server.
|
||||
*
|
||||
*/
|
||||
otError SetDomainName(const char *aName);
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE
|
||||
|
||||
/**
|
||||
* This static method converts a `ItemState` to a string.
|
||||
*
|
||||
* @param[in] aState An `ItemState`.
|
||||
*
|
||||
* @returns A string representation of @p aState.
|
||||
*
|
||||
*/
|
||||
static const char *ItemStateToString(ItemState aState);
|
||||
|
||||
private:
|
||||
enum : uint8_t
|
||||
{
|
||||
kFastPollsAfterUpdateTx = 11, // Number of fast data polls after SRP Update tx (11x 188ms = ~2 seconds)
|
||||
};
|
||||
|
||||
enum : uint16_t
|
||||
{
|
||||
kUdpPayloadSize = Ip6::Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header), // Max UDP payload size
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
// -------------------------------
|
||||
// Lease related constants
|
||||
|
||||
kDefaultLease = OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_LEASE, // in seconds.
|
||||
kDefaultKeyLease = OPENTHREAD_CONFIG_SRP_CLIENT_DEFAULT_KEY_LEASE, // in seconds.
|
||||
|
||||
// The guard interval determines how much earlier (relative to
|
||||
// the lease expiration time) the client will send an update
|
||||
// to renew the lease.
|
||||
kLeaseRenewGuardInterval = OPENTHREAD_CONFIG_SRP_CLIENT_LEASE_RENEW_GUARD_INTERVAL, // in seconds.
|
||||
|
||||
// Max allowed lease time to avoid timer roll-over (~24.8 days).
|
||||
kMaxLease = (Timer::kMaxDelay / 1000) - 1,
|
||||
|
||||
// Opportunistic early refresh: When sending an SRP update, the
|
||||
// services that are not yet expired but are close, are allowed
|
||||
// to refresh early and are included in the SRP update. This
|
||||
// helps place more services on the same lease refresh schedule
|
||||
// reducing number of messages sent to the SRP server. The
|
||||
// "early lease renewal interval" is used to determine if a
|
||||
// service can renew early. The interval is calculated by
|
||||
// multiplying the accepted lease interval by the"early lease
|
||||
// renewal factor" which is given as a fraction (numerator and
|
||||
// denominator).
|
||||
//
|
||||
// If the factor is set to zero (numerator=0, denominator=1),
|
||||
// the opportunistic early refresh behavior is disabled. If
|
||||
// denominator is set to zero (the factor is set to infinity),
|
||||
// then all services (including previously registered ones)
|
||||
// are always included in SRP update message.
|
||||
|
||||
kEarlyLeaseRenewFactorNumerator = OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_NUMERATOR,
|
||||
kEarlyLeaseRenewFactorDenominator = OPENTHREAD_CONFIG_SRP_CLIENT_EARLY_LEASE_RENEW_FACTOR_DENOMINATOR,
|
||||
|
||||
// -------------------------------
|
||||
// When there is a change (e.g., a new service is added/removed)
|
||||
// that requires an update, the SRP client will wait for a short
|
||||
// delay as specified by `kUpdateTxDelay` before sending an SRP
|
||||
// update to server. This allows the user to provide more change
|
||||
// that are then all sent in same update message.
|
||||
kUpdateTxDelay = OPENTHREAD_CONFIG_SRP_CLIENT_UPDATE_TX_DELAY, // in msec.
|
||||
|
||||
// -------------------------------
|
||||
// Retry related constants
|
||||
//
|
||||
// If the preparation or transmission of an SRP update message
|
||||
// fails (e.g., no buffer to allocate the message), SRP client
|
||||
// will retry after a short interval `kTxFailureRetryInterval`
|
||||
// up to `kMaxTxFailureRetries` attempts. After this, the retry
|
||||
// wait interval will be used (which keeps growing on each failure
|
||||
// - please see bellow).
|
||||
//
|
||||
// If the update message is sent successfully but there is no
|
||||
// response from server or if server rejects the update, the
|
||||
// client will retransmit the update message after some wait
|
||||
// interval. The wait interval starts from the minimum value and
|
||||
// is increased by the growth factor on back-to-back failures up
|
||||
// to the max value. The growth factor is given as a fraction
|
||||
// (e.g., for 1.5, we can use 15 as the numerator and 10 as the
|
||||
// denominator). A random jitter is added to the retry interval.
|
||||
// If the current wait interval value is smaller than the jitter
|
||||
// interval, then wait interval value itself is used as the
|
||||
// jitter value. For example, with jitter interval of 2 seconds
|
||||
// if the current retry interval is 800ms, then a random wait
|
||||
// interval in [0,2*800] ms will be used.
|
||||
|
||||
kTxFailureRetryInterval = 250, // in ms
|
||||
kMaxTxFailureRetries = 8, // num of quick retries after tx failure
|
||||
kMinRetryWaitInterval = OPENTHREAD_CONFIG_SRP_CLIENT_MIN_RETRY_WAIT_INTERVAL, // in ms
|
||||
kMaxRetryWaitInterval = OPENTHREAD_CONFIG_SRP_CLIENT_MAX_RETRY_WAIT_INTERVAL, // in ms
|
||||
kRetryIntervalGrowthFactorNumerator = OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_NUMERATOR,
|
||||
kRetryIntervalGrowthFactorDenominator = OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_INTERVAL_GROWTH_FACTOR_DENOMINATOR,
|
||||
};
|
||||
|
||||
enum : uint16_t
|
||||
{
|
||||
kTxFailureRetryJitter = 10, // in ms
|
||||
kRetryIntervalJitter = OPENTHREAD_CONFIG_SRP_CLIENT_RETRY_WAIT_INTERVAL_JITTER, // in ms
|
||||
};
|
||||
|
||||
static_assert(kDefaultLease <= static_cast<uint32_t>(kMaxLease), "kDefaultLease is larger than max");
|
||||
static_assert(kDefaultKeyLease <= static_cast<uint32_t>(kMaxLease), "kDefaultKeyLease is larger than max");
|
||||
|
||||
enum State : uint8_t
|
||||
{
|
||||
kStateStopped, // Client is stopped.
|
||||
kStatePaused, // Client is paused (due to device being detached).
|
||||
kStateToUpdate, // Waiting to send SRP update
|
||||
kStateUpdating, // SRP update is sent, waiting for response from server.
|
||||
kStateUpdated, // SRP update response received from server.
|
||||
kStateToRetry, // SRP update tx failed, waiting to retry.
|
||||
};
|
||||
|
||||
struct Info : public Clearable<Info>
|
||||
{
|
||||
enum : uint16_t
|
||||
{
|
||||
kUnknownOffset = 0, // Unknown offset value (used when offset is not yet set).
|
||||
};
|
||||
|
||||
uint16_t mDomainNameOffset; // Offset of domain name serialization
|
||||
uint16_t mHostNameOffset; // Offset of host name serialization.
|
||||
uint16_t mRecordCount; // Number of resource records in Update section.
|
||||
Crypto::Ecdsa::P256::KeyPair mKeyPair; // The ECDSA key pair.
|
||||
};
|
||||
|
||||
void Resume(void);
|
||||
void Pause(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
void UpdateServiceStateToRemove(Service &aService);
|
||||
State GetState(void) const { return mState; }
|
||||
void SetState(State aState);
|
||||
void ChangeHostAndServiceStates(const ItemState *aNewStates);
|
||||
void InvokeCallback(otError aError) const;
|
||||
void InvokeCallback(otError aError, const HostInfo &aHostInfo, const Service *aRemovedServices) const;
|
||||
void ClearHostInfoAndServices(void);
|
||||
void HandleHostInfoOrServiceChange(void);
|
||||
void SendUpdate(void);
|
||||
otError PrepareUpdateMessage(Message &aMessage);
|
||||
otError ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||
otError AppendServiceInstructions(Service &aService, Message &aMessage, Info &aInfo);
|
||||
otError AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const;
|
||||
otError AppendDeleteAllRrsets(Message &aMessage) const;
|
||||
otError AppendHostName(Message &aMessage, Info &aInfo, bool aDoNotCompress = false) const;
|
||||
otError AppendUpdateLeaseOptRecord(Message &aMessage) const;
|
||||
otError AppendSignature(Message &aMessage, Info &aInfo);
|
||||
void UpdateRecordLengthInMessage(Dns::ResourceRecord &aRecord, uint16_t aOffset, Message &aMessage) const;
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void ProcessResponse(Message &aMessage);
|
||||
void HandleUpdateDone(void);
|
||||
void GetRemovedServices(LinkedList<Service> &aRemovedServices);
|
||||
static otError ReadResourceRecord(const Message &aMessage, uint16_t &aOffset, Dns::ResourceRecord &aRecord);
|
||||
otError ProcessOptRecord(const Message &aMessage, uint16_t aOffset, const Dns::OptRecord &aOptRecord);
|
||||
void UpdateState(void);
|
||||
uint32_t GetRetryWaitInterval(void) const { return mRetryWaitInterval; }
|
||||
void ResetRetryWaitInterval(void) { mRetryWaitInterval = kMinRetryWaitInterval; }
|
||||
void GrowRetryWaitInterval(void);
|
||||
uint32_t GetBoundedLeaseInterval(uint32_t aInterval, uint32_t aDefaultInterval) const;
|
||||
bool ShouldRenewEarly(const Service &aService) const;
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_SRP == 1)
|
||||
static const char *StateToString(State aState);
|
||||
void LogRetryWaitInterval(void) const;
|
||||
#else
|
||||
void LogRetryWaitInterval(void) const {}
|
||||
#endif
|
||||
|
||||
static const char kDefaultDomainName[];
|
||||
|
||||
static_assert(kMaxTxFailureRetries < 128, "kMaxTxFailureRetries exceed the range of mTxFailureRetryCount (7-bit)");
|
||||
|
||||
State mState;
|
||||
uint8_t mTxFailureRetryCount : 7;
|
||||
bool mShouldRemoveKeyLease : 1;
|
||||
|
||||
uint16_t mUpdateMessageId;
|
||||
uint32_t mRetryWaitInterval;
|
||||
|
||||
TimeMilli mLeaseRenewTime;
|
||||
uint32_t mAcceptedLeaseInterval;
|
||||
uint32_t mLeaseInterval;
|
||||
uint32_t mKeyLeaseInterval;
|
||||
|
||||
Ip6::Udp::Socket mSocket;
|
||||
|
||||
Callback mCallback;
|
||||
void * mCallbackContext;
|
||||
const char * mDomainName;
|
||||
HostInfo mHostInfo;
|
||||
LinkedList<Service> mServices;
|
||||
TimerMilli mTimer;
|
||||
};
|
||||
|
||||
} // namespace Srp
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
#endif // SRP_CLIENT_HPP_
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "config/platform.h"
|
||||
#include "config/radio_link.h"
|
||||
#include "config/sntp_client.h"
|
||||
#include "config/srp_client.h"
|
||||
#include "config/time_sync.h"
|
||||
#include "config/tmf.h"
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
, mDnsClient(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
, mSrpClient(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
, mSntpClient(aInstance)
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "net/ip6_filter.hpp"
|
||||
#include "net/netif.hpp"
|
||||
#include "net/sntp_client.hpp"
|
||||
#include "net/srp_client.hpp"
|
||||
#include "thread/address_resolver.hpp"
|
||||
#include "thread/announce_begin_server.hpp"
|
||||
#include "thread/discover_scanner.hpp"
|
||||
@@ -196,10 +197,13 @@ private:
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
Dns::Client mDnsClient;
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
Srp::Client mSrpClient;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
Sntp::Client mSntpClient;
|
||||
#endif // OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
#endif
|
||||
MeshCoP::ActiveDataset mActiveDataset;
|
||||
MeshCoP::PendingDataset mPendingDataset;
|
||||
Ip6::Filter mIp6Filter;
|
||||
|
||||
@@ -470,6 +470,22 @@
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
*
|
||||
* Define to 1 to enable SRP Client support.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_CHANGE_ENABLE
|
||||
*
|
||||
* Define to 1 for the SRP client implementation to provides APIs to allow domain name to be set/changed.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_API_ENABLE 1
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
|
||||
|
||||
Reference in New Issue
Block a user