[net] SRP server implementation (#5986)

This PR includes the initial implementation of the SRP server
defined in https://tools.ietf.org/html/draft-ietf-dnssd-srp-07.

- SRP server Service TLV propagation: Includes only the 2-bytes
  dynamic listening port in the Server TLV.
- SRP request processing (parsing & validation)
- LEASE & KEY-LEASE management
- SIG(0) verification
- Interface for advertising proxy
- CLI commands for testing
- Support removing indivitual SRP service
This commit is contained in:
kangping
2021-01-22 13:19:21 -08:00
committed by Jonathan Hui
parent f3e987baa9
commit 1ec9fd525d
35 changed files with 3598 additions and 11 deletions
+3
View File
@@ -187,6 +187,7 @@ LOCAL_SRC_FILES := \
src/core/api/random_noncrypto_api.cpp \
src/core/api/server_api.cpp \
src/core/api/srp_client_api.cpp \
src/core/api/srp_server_api.cpp \
src/core/api/tasklet_api.cpp \
src/core/api/thread_api.cpp \
src/core/api/thread_ftd_api.cpp \
@@ -264,6 +265,7 @@ LOCAL_SRC_FILES := \
src/core/net/ip6_mpl.cpp \
src/core/net/netif.cpp \
src/core/net/srp_client.cpp \
src/core/net/srp_server.cpp \
src/core/net/udp6.cpp \
src/core/radio/radio.cpp \
src/core/radio/radio_callbacks.cpp \
@@ -421,6 +423,7 @@ LOCAL_SRC_FILES := \
src/cli/cli_joiner.cpp \
src/cli/cli_network_data.cpp \
src/cli/cli_srp_client.cpp \
src/cli/cli_srp_server.cpp \
src/cli/cli_uart.cpp \
src/cli/cli_udp.cpp \
$(NULL)
+5
View File
@@ -282,6 +282,11 @@ if(OT_SNTP_CLIENT)
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1")
endif()
option(OT_SRP_SERVER "enable SRP server")
if (OT_SRP_SERVER)
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_SRP_SERVER_ENABLE=1")
endif()
option(OT_TIME_SYNC "enable the time synchronization service feature")
if(OT_TIME_SYNC)
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1")
+3
View File
@@ -198,6 +198,9 @@ if (openthread_enable_core_config_args) {
# Enable SNTP Client support
openthread_config_sntp_client_enable = false
# Enable SRP Server support
openthread_config_srp_server_enable = false
# Enable the time synchronization service feature
openthread_config_time_sync_enable = false
+1
View File
@@ -57,6 +57,7 @@ This page lists the available common switches with description. Unless stated ot
| 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. |
| SRP_SERVER | OT_SRP_SERVER | Enable support for SRP server. |
| 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. |
+5
View File
@@ -77,6 +77,7 @@ SETTINGS_RAM ?= 0
SLAAC ?= 1
SNTP_CLIENT ?= 0
SRP_CLIENT ?= 0
SRP_SERVER ?= 0
THREAD_VERSION ?= 1.1
TIME_SYNC ?= 0
UDP_FORWARD ?= 0
@@ -273,6 +274,10 @@ ifeq ($(SRP_CLIENT),1)
COMMONCFLAGS += -DOPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1
endif
ifeq ($(SRP_SERVER),1)
COMMONCFLAGS += -DOPENTHREAD_CONFIG_SRP_SERVER_ENABLE=1
endif
ifeq ($(THREAD_VERSION),1.1)
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
else ifeq ($(THREAD_VERSION),1.2)
+1
View File
@@ -75,6 +75,7 @@ openthread_headers = \
openthread/server.h \
openthread/sntp.h \
openthread/srp_client.h \
openthread/srp_server.h \
openthread/tasklet.h \
openthread/thread.h \
openthread/thread_ftd.h \
+1
View File
@@ -115,6 +115,7 @@ source_set("openthread") {
"server.h",
"sntp.h",
"srp_client.h",
"srp_server.h",
"tasklet.h",
"thread.h",
"thread_ftd.h",
+335
View File
@@ -0,0 +1,335 @@
/*
* 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 API for server of the Service Registration Protocol (SRP).
*/
#ifndef OPENTHREAD_SRP_SERVER_H_
#define OPENTHREAD_SRP_SERVER_H_
#include <stdint.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup api-srp
*
* @brief
* This module includes functions of the Service Registration Protocol.
*
* @{
*
*/
/**
* This opaque type represents a SRP service host.
*
*/
typedef void otSrpServerHost;
/**
* This opaque type represents a SRP service.
*
*/
typedef void otSrpServerService;
/**
* This method returns the domain authorized to the SRP server.
*
* If the domain if not set by SetDomain, "default.service.arpa." will be returned.
* A trailing dot is always appended even if the domain is set without it.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to the dot-joined domain string.
*
*/
const char *otSrpServerGetDomain(otInstance *aInstance);
/**
* This method sets the domain on the SRP server.
*
* A trailing dot will be appended to @p aDomain if it is not already there.
* This method should only be called before the SRP server is enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aDomain The domain to be set. MUST NOT be nullptr.
*
* @retval OT_ERROR_NONE Successfully set the domain to @p aDomain.
* @retval OT_ERROR_INVALID_STATE The SRP server is already enabled and the Domain cannot be changed.
* @retval OT_ERROR_INVALID_ARGS The argument @p aDomain is not a valid DNS domain name.
* @retval OT_ERROR_NO_BUFS There is no memory to store content of @p aDomain.
*
*/
otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain);
/**
* This method enables/disables the SRP server.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aEnabled A boolean to enable/disable the SRP server.
*
*/
void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled);
/**
* This method sets LEASE & KEY-LEASE range that is acceptable by the SRP server.
*
* When a non-zero LEASE time is requested from a client, the granted value will be
* limited in range [aMinLease, aMaxLease]; and a non-zero KEY-LEASE will be granted
* in range [aMinKeyLease, aMaxKeyLease]. For zero LEASE or KEY-LEASE time, zero will
* be granted.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aMinLease The minimum LEASE interval in seconds.
* @param[in] aMaxLease The maximum LEASE interval in seconds.
* @param[in] aMinKeyLease The minimum KEY-LEASE interval in seconds.
* @param[in] aMaxKeyLease The maximum KEY-LEASE interval in seconds.
*
* @retval OT_ERROR_NONE Successfully set the LEASE and KEY-LEASE ranges.
* @retval OT_ERROR_INVALID_ARGS The LEASE or KEY-LEASE range is not valid.
*
*/
otError otSrpServerSetLeaseRange(otInstance *aInstance,
uint32_t aMinLease,
uint32_t aMaxLease,
uint32_t aMinKeyLease,
uint32_t aMaxKeyLease);
/**
* This method handles SRP service updates.
*
* This function is called by the SRP server to notify that a SRP host and possibly SRP services
* are being updated. It is important that the SRP updates are not commited until the handler
* returns the result by calling otSrpServerHandleServiceUpdateResult or times out after @p aTimeout.
*
* A SRP service observer should always call otSrpServerHandleServiceUpdateResult with error code
* OT_ERROR_NONE immediately after receiving the update events.
*
* A more generic handler may perform validations on the SRP host/services and rejects the SRP updates
* if any validation fails. For example, an Advertising Proxy should advertise (or remove) the host and
* services on a multicast-capable link and returns specific error code if any failure occurs.
*
* @param[in] aHost A pointer to the otSrpServerHost object which contains the SRP updates.
* The pointer should be passed back to otSrpServerHandleServiceUpdateResult, but
* the content MUST not be accessed after this method returns. The handler
* should publish/un-publish the host and each service points to this host
* with below rules:
* 1. If the host is not deleted (indicated by `otSrpServerHostIsDeleted`),
* then it should be published or updated with mDNS. Otherwise, the host
* should be un-published (remove AAAA RRs).
* 2. For each service points to this host, it must be un-published if the host
* is to be un-published. Otherwise, the handler should publish or update the
* service when it is not deleted (indicated by `otSrpServerServiceIsDeleted`)
* and un-publish it when deleted.
* @param[in] aTimeout The maximum time in milliseconds for the handler to process the service event.
* @param[in] aContext A pointer to application-specific context.
*
* @sa otSrpServerSetServiceUpdateHandler
* @sa otSrpServerHandleServiceUpdateResult
*
*/
typedef void (*otSrpServerServiceUpdateHandler)(const otSrpServerHost *aHost, uint32_t aTimeout, void *aContext);
/**
* This method sets the SRP service updates handler on SRP server.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aServiceHandler A pointer to a service handler. Use NULL to remove the handler.
* @param[in] aContext A pointer to arbitrary context information.
* May be NULL if not used.
*
*/
void otSrpServerSetServiceUpdateHandler(otInstance * aInstance,
otSrpServerServiceUpdateHandler aServiceHandler,
void * aContext);
/**
* This method reports the result of processing a SRP update to the SRP server.
*
* The Service Update Handler should call this function to return the result of its
* processing of a SRP update.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aHost A pointer to the Host object which represents a SRP update.
* @param[in] aError An error to be returned to the SRP server. Use OT_ERROR_DUPLICATED
* to represent DNS name conflicts.
*
*/
void otSrpServerHandleServiceUpdateResult(otInstance *aInstance, const otSrpServerHost *aHost, otError aError);
/**
* This method returns the next registered host on the SRP server.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aHost A pointer to current host; use NULL to get the first host.
*
* @returns A pointer to the registered host. NULL, if no more hosts can be found.
*
*/
const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrpServerHost *aHost);
/**
* This method tells if the SRP service host has been deleted.
*
* A SRP service host can be deleted but retains its name for future uses.
* In this case, the host instance is not removed from the SRP server/registry.
*
* @param[in] aHost A pointer to the SRP service host.
*
* @returns TRUE if the host has been deleted, FALSE if not.
*
*/
bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost);
/**
* This method returns the full name of the host.
*
* @param[in] aHost A pointer to the SRP service host.
*
* @returns A pointer to the null-terminated host name string.
*
*/
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost);
/**
* This method returns the addresses of given host.
*
* @param[in] aHost A pointer to the SRP service host.
* @param[out] aAddressesNum A pointer to where we should output the number of the addresses to.
*
* @returns A pointer to the array of IPv6 Address.
*
*/
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum);
/**
* This method returns the next service of given host.
*
* @param[in] aHost A pointer to the SRP service host.
* @param[in] aService A pointer to current SRP service instance; use NULL to get the first service.
*
* @returns A pointer to the next service or NULL if there is no more services.
*
*/
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost * aHost,
const otSrpServerService *aService);
/**
* This method tells if the SRP service has been deleted.
*
* A SRP service can be deleted but retains its name for future uses.
* In this case, the service instance is not removed from the SRP server/registry.
* It is guaranteed that all services are deleted if the host is deleted.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns TRUE if the service has been deleted, FALSE if not.
*
*/
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService);
/**
* This method returns the full name of the service.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns A pointer to the null-terminated service name string.
*
*/
const char *otSrpServerServiceGetFullName(const otSrpServerService *aService);
/**
* This method returns the port of the service instance.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns The port of the service.
*
*/
uint16_t otSrpServerServiceGetPort(const otSrpServerService *aService);
/**
* This method returns the weight of the service instance.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns The weight of the service.
*
*/
uint16_t otSrpServerServiceGetWeight(const otSrpServerService *aService);
/**
* This method returns the priority of the service instance.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns The priority of the service.
*
*/
uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService);
/**
* This method returns the TXT data of the service instance.
*
* @param[in] aService A pointer to the SRP service.
* @param[out] aTxtLength A pointer to the output of the TXT data length.
*
* @returns A pointer to the standard TXT data with format described by RFC 6763.
*
*/
const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService, uint16_t *aTxtLength);
/**
* This method returns the host which the service instance reside on.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns A pointer to the host instance.
*
*/
const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aService);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_SRP_SERVER_H_
+1
View File
@@ -74,6 +74,7 @@ do_scan_build()
"-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1"
"-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1"
"-DOPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1"
"-DOPENTHREAD_CONFIG_SRP_SERVER_ENABLE=1"
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
+1
View File
@@ -127,6 +127,7 @@ size_nrf52840_version()
"SLAAC=1"
"SNTP_CLIENT=1"
"SRP_CLIENT=1"
"SRP_SERVER=1"
"TIME_SYNC=1"
"UDP_FORWARD=1"
)
+15 -1
View File
@@ -52,7 +52,15 @@ readonly OT_COREDUMP_DIR="${PWD}/ot-core-dump"
build_simulation()
{
local version="$1"
local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON" "-DOT_REFERENCE_DEVICE=ON")
local options=(
"-DOT_MESSAGE_USE_HEAP=ON"
"-DOT_THREAD_VERSION=${version}"
"-DBUILD_TESTING=ON"
"-DOT_REFERENCE_DEVICE=ON"
"-DOT_SRP_SERVER=ON"
"-DOT_SRP_CLIENT=ON"
"-DOT_SERVICE=ON"
"-DOT_ECDSA=ON")
if [[ ${version} == "1.2" ]]; then
options+=("-DOT_DUA=ON")
@@ -192,6 +200,8 @@ do_cert()
fi
fi
export PYTHONPATH=tests/scripts/thread-cert
[[ ! -d tmp ]] || rm -rvf tmp
PYTHONUNBUFFERED=1 "$@"
}
@@ -238,6 +248,10 @@ do_build_otbr_docker()
local otbr_options="-DOT_SLAAC=ON -DOT_DUA=ON -DOT_MLR=ON -DOT_COVERAGE=ON -DOTBR_REST=OFF -DOTBR_WEB=OFF"
local otbr_docker_image=${OTBR_DOCKER_IMAGE:-otbr-ot12-backbone-ci}
# Always enable SRP server for OTBR.
# TODO: enable SRP server inside OTBR after this PR merged.
otbr_options="${otbr_options} -DOT_SRP_SERVER=ON -DOT_SERVICE=ON -DOT_ECDSA=ON"
if [[ ${BORDER_ROUTING} == "1" ]]; then
otbr_options="${otbr_options} -DOT_BORDER_ROUTING=ON"
fi
+2
View File
@@ -47,6 +47,8 @@ openthread_cli_sources = [
"cli_network_data.hpp",
"cli_srp_client.cpp",
"cli_srp_client.hpp",
"cli_srp_server.cpp",
"cli_srp_server.hpp",
"cli_uart.cpp",
"cli_uart.hpp",
"cli_udp.cpp",
+1
View File
@@ -48,6 +48,7 @@ set(COMMON_SOURCES
cli_joiner.cpp
cli_network_data.cpp
cli_srp_client.cpp
cli_srp_server.cpp
cli_uart.cpp
cli_udp.cpp
)
+2
View File
@@ -159,6 +159,7 @@ SOURCES_COMMON = \
cli_joiner.cpp \
cli_network_data.cpp \
cli_srp_client.cpp \
cli_srp_server.cpp \
cli_uart.cpp \
cli_udp.cpp \
$(NULL)
@@ -182,6 +183,7 @@ noinst_HEADERS = \
cli_joiner.hpp \
cli_network_data.hpp \
cli_srp_client.hpp \
cli_srp_server.hpp \
cli_uart.hpp \
cli_udp.hpp \
x509_cert_key.hpp \
+120
View File
@@ -0,0 +1,120 @@
# OpenThread CLI - SRP Server
## Quick Start
See [README_SRP.md](README_SRP.md).
## Command List
- [help](#help)
- [disable](#disable)
- [domain](#domain)
- [enable](#enable)
- [host](#host)
- [lease](#lease)
- [service](#service)
## Command Details
### help
Usage: `srp server help`
Print SRP server help menu.
```bash
> srp server help
disable
domain
enable
help
host
lease
service
Done
```
### disable
Usage: `srp server disable`
Disable the SRP server.
```bash
> srp server disable
Done
```
### domain
Usage: `srp server domain [domain-name]`
Get the domain.
```bash
> srp server domain
default.service.arpa.
Done
```
Set the domain.
```bash
> srp server domain thread.service.arpa.
Done
```
### enable
Usage: `srp server enable`
Enable the SRP server.
```bash
> srp server enable
Done
```
### host
Usage: `srp server host`
Print information of all registered hosts.
```bash
> srp server host
srp-api-test-1.default.service.arpa.
deleted: false
addresses: [fdde:ad00:beef:0:0:ff:fe00:fc10]
srp-api-test-0.default.service.arpa.
deleted: false
addresses: [fdde:ad00:beef:0:0:ff:fe00:fc10]
Done
```
### srp server service
Usage: `srp server service`
Print information of all registered services.
```bash
> srp server service
srp-api-test-1._ipps._tcp.default.service.arpa.
deleted: false
port: 49152
priority: 0
weight: 0
TXT: 0130
host: srp-api-test-1.default.service.arpa.
addresses: [fdde:ad00:beef:0:0:ff:fe00:fc10]
srp-api-test-0._ipps._tcp.default.service.arpa.
deleted: false
port: 49152
priority: 0
weight: 0
TXT: 0130
host: srp-api-test-0.default.service.arpa.
addresses: [fdde:ad00:beef:0:0:ff:fe00:fc10]
Done
```
+20 -5
View File
@@ -143,6 +143,9 @@ Interpreter::Interpreter(Instance *aInstance)
#endif
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
, mSrpClient(*this)
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
, mSrpServer(*this)
#endif
, mInstance(aInstance)
{
@@ -178,9 +181,9 @@ void Interpreter::OutputResult(otError aError)
}
}
void Interpreter::OutputBytes(const uint8_t *aBytes, uint8_t aLength)
void Interpreter::OutputBytes(const uint8_t *aBytes, uint16_t aLength)
{
for (int i = 0; i < aLength; i++)
for (uint16_t i = 0; i < aLength; i++)
{
OutputFormat("%02x", aBytes[i]);
}
@@ -3872,29 +3875,41 @@ void Interpreter::HandleSntpResponse(uint64_t aTime, otError aResult)
}
#endif // OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
otError Interpreter::ProcessSrp(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgsLength == 0)
{
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
OutputLine("client");
// OutputLine("server");
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
OutputLine("server");
#endif
ExitNow();
}
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
if (strcmp(aArgs[0], "client") == 0)
{
ExitNow(error = mSrpClient.Process(aArgsLength - 1, aArgs + 1));
}
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
if (strcmp(aArgs[0], "server") == 0)
{
ExitNow(error = mSrpServer.Process(aArgsLength - 1, aArgs + 1));
}
#endif
error = OT_ERROR_INVALID_COMMAND;
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
otError Interpreter::ProcessState(uint8_t aArgsLength, char *aArgs[])
{
+9 -3
View File
@@ -51,6 +51,7 @@
#include "cli/cli_joiner.hpp"
#include "cli/cli_network_data.hpp"
#include "cli/cli_srp_client.hpp"
#include "cli/cli_srp_server.hpp"
#include "cli/cli_udp.hpp"
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
#include "cli/cli_coap.hpp"
@@ -88,6 +89,7 @@ class Interpreter
friend class Joiner;
friend class NetworkData;
friend class SrpClient;
friend class SrpServer;
friend class UdpExample;
public:
@@ -148,7 +150,7 @@ public:
* @param[in] aLength @p aBytes length.
*
*/
void OutputBytes(const uint8_t *aBytes, uint8_t aLength);
void OutputBytes(const uint8_t *aBytes, uint16_t aLength);
/**
* This method writes a number of bytes to the CLI console as a hex string.
@@ -496,7 +498,7 @@ private:
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
otError ProcessSntp(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
otError ProcessSrp(uint8_t aArgsLength, char *aArgs[]);
#endif
otError ProcessState(uint8_t aArgsLength, char *aArgs[]);
@@ -760,7 +762,7 @@ private:
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
{"sntp", &Interpreter::ProcessSntp},
#endif
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
{"srp", &Interpreter::ProcessSrp},
#endif
{"state", &Interpreter::ProcessState},
@@ -818,6 +820,10 @@ private:
SrpClient mSrpClient;
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
SrpServer mSrpServer;
#endif
Instance *mInstance;
};
+246
View File
@@ -0,0 +1,246 @@
/*
* 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 a simple CLI for the SRP server.
*/
#include "cli_srp_server.hpp"
#include <inttypes.h>
#include "cli/cli.hpp"
#include "common/string.hpp"
#include "utils/parse_cmdline.hpp"
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
namespace ot {
namespace Cli {
constexpr SrpServer::Command SrpServer::sCommands[];
otError SrpServer::Process(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_INVALID_COMMAND;
const Command *command;
VerifyOrExit(aArgsLength != 0, IgnoreError(ProcessHelp(0, nullptr)));
command = Utils::LookupTable::Find(aArgs[0], sCommands);
VerifyOrExit(command != nullptr);
error = (this->*command->mHandler)(aArgsLength, aArgs);
exit:
return error;
}
otError SrpServer::ProcessDomain(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgsLength > 1)
{
SuccessOrExit(error = otSrpServerSetDomain(mInterpreter.mInstance, aArgs[1]));
}
else
{
mInterpreter.OutputLine(otSrpServerGetDomain(mInterpreter.mInstance));
}
exit:
return error;
}
otError SrpServer::ProcessEnable(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otSrpServerSetEnabled(mInterpreter.mInstance, /* aEnabled */ true);
return OT_ERROR_NONE;
}
otError SrpServer::ProcessDisable(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otSrpServerSetEnabled(mInterpreter.mInstance, /* aEnabled */ false);
return OT_ERROR_NONE;
}
otError SrpServer::ProcessLease(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
uint32_t minLease;
uint32_t maxLease;
uint32_t minKeyLease;
uint32_t maxKeyLease;
VerifyOrExit(aArgsLength == 5, error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[1], minLease));
SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[2], maxLease));
SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[3], minKeyLease));
SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[4], maxKeyLease));
error = otSrpServerSetLeaseRange(mInterpreter.mInstance, minLease, maxLease, minKeyLease, maxKeyLease);
exit:
return error;
}
otError SrpServer::ProcessHost(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
const otSrpServerHost *host;
VerifyOrExit(aArgsLength <= 1, error = OT_ERROR_INVALID_ARGS);
host = nullptr;
while ((host = otSrpServerGetNextHost(mInterpreter.mInstance, host)) != nullptr)
{
const otIp6Address *addresses;
uint8_t addressesNum;
bool isDeleted = otSrpServerHostIsDeleted(host);
mInterpreter.OutputLine(otSrpServerHostGetFullName(host));
mInterpreter.OutputLine(Interpreter::kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
if (isDeleted)
{
continue;
}
mInterpreter.OutputSpaces(Interpreter::kIndentSize);
mInterpreter.OutputFormat("addresses: [");
addresses = otSrpServerHostGetAddresses(host, &addressesNum);
for (uint8_t i = 0; i < addressesNum; ++i)
{
mInterpreter.OutputIp6Address(addresses[i]);
if (i < addressesNum - 1)
{
mInterpreter.OutputFormat(", ");
}
}
mInterpreter.OutputFormat("]\r\n");
}
exit:
return error;
}
otError SrpServer::ProcessService(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
const otSrpServerHost *host;
VerifyOrExit(aArgsLength <= 1, error = OT_ERROR_INVALID_ARGS);
host = nullptr;
while ((host = otSrpServerGetNextHost(mInterpreter.mInstance, host)) != nullptr)
{
const otSrpServerService *service = nullptr;
while ((service = otSrpServerHostGetNextService(host, service)) != nullptr)
{
const otIp6Address *addresses;
uint8_t addressesNum;
const uint8_t * txtData;
uint16_t txtLength;
bool isDeleted = otSrpServerServiceIsDeleted(service);
mInterpreter.OutputLine(otSrpServerServiceGetFullName(service));
mInterpreter.OutputLine(Interpreter::kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
if (isDeleted)
{
continue;
}
mInterpreter.OutputLine(Interpreter::kIndentSize, "port: %hu", otSrpServerServiceGetPort(service));
mInterpreter.OutputLine(Interpreter::kIndentSize, "priority: %hu", otSrpServerServiceGetPriority(service));
mInterpreter.OutputLine(Interpreter::kIndentSize, "weight: %hu", otSrpServerServiceGetWeight(service));
txtData = otSrpServerServiceGetTxtData(service, &txtLength);
if (txtLength > 0)
{
mInterpreter.OutputSpaces(Interpreter::kIndentSize);
mInterpreter.OutputFormat("TXT: ");
mInterpreter.OutputBytes(txtData, txtLength);
mInterpreter.OutputFormat("\r\n");
}
mInterpreter.OutputLine(Interpreter::kIndentSize, "host: %s", otSrpServerHostGetFullName(host));
mInterpreter.OutputSpaces(Interpreter::kIndentSize);
mInterpreter.OutputFormat("addresses: [");
addresses = otSrpServerHostGetAddresses(host, &addressesNum);
for (uint8_t i = 0; i < addressesNum; ++i)
{
mInterpreter.OutputIp6Address(addresses[i]);
if (i < addressesNum - 1)
{
mInterpreter.OutputFormat(", ");
}
}
mInterpreter.OutputFormat("]\r\n");
}
}
exit:
return error;
}
otError SrpServer::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
for (const Command &command : sCommands)
{
mInterpreter.OutputLine(command.mName);
}
return OT_ERROR_NONE;
}
} // namespace Cli
} // namespace ot
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
+112
View File
@@ -0,0 +1,112 @@
/*
* 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 contains definitions for a simple CLI to control the SRP server.
*/
#ifndef CLI_SRP_SERVER_HPP_
#define CLI_SRP_SERVER_HPP_
#include "openthread-core-config.h"
#include <openthread/srp_server.h>
#include "utils/lookup_table.hpp"
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
namespace ot {
namespace Cli {
class Interpreter;
/**
* This class implements the SRP Server CLI interpreter.
*
*/
class SrpServer
{
public:
/**
* Constructor
*
* @param[in] aInterpreter The CLI interpreter.
*
*/
explicit SrpServer(Interpreter &aInterpreter)
: mInterpreter(aInterpreter)
{
}
/**
* This method interprets a list of CLI arguments.
*
* @param[in] aArgsLength The number of elements in @p aArgs.
* @param[in] aArgs A pointer to an array of command line arguments.
*
* @retval OT_ERROR_NONE Successfully executed the CLI command.
* @retval ... Failed to execute the CLI command.
*
*/
otError Process(uint8_t aArgsLength, char *aArgs[]);
private:
struct Command
{
const char *mName;
otError (SrpServer::*mHandler)(uint8_t aArgsLength, char *aArgs[]);
};
otError ProcessDomain(uint8_t aArgsLength, char *aArgs[]);
otError ProcessEnable(uint8_t aArgsLength, char *aArgs[]);
otError ProcessDisable(uint8_t aArgsLength, char *aArgs[]);
otError ProcessLease(uint8_t aArgsLength, char *aArgs[]);
otError ProcessHost(uint8_t aArgsLength, char *aArgs[]);
otError ProcessService(uint8_t aArgsLength, char *aArgs[]);
otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
static constexpr Command sCommands[] = {
{"disable", &SrpServer::ProcessDisable}, {"domain", &SrpServer::ProcessDomain},
{"enable", &SrpServer::ProcessEnable}, {"help", &SrpServer::ProcessHelp},
{"host", &SrpServer::ProcessHost}, {"lease", &SrpServer::ProcessLease},
{"service", &SrpServer::ProcessService},
};
static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
Interpreter &mInterpreter;
};
} // namespace Cli
} // namespace ot
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#endif // CLI_SRP_SERVER_HPP_
+8
View File
@@ -224,6 +224,10 @@ if (openthread_enable_core_config_args) {
defines += [ "OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1" ]
}
if (openthread_config_srp_server_enable) {
defines += [ "OPENTHREAD_CONFIG_SRP_SERVER_ENABLE=1" ]
}
if (openthread_config_time_sync_enable) {
defines += [ "OPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1" ]
}
@@ -334,6 +338,7 @@ openthread_core_files = [
"api/server_api.cpp",
"api/sntp_api.cpp",
"api/srp_client_api.cpp",
"api/srp_server_api.cpp",
"api/tasklet_api.cpp",
"api/thread_api.cpp",
"api/thread_ftd_api.cpp",
@@ -506,6 +511,8 @@ openthread_core_files = [
"net/socket.hpp",
"net/srp_client.cpp",
"net/srp_client.hpp",
"net/srp_server.cpp",
"net/srp_server.hpp",
"net/tcp.hpp",
"net/udp6.cpp",
"net/udp6.hpp",
@@ -687,6 +694,7 @@ source_set("libopenthread_core_config") {
"config/radio_link.h",
"config/sntp_client.h",
"config/srp_client.h",
"config/srp_server.h",
"config/time_sync.h",
"config/tmf.h",
"openthread-core-config.h",
+2
View File
@@ -67,6 +67,7 @@ set(COMMON_SOURCES
api/server_api.cpp
api/sntp_api.cpp
api/srp_client_api.cpp
api/srp_server_api.cpp
api/tasklet_api.cpp
api/thread_api.cpp
api/thread_ftd_api.cpp
@@ -146,6 +147,7 @@ set(COMMON_SOURCES
net/netif.cpp
net/sntp_client.cpp
net/srp_client.cpp
net/srp_server.cpp
net/udp6.cpp
radio/radio.cpp
radio/radio_callbacks.cpp
+4
View File
@@ -144,6 +144,7 @@ SOURCES_COMMON = \
api/server_api.cpp \
api/sntp_api.cpp \
api/srp_client_api.cpp \
api/srp_server_api.cpp \
api/tasklet_api.cpp \
api/thread_api.cpp \
api/thread_ftd_api.cpp \
@@ -223,6 +224,7 @@ SOURCES_COMMON = \
net/netif.cpp \
net/sntp_client.cpp \
net/srp_client.cpp \
net/srp_server.cpp \
net/udp6.cpp \
radio/radio.cpp \
radio/radio_callbacks.cpp \
@@ -415,6 +417,7 @@ HEADERS_COMMON = \
config/radio_link.h \
config/sntp_client.h \
config/srp_client.h \
config/srp_server.h \
config/time_sync.h \
config/tmf.h \
crypto/aes_ccm.hpp \
@@ -467,6 +470,7 @@ HEADERS_COMMON = \
net/sntp_client.hpp \
net/socket.hpp \
net/srp_client.hpp \
net/srp_server.hpp \
net/tcp.hpp \
net/udp6.hpp \
radio/radio.hpp \
+160
View File
@@ -0,0 +1,160 @@
/*
* 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 defines the OpenThread SRP server API.
*/
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#include <openthread/srp_server.h>
#include "common/instance.hpp"
#include "common/locator-getters.hpp"
using namespace ot;
const char *otSrpServerGetDomain(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Srp::Server>().GetDomain();
}
otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Srp::Server>().SetDomain(aDomain);
}
void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled)
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.Get<Srp::Server>().SetEnabled(aEnabled);
}
otError otSrpServerSetLeaseRange(otInstance *aInstance,
uint32_t aMinLease,
uint32_t aMaxLease,
uint32_t aMinKeyLease,
uint32_t aMaxKeyLease)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Srp::Server>().SetLeaseRange(aMinLease, aMaxLease, aMinKeyLease, aMaxKeyLease);
}
void otSrpServerSetServiceUpdateHandler(otInstance * aInstance,
otSrpServerServiceUpdateHandler aServiceHandler,
void * aContext)
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.Get<Srp::Server>().SetServiceHandler(aServiceHandler, aContext);
}
void otSrpServerHandleServiceUpdateResult(otInstance *aInstance, const otSrpServerHost *aHost, otError aError)
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.Get<Srp::Server>().HandleAdvertisingResult(static_cast<const Srp::Server::Host *>(aHost), aError);
}
const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrpServerHost *aHost)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Srp::Server>().GetNextHost(static_cast<const Srp::Server::Host *>(aHost));
}
bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost)
{
return static_cast<const Srp::Server::Host *>(aHost)->IsDeleted();
}
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost)
{
return static_cast<const Srp::Server::Host *>(aHost)->GetFullName();
}
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum)
{
auto host = static_cast<const Srp::Server::Host *>(aHost);
return host->GetAddresses(*aAddressesNum);
}
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost * aHost,
const otSrpServerService *aService)
{
auto host = static_cast<const Srp::Server::Host *>(aHost);
return host->GetNextService(static_cast<const Srp::Server::Service *>(aService));
}
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService)
{
return static_cast<const Srp::Server::Service *>(aService)->IsDeleted();
}
const char *otSrpServerServiceGetFullName(const otSrpServerService *aService)
{
return static_cast<const Srp::Server::Service *>(aService)->GetFullName();
}
uint16_t otSrpServerServiceGetPort(const otSrpServerService *aService)
{
return static_cast<const Srp::Server::Service *>(aService)->GetPort();
}
uint16_t otSrpServerServiceGetWeight(const otSrpServerService *aService)
{
return static_cast<const Srp::Server::Service *>(aService)->GetWeight();
}
uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService)
{
return static_cast<const Srp::Server::Service *>(aService)->GetPriority();
}
const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService, uint16_t *aTxtLength)
{
return static_cast<const Srp::Server::Service *>(aService)->GetTxtData(*aTxtLength);
}
const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aService)
{
return &static_cast<const Srp::Server::Service *>(aService)->GetHost();
}
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
+7
View File
@@ -869,6 +869,13 @@ template <> inline BorderRouter::RoutingManager &Instance::Get(void)
}
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
template <> inline Srp::Server &Instance::Get(void)
{
return mThreadNetif.mSrpServer;
}
#endif
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+3
View File
@@ -183,6 +183,9 @@ void Notifier::EmitEvents(void)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
Get<BorderRouter::RoutingManager>().HandleNotifierEvents(events);
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Get<Srp::Server>().HandleNotifierEvents(events);
#endif
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
Get<Srp::Client>().HandleNotifierEvents(events);
#endif
@@ -36,6 +36,7 @@
#define OPENTHREAD_CORE_DEFAULT_CONFIG_H_
#include "config/coap.h"
#include "config/srp_server.h"
/**
* @def OPENTHREAD_CONFIG_STACK_VENDOR_OUI
@@ -265,7 +266,10 @@
*
*/
#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
// Internal heap doesn't support size larger than 64K bytes.
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (63 * 1024)
#elif OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (3072 * sizeof(void *))
#else
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (1568 * sizeof(void *))
@@ -279,7 +283,10 @@
*
*/
#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
// Internal heap doesn't support size larger than 64K bytes.
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS (63 * 1024)
#elif OPENTHREAD_CONFIG_ECDSA_ENABLE
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS 2600
#else
#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS 384
+83
View File
@@ -0,0 +1,83 @@
/*
* 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) Server.
*
*/
#ifndef CONFIG_SRP_SERVER_H_
#define CONFIG_SRP_SERVER_H_
/**
* @def OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
*
* Define to 1 to enable SRP Server support.
*
*/
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#define OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE
*
* Specifies the Service Type for SRP Server.
*
*/
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE
#define OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE 0x5du
#endif
/**
* @def OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT
*
* Specifies the timeout value (in milliseconds) for the service update handler.
*
* The default timeout value is the sum of the maximum total mDNS probing delays
* and a loose IPC timeout of 250ms. It is recommended that this configuration should
* not use a value smaller than the default value here, if an Advertising Proxy is used
* to handle the service update events.
*
*/
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT
#define OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT ((4 * 250u) + 250u)
#endif
/**
* @def OPENTHREAD_CONFIG_SRP_SERVER_MAX_ADDRESSES_NUM
*
* Specifies the maximum number of addresses the SRP server can handle for a host.
*
*/
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_MAX_ADDRESSES_NUM
#define OPENTHREAD_CONFIG_SRP_SERVER_MAX_ADDRESSES_NUM 2
#endif
#endif // CONFIG_SRP_SERVER_H_
+34
View File
@@ -373,5 +373,39 @@ exit:
return error;
}
bool AaaaRecord::IsValid(void) const
{
return GetType() == Dns::ResourceRecord::kTypeAaaa && GetSize() == sizeof(*this);
}
bool KeyRecord::IsValid(void) const
{
return GetType() == Dns::ResourceRecord::kTypeKey;
}
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
void Ecdsa256KeyRecord::Init(void)
{
KeyRecord::Init();
SetAlgorithm(kAlgorithmEcdsaP256Sha256);
}
bool Ecdsa256KeyRecord::IsValid(void) const
{
return KeyRecord::IsValid() && GetLength() == sizeof(*this) - sizeof(ResourceRecord) &&
GetAlgorithm() == kAlgorithmEcdsaP256Sha256;
}
#endif
bool SigRecord::IsValid(void) const
{
return GetType() == Dns::ResourceRecord::kTypeSig && GetLength() >= sizeof(*this) - sizeof(ResourceRecord);
}
bool LeaseOption::IsValid(void) const
{
return GetLeaseInterval() <= GetKeyLeaseInterval();
}
} // namespace Dns
} // namespace ot
+87
View File
@@ -39,6 +39,7 @@
#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/message.hpp"
#include "crypto/ecdsa.hpp"
#include "net/ip6_address.hpp"
namespace ot {
@@ -923,6 +924,14 @@ public:
SetLength(sizeof(Ip6::Address));
}
/**
* This method tells whether this is a valid AAAA record.
*
* @returns A boolean indicates whether this is a valid AAAA record.
*
*/
bool IsValid(void) const;
/**
* This method sets the IPv6 address of the resource record.
*
@@ -1095,6 +1104,14 @@ public:
*/
void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeKey, aClass); }
/**
* This method tells whether the KEY record is valid.
*
* @returns TRUE if this is a valid KEY record, FALSE if an invalid KEY record.
*
*/
bool IsValid(void) const;
/**
* This method gets the key use (or key type) flags.
*
@@ -1189,6 +1206,60 @@ private:
} OT_TOOL_PACKED_END;
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
OT_TOOL_PACKED_BEGIN
class Ecdsa256KeyRecord : public KeyRecord, public Clearable<Ecdsa256KeyRecord>
{
public:
/**
* This method initializes the KEY Resource Record to ECDSA with curve P-256.
*
* Other record fields (TTL, length, flags, protocol) remain unchanged/uninitialized.
*
*/
void Init(void);
/**
* This method tells whether this is a valid ECDSA DNSKEY with curve P-256.
*
* @returns A boolean that indicates whether this is a valid ECDSA DNSKEY RR with curve P-256.
*
*/
bool IsValid(void) const;
/**
* This method returns the ECDSA P-256 public kek.
*
* @returns A reference to the public key.
*
*/
const Crypto::Ecdsa::P256::PublicKey &GetKey(void) const { return mKey; }
/**
* This comparator tells whether two Ecdsa256KeyRecord objects are equal.
*
* @param[in] aOther The other Ecdsa256KeyRecord object.
*
* @returns TRUE if they are equal, FALSE if not.
*
*/
bool operator==(const Ecdsa256KeyRecord &aOther) const { return memcmp(this, &aOther, sizeof(*this)) == 0; }
/**
* This comparator tells whether two Ecdsa256KeyRecord objects are not equal.
*
* @param[in] aOther The other Ecdsa256KeyRecord object.
*
* @returns TRUE if they are not equal, FALSE if equal.
*
*/
bool operator!=(const Ecdsa256KeyRecord &aOther) const { return !(*this == aOther); }
private:
Crypto::Ecdsa::P256::PublicKey mKey;
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
/**
* This class implements Resource Record body format of SIG type (RFC 2535 - section-4.1).
*
@@ -1210,6 +1281,14 @@ public:
*/
void Init(uint16_t aClass) { ResourceRecord::Init(kTypeSig, aClass); }
/**
* This method tells whether the SIG record is valid.
*
* @returns TRUE if this is a valid SIG record, FALSE if not a valid SIG record.
*
*/
bool IsValid(void) const;
/**
* This method returns the SIG record's type-covered value.
*
@@ -1569,6 +1648,14 @@ public:
SetOptionLength(kOptionLength);
}
/**
* This method tells whether this is a valid Lease Option.
*
* @returns TRUE if this is a valid Lease Option, FALSE if not a valid Lease Option.
*
*/
bool IsValid(void) const;
/**
* This method returns the Update Lease OPT record's lease interval value.
*
+13
View File
@@ -236,6 +236,19 @@ public:
class SockAddr : public otSockAddr, public Clearable<SockAddr>
{
public:
enum
{
// The socket address string length is:
// len('[') + len(mAddress) + len(']') + len(':') + len(mPort)
kIp6SocketAddressStringSize = 1 + Address::kIp6AddressStringSize + 1 + 1 + 5,
};
/**
* This type defines the fixed-length `String` object returned from `ToString()`.
*
*/
typedef String<kIp6SocketAddressStringSize> InfoString;
/**
* This constructor initializes the socket address (all fields are set to zero).
*
File diff suppressed because it is too large Load Diff
+641
View File
@@ -0,0 +1,641 @@
/*
* 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 definitions for SRP server.
*/
#ifndef NET_SRP_SERVER_HPP_
#define NET_SRP_SERVER_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
#error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE"
#endif
#if !OPENTHREAD_CONFIG_ECDSA_ENABLE
#error "OPENTHREAD_CONFIG_ECDSA_ENABLE is required for OPENTHREAD_CONFIG_SRP_SERVER_ENABLE"
#endif
#include <openthread/ip6.h>
#include <openthread/srp_server.h>
#include "common/clearable.hpp"
#include "common/linked_list.hpp"
#include "common/locator.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/ip6_address.hpp"
#include "net/udp6.hpp"
namespace ot {
namespace Srp {
/**
* This class implements the SRP server.
*
*/
class Server : public InstanceLocator, private NonCopyable
{
friend class ot::Notifier;
public:
class Host;
class Service;
/**
* This class implements a server-side SRP service.
*
*/
class Service : public InstanceLocator, public LinkedListEntry<Service>, private NonCopyable
{
friend class LinkedListEntry<Service>;
friend class Server;
public:
/**
* This method creates a new Service object with given full name.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aFullName The full name of the service instance.
*
* @returns A pointer to the newly created Service object. nullptr if
* cannot allocate memory for the object.
*
*/
static Service *New(Instance &aInstance, const char *aFullName);
/**
* This method frees the Service object.
*
*/
void Free(void);
/**
* This method tells if the SRP service has been deleted.
*
* A SRP service can be deleted but retains its name for future uses.
* In this case, the service instance is not removed from the SRP server/registry.
* It is guaranteed that all services are deleted if the host is deleted.
*
* @returns TRUE if the service has been deleted, FALSE if not.
*
*/
bool IsDeleted(void) const { return mIsDeleted; }
/**
* This method returns the full name of the service.
*
* @returns A pointer to the null-terminated service name string.
*
*/
const char *GetFullName(void) const { return mFullName; }
/**
* This method returns the port of the service instance.
*
* @returns The port of the service.
*
*/
uint16_t GetPort(void) const { return mPort; }
/**
* This method returns the weight of the service instance.
*
* @returns The weight of the service.
*
*/
uint16_t GetWeight(void) const { return mWeight; }
/**
* This method returns the priority of the service instance.
*
* @param[in] aService A pointer to the SRP service.
*
* @returns The priority of the service.
*
*/
uint16_t GetPriority(void) const { return mPriority; }
/**
* This method returns the TXT data of the service instance.
*
* @param[out] aTxtLength A pointer to the output of the TXT data length.
*
* @returns A pointer to the standard TXT data with format described by RFC 6763.
*
*/
const uint8_t *GetTxtData(uint16_t &aTxtLength) const
{
aTxtLength = mTxtLength;
return mTxtData;
}
/**
* This method returns the host which the service instance reside on.
*
* @returns A reference to the host instance.
*
*/
const Host &GetHost(void) const { return *static_cast<const Host *>(mHost); }
/**
* This method returns the expire time (in milliseconds) of the service.
*
* @returns The service expire time in milliseconds.
*
*/
TimeMilli GetExpireTime(void) const;
/**
* This method returns the key expire time (in milliseconds) of the service.
*
* @returns The service key expire time in milliseconds.
*
*/
TimeMilli GetKeyExpireTime(void) const;
/**
* This method tells whether this service matches a given full name.
*
* @param[in] aFullName The full name.
*
* @returns TRUE if the servce matches the full name, FALSE if doesn't match.
*
*/
bool Matches(const char *aFullName) const;
private:
explicit Service(Instance &aInstance);
otError SetFullName(const char *aFullName);
otError SetTxtData(const uint8_t *aTxtData, uint16_t aTxtDataLength);
otError SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
otError CopyResourcesFrom(const Service &aService);
void ClearResources(void);
void DeleteResourcesButRetainName(void);
char * mFullName;
uint16_t mPriority;
uint16_t mWeight;
uint16_t mPort;
uint16_t mTxtLength;
uint8_t * mTxtData;
otSrpServerHost *mHost;
Service * mNext;
TimeMilli mTimeLastUpdate;
bool mIsDeleted;
};
/**
* This class implements the Host which registers services on the SRP server.
*
*/
class Host : public InstanceLocator, public LinkedListEntry<Host>, private NonCopyable
{
friend class LinkedListEntry<Host>;
friend class Server;
public:
/**
* This method creates a new Host object with given full name.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
* @returns A pointer to the newly created Host object. nullptr if
* cannot allocate memory for the object.
*
*/
static Host *New(Instance &aInstance);
/**
* This method Frees the Host object.
*
*/
void Free(void);
/**
* This method tells whether the Host object has been deleted.
*
* The Host object retains event if the host has been deleted by the SRP client,
* because the host name may retain.
*
* @returns TRUE if the host is deleted, FALSE if the host is not deleted.
*
*/
bool IsDeleted(void) const { return (mLease == 0); }
/**
* This method returns the full name of the host.
*
* @returns A pointer to the null-terminated full host name.
*
*/
const char *GetFullName(void) const { return mFullName; }
/**
* This method returns adrersses of the host.
*
* @param[out] aAddressesNum The number of the addresses.
*
* @returns A pointer to the addresses array.
*
*/
const Ip6::Address *GetAddresses(uint8_t &aAddressesNum) const
{
aAddressesNum = mAddressesNum;
return mAddresses;
}
/**
* This method returns the LEASE time of the host.
*
* @returns The LEASE time in seconds.
*
*/
uint32_t GetLease(void) const { return mLease; }
/**
* This method returns the KEY-LEASE time of the key of the host.
*
* @returns The KEY-LEASE time in seconds.
*
*/
uint32_t GetKeyLease(void) const { return mKeyLease; }
/**
* This method returns the KEY resource of the host.
*
* @returns A pointer to the ECDSA P 256 public key if there is valid one.
* nullptr if no valid key exists.
*
*/
const Dns::Ecdsa256KeyRecord *GetKey(void) const { return mKey.IsValid() ? &mKey : nullptr; }
/**
* This method returns the expire time (in milliseconds) of the host.
*
* @returns The expire time in milliseconds.
*
*/
TimeMilli GetExpireTime(void) const;
/**
* This method returns the expire time (in milliseconds) of the key of the host.
*
* @returns The expire time of the key in milliseconds.
*
*/
TimeMilli GetKeyExpireTime(void) const;
/**
* This method returns the next service of the host.
*
* @param[in] aService A pointer to current service.
*
* @returns A pointer to the next service or NULL if no more services exist.
*
*/
const Service *GetNextService(const Service *aService) const
{
return aService ? aService->GetNext() : mServices.GetHead();
}
/**
* This method tells whether the host matches a given full name.
*
* @param[in] aFullName The full name.
*
* @returns A boolean that indicates whether the host matches the given name.
*
*/
bool Matches(const char *aName) const;
private:
enum : uint8_t
{
kMaxAddressesNum = OPENTHREAD_CONFIG_SRP_SERVER_MAX_ADDRESSES_NUM,
};
explicit Host(Instance &aInstance);
otError SetFullName(const char *aFullName);
void SetKey(Dns::Ecdsa256KeyRecord &aKey);
void SetLease(uint32_t aLease);
void SetKeyLease(uint32_t aKeyLease);
Service *GetNextService(Service *aService) { return aService ? aService->GetNext() : mServices.GetHead(); }
Service *AddService(const char *aFullName);
void RemoveAndFreeService(Service *aService);
void RemoveAndFreeAllServices(void);
void ClearResources(void);
void DeleteResourcesButRetainName(void);
void CopyResourcesFrom(const Host &aHost);
Service *FindService(const char *aFullName);
otError AddIp6Address(const Ip6::Address &aIp6Address);
char * mFullName;
Ip6::Address mAddresses[kMaxAddressesNum];
uint8_t mAddressesNum;
Host * mNext;
Dns::Ecdsa256KeyRecord mKey;
uint32_t mLease; // The LEASE time in seconds.
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
TimeMilli mTimeLastUpdate;
LinkedList<Service> mServices;
};
/**
* This constructor initializes the SRP server object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit Server(Instance &aInstance);
~Server(void);
/**
* This method sets the SRP service events handler.
*
* @param[in] aServiceHandler A service events handler.
* @param[in] aServiceHandlerContext A pointer to arbitrary context information.
*
* @note The handler SHOULD call HandleAdvertisingResult to report the result of its processing.
* Otherwise, a SRP update will be considered failed.
*
* @sa HandleAdvertisingResult
*
*/
void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext);
/**
* This method returns the domain authorized to the SRP server.
*
* If the domain if not set by SetDomain, "default.service.arpa." will be returned.
* A trailing dot is always appended even if the domain is set without it.
*
* @returns A pointer to the dot-joined domain string.
*
*/
const char *GetDomain(void) const;
/**
* This method sets the domain on the SRP server.
*
* A trailing dot will be appended to @p aDomain if it is not already there.
* This method should only be called before the SRP server is enabled.
*
* @param[in] aDomain The domain to be set. MUST NOT be nullptr.
*
* @retval OT_ERROR_NONE Successfully set the domain to @p aDomain.
* @retval OT_ERROR_INVALID_STATE The SRP server is already enabled and the Domain cannot be changed.
* @retval OT_ERROR_INVALID_ARGS The argument @p aDomain is not a valid DNS domain name.
* @retval OT_ERROR_NO_BUFS There is no memory to store content of @p aDomain.
*
*/
otError SetDomain(const char *aDomain);
/**
* This method tells whether the SRP server is currently running.
*
* @returns A boolean that indicates whether the server is running.
*
*/
bool IsRunning(void) const;
/**
* This method enables/disables the SRP server.
*
* @param[in] aEnabled A boolean to enable/disable the SRP server.
*
*/
void SetEnabled(bool aEnabled);
/**
* This method sets LEASE & KEY-LEASE range that is acceptable by the SRP server.
*
* When a LEASE time is requested from a client, the granted value will be
* limited in range [aMinLease, aMaxLease]; and a KEY-LEASE will be granted
* in range [aMinKeyLease, aMaxKeyLease].
*
* @param[in] aMinLease The minimum LEASE interval in seconds.
* @param[in] aMaxLease The maximum LEASE interval in seconds.
* @param[in] aMinKeyLease The minimum KEY-LEASE interval in seconds.
* @param[in] aMaxKeyLease The maximum KEY-LEASE interval in seconds.
*
* @retval OT_ERROR_NONE Successfully set the LEASE and KEY-LEASE ranges.
* @retval OT_ERROR_INVALID_ARGS The LEASE or KEY-LEASE range is not valid.
*
*/
otError SetLeaseRange(uint32_t aMinLease, uint32_t aMaxLease, uint32_t aMinKeyLease, uint32_t aMaxKeyLease);
/**
* This method returns the next registered SRP host.
*
* @param[in] aHost The current SRP host; use nullptr to get the first SRP host.
*
* @returns A pointer to the next SRP host or nullptr if no more SRP hosts can be found.
*
*/
const Host *GetNextHost(const Host *aHost);
/**
* This method receives the service advertising result.
*
* @param[in] aHost A pointer to the Host object which contains the SRP service updates.
* @param[in] aError The service advertising result.
*
*/
void HandleAdvertisingResult(const Host *aHost, otError aError);
private:
enum : uint8_t
{
kThreadServiceTypeSrpServer = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE,
};
enum : uint16_t
{
kUdpPayloadSize = Ip6::Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header), // Max UDP payload size
};
enum : uint32_t
{
kDefaultMinLease = 60u * 30, // Default minimum lease time, 30 min (in seconds).
kDefaultMaxLease = 3600u * 2, // Default maximum lease time, 2 hours (in seconds).
kDefaultMinKeyLease = 3600u * 24, // Default minimum key-lease time, 1 day (in seconds).
kDefaultMaxKeyLease = 3600u * 24 * 14, // Default maximum key-lease time, 14 days (in seconds).
kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT,
};
/**
* This class includes metadata for processing a SRP update (register, deregister)
* and sending DNS response to the client.
*
*/
class UpdateMetadata : public InstanceLocator, public LinkedListEntry<UpdateMetadata>
{
friend class LinkedListEntry<UpdateMetadata>;
public:
static UpdateMetadata * New(Instance & aInstance,
const Dns::UpdateHeader &aHeader,
Host * aHost,
const Ip6::MessageInfo & aMessageInfo);
void Free(void);
TimeMilli GetExpireTime(void) const { return mExpireTime; }
const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
Host & GetHost(void) { return *mHost; }
const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; }
bool Matches(const Host *aHost) const { return mHost == aHost; }
private:
UpdateMetadata(Instance & aInstance,
const Dns::UpdateHeader &aHeader,
Host * aHost,
const Ip6::MessageInfo & aMessageInfo);
TimeMilli mExpireTime;
Dns::UpdateHeader mDnsHeader;
Host * mHost; // The host will be updated. The UpdateMetadata has no ownership of this host.
Ip6::MessageInfo mMessageInfo; // The message info of the DNS update request.
UpdateMetadata * mNext;
};
void Start(void);
void Stop(void);
void HandleNotifierEvents(Events aEvents);
otError PublishServerData(void);
void UnpublishServerData(void);
uint32_t GrantLease(uint32_t aLease) const;
uint32_t GrantKeyLease(uint32_t aKeyLease) const;
void HandleSrpUpdateResult(otError aError,
const Dns::UpdateHeader &aDnsHeader,
Host & aHost,
const Ip6::MessageInfo & aMessageInfo);
void HandleDnsUpdate(Message & aMessage,
const Ip6::MessageInfo & aMessageInfo,
const Dns::UpdateHeader &aDnsHeader,
uint16_t aOffset);
otError ProcessUpdateSection(Host & aHost,
const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
const Dns::Zone & aZone,
uint16_t aHeaderOffset,
uint16_t & aOffset);
otError ProcessAdditionalSection(Host * aHost,
const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
uint16_t aHeaderOffset,
uint16_t & aOffset);
otError VerifySignature(const Dns::Ecdsa256KeyRecord &aKey,
const Message & aMessage,
Dns::UpdateHeader aDnsHeader,
uint16_t aSigOffset,
uint16_t aSigRdataOffset,
uint16_t aSigRdataLength,
const char * aSignerName);
static otError ProcessZoneSection(const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
uint16_t & aOffset,
Dns::Zone & aZone);
static otError ProcessHostDescriptionInstruction(Host & aHost,
const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
const Dns::Zone & aZone,
uint16_t aHeaderOffset,
uint16_t aOffset);
static otError ProcessServiceDiscoveryInstructions(Host & aHost,
const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
const Dns::Zone & aZone,
uint16_t aHeaderOffset,
uint16_t aOffset);
static otError ProcessServiceDescriptionInstructions(Host & aHost,
const Message & aMessage,
const Dns::UpdateHeader &aDnsHeader,
const Dns::Zone & aZone,
uint16_t aHeaderOffset,
uint16_t & aOffset);
static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord);
void HandleUpdate(const Dns::UpdateHeader &aDnsHeader, Host *aHost, const Ip6::MessageInfo &aMessageInfo);
void AddHost(Host *aHost);
void RemoveAndFreeHost(Host *aHost);
Service * FindService(const char *aFullName);
bool HasNameConflictsWith(Host &aHost);
void SendResponse(const Dns::UpdateHeader & aHeader,
Dns::UpdateHeader::Response aResponseCode,
const Ip6::MessageInfo & aMessageInfo);
void SendResponse(const Dns::UpdateHeader &aHeader,
uint32_t aLease,
uint32_t aKeyLease,
const Ip6::MessageInfo & aMessageInfo);
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleLeaseTimer(Timer &aTimer);
void HandleLeaseTimer(void);
static void HandleOutstandingUpdatesTimer(Timer &aTimer);
void HandleOutstandingUpdatesTimer(void);
void HandleAdvertisingResult(UpdateMetadata *aUpdate, otError aError);
const UpdateMetadata *FindOutstandingUpdate(const Ip6::MessageInfo &aMessageInfo, uint16_t aDnsMessageId);
Ip6::Udp::Socket mSocket;
otSrpServerServiceUpdateHandler mAdvertisingHandler;
void * mAdvertisingHandlerContext;
char *mDomain;
uint32_t mMinLease; // The minimum lease time in seconds.
uint32_t mMaxLease; // The maximum lease time in seconds.
uint32_t mMinKeyLease; // The minimum key-lease time in seconds.
uint32_t mMaxKeyLease; // The maximum key-lease time in seconds.
LinkedList<Host> mHosts;
TimerMilli mLeaseTimer;
TimerMilli mOutstandingUpdatesTimer;
LinkedList<UpdateMetadata> mOutstandingUpdates;
bool mEnabled;
};
} // namespace Srp
} // namespace ot
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#endif // NET_SRP_SERVER_HPP_
+1
View File
@@ -77,6 +77,7 @@
#include "config/radio_link.h"
#include "config/sntp_client.h"
#include "config/srp_client.h"
#include "config/srp_server.h"
#include "config/time_sync.h"
#include "config/tmf.h"
+4
View File
@@ -124,6 +124,10 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
#if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
, mDuaManager(aInstance)
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
, mSrpServer(aInstance)
#endif
, mChildSupervisor(aInstance)
, mSupervisionListener(aInstance)
, mAnnounceBegin(aInstance)
+8
View File
@@ -64,6 +64,10 @@
#include "thread/dua_manager.hpp"
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
#include "net/srp_server.hpp"
#endif
#include "meshcop/dataset_manager.hpp"
#if OPENTHREAD_CONFIG_JOINER_ENABLE
@@ -266,6 +270,10 @@ private:
#if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
DuaManager mDuaManager;
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Srp::Server mSrpServer;
#endif
Utils::ChildSupervisor mChildSupervisor;
Utils::SupervisionListener mSupervisionListener;
AnnounceBeginServer mAnnounceBegin;