mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 23:57:46 +00:00
[srp-server] simplify sub-type services (#9208)
This commit updates and simplifies how `Srp::Server` stores the sub-type services. The earlier implementation treated each sub-type as its own service, which was tracked by a `Service` object. This design allowed sub-type services to be registered and deleted individually. However, the latest SRP RFC draft requires SRP servers to treat updates to a service and all its sub-types as atomic. This means that when a service and its sub-types are being updated, the SRP Update message must contain the entirety of information about that service and its sub-types. As a result of this change, we can simplify the server implementation by tracking sub-types as an array of sub-type names in the `Service` object. This commit also updates the way the server commits a received SRP update info into its existing data. Previously, the server would try to merge the new information into existing `Host` and `Service` objects. However, this could be inefficient, as it would require moving heap-allocated items like "txt data" and/or array of host IPv6 addresses from one object to another. The new `CommitSrpUpdate()` implementation now starts from the new `Host` object that is constructed as the received SRP Update message from the client is parsed. Any previously registered services that are not present in the new `Host` object are then moved into it. This commit adds new public OT APIs for retrieving the sub-types associated with a service and making it easier to iterate over the list of registered services by a host. Due to fundamental changes in how services are stored by the `Srp::Server` class, some existing public `otSrpServer` APIs for filtering and iterating over services are being removed.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
|||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (342)
|
#define OPENTHREAD_API_VERSION (343)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
|||||||
+104
-139
@@ -73,64 +73,6 @@ typedef struct otSrpServerService otSrpServerService;
|
|||||||
*/
|
*/
|
||||||
typedef uint32_t otSrpServerServiceUpdateId;
|
typedef uint32_t otSrpServerServiceUpdateId;
|
||||||
|
|
||||||
/**
|
|
||||||
* The service flag type to indicate which services to include or exclude when searching in (or iterating over) the
|
|
||||||
* list of SRP services.
|
|
||||||
*
|
|
||||||
* This is a combination of bit-flags. The specific bit-flags are defined in the enumeration `OT_SRP_SERVER_FLAG_*`.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef uint8_t otSrpServerServiceFlags;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE = 1 << 0, ///< Include base services (not a sub-type).
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE = 1 << 1, ///< Include sub-type services.
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_ACTIVE = 1 << 2, ///< Include active (not deleted) services.
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_DELETED = 1 << 3, ///< Include deleted services.
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* This constant defines an `otSrpServerServiceFlags` combination accepting any service (base/sub-type,
|
|
||||||
* active/deleted).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_SRP_SERVER_FLAGS_ANY_SERVICE = (OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE |
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_ACTIVE | OT_SRP_SERVER_SERVICE_FLAG_DELETED),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines an `otSrpServerServiceFlags` combination accepting base service only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY =
|
|
||||||
(OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE | OT_SRP_SERVER_SERVICE_FLAG_DELETED),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines an `otSrpServerServiceFlags` combination accepting sub-type service only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY =
|
|
||||||
(OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE | OT_SRP_SERVER_SERVICE_FLAG_DELETED),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines an `otSrpServerServiceFlags` combination accepting any active service (not deleted).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE =
|
|
||||||
(OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE |
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_ACTIVE),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines an `otSrpServerServiceFlags` combination accepting any deleted service.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE =
|
|
||||||
(OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE |
|
|
||||||
OT_SRP_SERVER_SERVICE_FLAG_ACTIVE),
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of the SRP server.
|
* Represents the state of the SRP server.
|
||||||
*
|
*
|
||||||
@@ -505,6 +447,21 @@ bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost);
|
|||||||
*/
|
*/
|
||||||
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost);
|
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the host matches a given host name.
|
||||||
|
*
|
||||||
|
* DNS name matches are performed using a case-insensitive string comparison (i.e., "Abc" and "aBc" are considered to
|
||||||
|
* be the same).
|
||||||
|
*
|
||||||
|
* @param[in] aHost A pointer to the SRP service host.
|
||||||
|
* @param[in] aFullName A full host name.
|
||||||
|
*
|
||||||
|
* @retval TRUE If host matches the host name.
|
||||||
|
* @retval FALSE If host does not match the host name.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool otSrpServerHostMatchesFullName(const otSrpServerHost *aHost, const char *aFullName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the addresses of given host.
|
* Returns the addresses of given host.
|
||||||
*
|
*
|
||||||
@@ -526,10 +483,7 @@ const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, ui
|
|||||||
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo);
|
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next service (excluding any sub-type services) of given host.
|
* Returns the next service of given host.
|
||||||
*
|
|
||||||
* @note This function is being deprecated and will be removed. `otSrpServerHostFindNextService()` can be used
|
|
||||||
* instead.
|
|
||||||
*
|
*
|
||||||
* @param[in] aHost A pointer to the SRP service 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.
|
* @param[in] aService A pointer to current SRP service instance; use NULL to get the first service.
|
||||||
@@ -540,44 +494,6 @@ void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseI
|
|||||||
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost *aHost,
|
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost *aHost,
|
||||||
const otSrpServerService *aService);
|
const otSrpServerService *aService);
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the next matching service on the host.
|
|
||||||
*
|
|
||||||
* The combination of flags and service and instance names enables iterating over the full list of services and/or a
|
|
||||||
* subset of them matching certain conditions, or finding a specific service.
|
|
||||||
*
|
|
||||||
* To iterate over all services of a host:
|
|
||||||
* service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_ANY_SERVICE, NULL, NULL);
|
|
||||||
*
|
|
||||||
* To iterate over base services only (exclude sub-types):
|
|
||||||
* service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY, NULL, NULL);
|
|
||||||
*
|
|
||||||
* To iterate over sub-types of a specific instance name `instanceName`:
|
|
||||||
* service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY, NULL,
|
|
||||||
* instanceName);
|
|
||||||
*
|
|
||||||
* To find a specific service with service name `serviceName` and service instance name `instanceName`:
|
|
||||||
* service = otSrpServerHostFindNextService(host, NULL, OT_SRP_SERVER_FLAGS_ANY_SERVICE, serviceName, instanceName);
|
|
||||||
*
|
|
||||||
* To find the base type service with a given service instance name `instanceName`:
|
|
||||||
* service = otSrpServerHostFindNextService(host, NULL, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY, NULL,
|
|
||||||
* instanceName);
|
|
||||||
*
|
|
||||||
* @param[in] aHost A pointer to the SRP service host (MUST NOT be NULL).
|
|
||||||
* @param[in] aPrevService A pointer to the previous service or NULL to start from the beginning of the list.
|
|
||||||
* @param[in] aFlags Flags indicating which services to include (base/sub-type, active/deleted).
|
|
||||||
* @param[in] aServiceName The service name to match. Set to NULL to accept any name.
|
|
||||||
* @param[in] aInstanceName The service instance name to match. Set to NULL to accept any name.
|
|
||||||
*
|
|
||||||
* @returns A pointer to the next matching service or NULL if no matching service could be found.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const otSrpServerService *otSrpServerHostFindNextService(const otSrpServerHost *aHost,
|
|
||||||
const otSrpServerService *aPrevService,
|
|
||||||
otSrpServerServiceFlags aFlags,
|
|
||||||
const char *aServiceName,
|
|
||||||
const char *aInstanceName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether or not the SRP service has been deleted.
|
* Indicates whether or not the SRP service has been deleted.
|
||||||
*
|
*
|
||||||
@@ -592,29 +508,6 @@ const otSrpServerService *otSrpServerHostFindNextService(const otSrpServerHost
|
|||||||
*/
|
*/
|
||||||
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService);
|
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService);
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether or not the SRP service is sub-type.
|
|
||||||
*
|
|
||||||
* @param[in] aService A pointer to the SRP service.
|
|
||||||
*
|
|
||||||
* @returns TRUE if the service is a sub-type, FALSE if not.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool otSrpServerServiceIsSubType(const otSrpServerService *aService);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the full service instance name of the service.
|
|
||||||
*
|
|
||||||
* @note This function is being deprecated and will be removed. `otSrpServerServiceGetInstanceName()` can be used
|
|
||||||
* instead.
|
|
||||||
*
|
|
||||||
* @param[in] aService A pointer to the SRP service.
|
|
||||||
*
|
|
||||||
* @returns A pointer to the null-terminated service instance name string.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const char *otSrpServerServiceGetFullName(const otSrpServerService *aService);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full service instance name of the service.
|
* Returns the full service instance name of the service.
|
||||||
*
|
*
|
||||||
@@ -625,6 +518,31 @@ const char *otSrpServerServiceGetFullName(const otSrpServerService *aService);
|
|||||||
*/
|
*/
|
||||||
const char *otSrpServerServiceGetInstanceName(const otSrpServerService *aService);
|
const char *otSrpServerServiceGetInstanceName(const otSrpServerService *aService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this service matches a given service instance name.
|
||||||
|
*
|
||||||
|
* DNS name matches are performed using a case-insensitive string comparison (i.e., "Abc" and "aBc" are considered to
|
||||||
|
* be the same).
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
* @param[in] aInstanceName The service instance name.
|
||||||
|
*
|
||||||
|
* @retval TRUE If service matches the service instance name.
|
||||||
|
* @retval FALSE If service does not match the service instance name.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool otSrpServerServiceMatchesInstanceName(const otSrpServerService *aService, const char *aInstanceName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service instance label (first label in instance name) of the service.
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
*
|
||||||
|
* @returns A pointer to the null-terminated service instance label string..
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *otSrpServerServiceGetInstanceLabel(const otSrpServerService *aService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full service name of the service.
|
* Returns the full service name of the service.
|
||||||
*
|
*
|
||||||
@@ -636,27 +554,74 @@ const char *otSrpServerServiceGetInstanceName(const otSrpServerService *aService
|
|||||||
const char *otSrpServerServiceGetServiceName(const otSrpServerService *aService);
|
const char *otSrpServerServiceGetServiceName(const otSrpServerService *aService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the sub-type label from service name.
|
* Indicates whether this service matches a given service name.
|
||||||
*
|
*
|
||||||
* Is intended to be used when the @p aService is a sub-type, i.e., `otSrpServerServiceIsSubType()` for
|
* DNS name matches are performed using a case-insensitive string comparison (i.e., "Abc" and "aBc" are considered to
|
||||||
* the service returns TRUE. If it is not a sub-type this function returns `OT_ERROR_INVALID_ARGS`.
|
* be the same).
|
||||||
*
|
*
|
||||||
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This function
|
* @param[in] aService A pointer to the SRP service.
|
||||||
* copies the `<sub-label>` into the @p aLabel buffer.
|
* @param[in] aServiceName The service name.
|
||||||
*
|
*
|
||||||
* The @p aLabel is ensured to always be null-terminated after returning even in case of failure.
|
* @retval TRUE If service matches the service name.
|
||||||
*
|
* @retval FALSE If service does not match the service name.
|
||||||
* @param[in] aService A pointer to the SRP service.
|
|
||||||
* @param[out] aLabel A pointer to a buffer to copy the sub-type label name into.
|
|
||||||
* @param[in] aMaxSize Maximum size of @p aLabel buffer.
|
|
||||||
*
|
|
||||||
* @retval OT_ERROR_NONE @p aLabel was updated successfully.
|
|
||||||
* @retval OT_ERROR_NO_BUFS The sub-type label could not fit in @p aLabel buffer (number of chars from label
|
|
||||||
* that could fit are copied in @p aLabel ensuring it is null-terminated).
|
|
||||||
* @retval OT_ERROR_INVALID_ARGS SRP service is not a sub-type.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
otError otSrpServerServiceGetServiceSubTypeLabel(const otSrpServerService *aService, char *aLabel, uint8_t aMaxSize);
|
bool otSrpServerServiceMatchesServiceName(const otSrpServerService *aService, const char *aServiceName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of sub-types of the service.
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
*
|
||||||
|
* @returns The number of sub-types of @p aService.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t otSrpServerServiceGetNumberOfSubTypes(const otSrpServerService *aService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sub-type service name (full name) of the service at a given index
|
||||||
|
*
|
||||||
|
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.".
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
* @param[in] aIndex The index to get.
|
||||||
|
*
|
||||||
|
* @returns A pointer to sub-type service name at @p aIndex, or `NULL` if no sub-type at this index.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *otSrpServerServiceGetSubTypeServiceNameAt(const otSrpServerService *aService, uint16_t aIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the service has a given sub-type.
|
||||||
|
*
|
||||||
|
* DNS name matches are performed using a case-insensitive string comparison (i.e., "Abc" and "aBc" are considered to
|
||||||
|
* be the same).
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
* @param[in] aSubTypeServiceName The sub-type service name (full name) to check.
|
||||||
|
*
|
||||||
|
* @retval TRUE Service contains the sub-type @p aSubTypeServiceName.
|
||||||
|
* @retval FALSE Service does not contain the sub-type @p aSubTypeServiceName.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool otSrpServerServiceHasSubTypeServiceName(const otSrpServerService *aService, const char *aSubTypeServiceName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a sub-type service name (full name) and extracts the sub-type label.
|
||||||
|
*
|
||||||
|
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.".
|
||||||
|
*
|
||||||
|
* @param[in] aSubTypeServiceName A sub-type service name (full name).
|
||||||
|
* @param[out] aLabel A pointer to a buffer to copy the extracted sub-type label.
|
||||||
|
* @param[in] aLabelSize Maximum size of @p aLabel buffer.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Name was successfully parsed and @p aLabel was updated.
|
||||||
|
* @retval OT_ERROR_NO_BUFS The sub-type label could not fit in @p aLabel buffer (number of chars from label
|
||||||
|
* that could fit are copied in @p aLabel ensuring it is null-terminated).
|
||||||
|
* @retval OT_ERROR_INVALID_ARGS @p aSubTypeServiceName is not a valid sub-type format.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
otError otSrpServerParseSubTypeServiceName(const char *aSubTypeServiceName, char *aLabel, uint8_t aLabelSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the port of the service instance.
|
* Returns the port of the service instance.
|
||||||
|
|||||||
+16
-18
@@ -270,9 +270,6 @@ void SrpServer::OutputHostAddresses(const otSrpServerHost *aHost)
|
|||||||
|
|
||||||
template <> otError SrpServer::Process<Cmd("service")>(Arg aArgs[])
|
template <> otError SrpServer::Process<Cmd("service")>(Arg aArgs[])
|
||||||
{
|
{
|
||||||
static constexpr char *kAnyServiceName = nullptr;
|
|
||||||
static constexpr char *kAnyInstanceName = nullptr;
|
|
||||||
|
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
const otSrpServerHost *host = nullptr;
|
const otSrpServerHost *host = nullptr;
|
||||||
|
|
||||||
@@ -282,18 +279,15 @@ template <> otError SrpServer::Process<Cmd("service")>(Arg aArgs[])
|
|||||||
{
|
{
|
||||||
const otSrpServerService *service = nullptr;
|
const otSrpServerService *service = nullptr;
|
||||||
|
|
||||||
while ((service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY,
|
while ((service = otSrpServerHostGetNextService(host, service)) != nullptr)
|
||||||
kAnyServiceName, kAnyInstanceName)) != nullptr)
|
|
||||||
{
|
{
|
||||||
bool isDeleted = otSrpServerServiceIsDeleted(service);
|
bool isDeleted = otSrpServerServiceIsDeleted(service);
|
||||||
const char *instanceName = otSrpServerServiceGetInstanceName(service);
|
const uint8_t *txtData;
|
||||||
const otSrpServerService *subService = nullptr;
|
uint16_t txtDataLength;
|
||||||
const uint8_t *txtData;
|
bool hasSubType = false;
|
||||||
uint16_t txtDataLength;
|
otSrpServerLeaseInfo leaseInfo;
|
||||||
bool hasSubType = false;
|
|
||||||
otSrpServerLeaseInfo leaseInfo;
|
|
||||||
|
|
||||||
OutputLine("%s", instanceName);
|
OutputLine("%s", otSrpServerServiceGetInstanceName(service));
|
||||||
OutputLine(kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
|
OutputLine(kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
@@ -305,13 +299,17 @@ template <> otError SrpServer::Process<Cmd("service")>(Arg aArgs[])
|
|||||||
|
|
||||||
OutputFormat(kIndentSize, "subtypes: ");
|
OutputFormat(kIndentSize, "subtypes: ");
|
||||||
|
|
||||||
while ((subService = otSrpServerHostFindNextService(
|
for (uint16_t index = 0;; index++)
|
||||||
host, subService, (OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE),
|
|
||||||
kAnyServiceName, instanceName)) != nullptr)
|
|
||||||
{
|
{
|
||||||
char subLabel[OT_DNS_MAX_LABEL_SIZE];
|
char subLabel[OT_DNS_MAX_LABEL_SIZE];
|
||||||
|
const char *subTypeName = otSrpServerServiceGetSubTypeServiceNameAt(service, index);
|
||||||
|
|
||||||
IgnoreError(otSrpServerServiceGetServiceSubTypeLabel(subService, subLabel, sizeof(subLabel)));
|
if (subTypeName == nullptr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IgnoreError(otSrpServerParseSubTypeServiceName(subTypeName, subLabel, sizeof(subLabel)));
|
||||||
OutputFormat("%s%s", hasSubType ? "," : "", subLabel);
|
OutputFormat("%s%s", hasSubType ? "," : "", subLabel);
|
||||||
hasSubType = true;
|
hasSubType = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost) { return AsCoreType(
|
|||||||
|
|
||||||
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost) { return AsCoreType(aHost).GetFullName(); }
|
const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost) { return AsCoreType(aHost).GetFullName(); }
|
||||||
|
|
||||||
|
bool otSrpServerHostMatchesFullName(const otSrpServerHost *aHost, const char *aFullName)
|
||||||
|
{
|
||||||
|
return AsCoreType(aHost).Matches(aFullName);
|
||||||
|
}
|
||||||
|
|
||||||
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum)
|
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum)
|
||||||
{
|
{
|
||||||
return AsCoreType(aHost).GetAddresses(*aAddressesNum);
|
return AsCoreType(aHost).GetAddresses(*aAddressesNum);
|
||||||
@@ -154,30 +159,24 @@ uint32_t otSrpServerHostGetKeyLease(const otSrpServerHost *aHost) { return AsCor
|
|||||||
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost *aHost,
|
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost *aHost,
|
||||||
const otSrpServerService *aService)
|
const otSrpServerService *aService)
|
||||||
{
|
{
|
||||||
return AsCoreType(aHost).FindNextService(AsCoreTypePtr(aService), Srp::Server::kFlagsBaseTypeServiceOnly);
|
return AsCoreType(aHost).GetNextService(AsCoreTypePtr(aService));
|
||||||
}
|
|
||||||
|
|
||||||
const otSrpServerService *otSrpServerHostFindNextService(const otSrpServerHost *aHost,
|
|
||||||
const otSrpServerService *aPrevService,
|
|
||||||
otSrpServerServiceFlags aFlags,
|
|
||||||
const char *aServiceName,
|
|
||||||
const char *aInstanceName)
|
|
||||||
{
|
|
||||||
return AsCoreType(aHost).FindNextService(AsCoreTypePtr(aPrevService), aFlags, aServiceName, aInstanceName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService) { return AsCoreType(aService).IsDeleted(); }
|
bool otSrpServerServiceIsDeleted(const otSrpServerService *aService) { return AsCoreType(aService).IsDeleted(); }
|
||||||
|
|
||||||
bool otSrpServerServiceIsSubType(const otSrpServerService *aService) { return AsCoreType(aService).IsSubType(); }
|
const char *otSrpServerServiceGetInstanceName(const otSrpServerService *aService)
|
||||||
|
|
||||||
const char *otSrpServerServiceGetFullName(const otSrpServerService *aService)
|
|
||||||
{
|
{
|
||||||
return AsCoreType(aService).GetInstanceName();
|
return AsCoreType(aService).GetInstanceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *otSrpServerServiceGetInstanceName(const otSrpServerService *aService)
|
bool otSrpServerServiceMatchesInstanceName(const otSrpServerService *aService, const char *aInstanceName)
|
||||||
{
|
{
|
||||||
return AsCoreType(aService).GetInstanceName();
|
return AsCoreType(aService).MatchesInstanceName(aInstanceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *otSrpServerServiceGetInstanceLabel(const otSrpServerService *aService)
|
||||||
|
{
|
||||||
|
return AsCoreType(aService).GetInstanceLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *otSrpServerServiceGetServiceName(const otSrpServerService *aService)
|
const char *otSrpServerServiceGetServiceName(const otSrpServerService *aService)
|
||||||
@@ -185,9 +184,29 @@ const char *otSrpServerServiceGetServiceName(const otSrpServerService *aService)
|
|||||||
return AsCoreType(aService).GetServiceName();
|
return AsCoreType(aService).GetServiceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
otError otSrpServerServiceGetServiceSubTypeLabel(const otSrpServerService *aService, char *aLabel, uint8_t aMaxSize)
|
bool otSrpServerServiceMatchesServiceName(const otSrpServerService *aService, const char *aServiceName)
|
||||||
{
|
{
|
||||||
return AsCoreType(aService).GetServiceSubTypeLabel(aLabel, aMaxSize);
|
return AsCoreType(aService).MatchesServiceName(aServiceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t otSrpServerServiceGetNumberOfSubTypes(const otSrpServerService *aService)
|
||||||
|
{
|
||||||
|
return AsCoreType(aService).GetNumberOfSubTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *otSrpServerServiceGetSubTypeServiceNameAt(const otSrpServerService *aService, uint16_t aIndex)
|
||||||
|
{
|
||||||
|
return AsCoreType(aService).GetSubTypeServiceNameAt(aIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool otSrpServerServiceHasSubTypeServiceName(const otSrpServerService *aService, const char *aSubTypeServiceName)
|
||||||
|
{
|
||||||
|
return AsCoreType(aService).HasSubTypeServiceName(aSubTypeServiceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
otError otSrpServerParseSubTypeServiceName(const char *aSubTypeServiceName, char *aLabel, uint8_t aLabelSize)
|
||||||
|
{
|
||||||
|
return Srp::Server::Service::ParseSubTypeServiceName(aSubTypeServiceName, aLabel, aLabelSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t otSrpServerServiceGetPort(const otSrpServerService *aService) { return AsCoreType(aService).GetPort(); }
|
uint16_t otSrpServerServiceGetPort(const otSrpServerService *aService) { return AsCoreType(aService).GetPort(); }
|
||||||
|
|||||||
@@ -754,31 +754,46 @@ Header::Response Server::ResolveQuestionBySrp(const char *aName,
|
|||||||
NameCompressInfo &aCompressInfo,
|
NameCompressInfo &aCompressInfo,
|
||||||
bool aAdditional)
|
bool aAdditional)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
const Srp::Server::Host *host = nullptr;
|
TimeMilli now = TimerMilli::GetNow();
|
||||||
TimeMilli now = TimerMilli::GetNow();
|
uint16_t qtype = aQuestion.GetType();
|
||||||
uint16_t qtype = aQuestion.GetType();
|
Header::Response response = Header::kResponseNameError;
|
||||||
Header::Response response = Header::kResponseNameError;
|
|
||||||
|
|
||||||
while ((host = GetNextSrpHost(host)) != nullptr)
|
for (const Srp::Server::Host &host : Get<Srp::Server>().GetHosts())
|
||||||
{
|
{
|
||||||
bool needAdditionalAaaaRecord = false;
|
bool needAdditionalAaaaRecord = false;
|
||||||
const char *hostName = host->GetFullName();
|
const char *hostName = host.GetFullName();
|
||||||
|
|
||||||
|
if (host.IsDeleted())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle PTR/SRV/TXT query
|
// Handle PTR/SRV/TXT query
|
||||||
if (qtype == ResourceRecord::kTypePtr || qtype == ResourceRecord::kTypeSrv || qtype == ResourceRecord::kTypeTxt)
|
if (qtype == ResourceRecord::kTypePtr || qtype == ResourceRecord::kTypeSrv || qtype == ResourceRecord::kTypeTxt)
|
||||||
{
|
{
|
||||||
const Srp::Server::Service *service = nullptr;
|
for (const Srp::Server::Service &service : host.GetServices())
|
||||||
|
|
||||||
while ((service = GetNextSrpService(*host, service)) != nullptr)
|
|
||||||
{
|
{
|
||||||
uint32_t instanceTtl = TimeMilli::MsecToSec(service->GetExpireTime() - TimerMilli::GetNow());
|
uint32_t instanceTtl;
|
||||||
const char *instanceName = service->GetInstanceName();
|
const char *instanceName;
|
||||||
bool serviceNameMatched = service->MatchesServiceName(aName);
|
bool serviceNameMatched;
|
||||||
bool instanceNameMatched = service->MatchesInstanceName(aName);
|
bool instanceNameMatched;
|
||||||
bool ptrQueryMatched = qtype == ResourceRecord::kTypePtr && serviceNameMatched;
|
bool ptrQueryMatched;
|
||||||
bool srvQueryMatched = qtype == ResourceRecord::kTypeSrv && instanceNameMatched;
|
bool srvQueryMatched;
|
||||||
bool txtQueryMatched = qtype == ResourceRecord::kTypeTxt && instanceNameMatched;
|
bool txtQueryMatched;
|
||||||
|
|
||||||
|
if (service.IsDeleted())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceTtl = TimeMilli::MsecToSec(service.GetExpireTime() - TimerMilli::GetNow());
|
||||||
|
instanceName = service.GetInstanceName();
|
||||||
|
serviceNameMatched = service.MatchesServiceName(aName) || service.HasSubTypeServiceName(aName);
|
||||||
|
instanceNameMatched = service.MatchesInstanceName(aName);
|
||||||
|
ptrQueryMatched = qtype == ResourceRecord::kTypePtr && serviceNameMatched;
|
||||||
|
srvQueryMatched = qtype == ResourceRecord::kTypeSrv && instanceNameMatched;
|
||||||
|
txtQueryMatched = qtype == ResourceRecord::kTypeTxt && instanceNameMatched;
|
||||||
|
|
||||||
if (ptrQueryMatched || srvQueryMatched)
|
if (ptrQueryMatched || srvQueryMatched)
|
||||||
{
|
{
|
||||||
@@ -798,8 +813,8 @@ Header::Response Server::ResolveQuestionBySrp(const char *aName,
|
|||||||
!HasQuestion(aResponseHeader, aResponseMessage, instanceName, ResourceRecord::kTypeSrv)))
|
!HasQuestion(aResponseHeader, aResponseMessage, instanceName, ResourceRecord::kTypeSrv)))
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = AppendSrvRecord(aResponseMessage, instanceName, hostName, instanceTtl,
|
SuccessOrExit(error = AppendSrvRecord(aResponseMessage, instanceName, hostName, instanceTtl,
|
||||||
service->GetPriority(), service->GetWeight(),
|
service.GetPriority(), service.GetWeight(), service.GetPort(),
|
||||||
service->GetPort(), aCompressInfo));
|
aCompressInfo));
|
||||||
IncResourceRecordCount(aResponseHeader, aAdditional);
|
IncResourceRecordCount(aResponseHeader, aAdditional);
|
||||||
response = Header::kResponseSuccess;
|
response = Header::kResponseSuccess;
|
||||||
}
|
}
|
||||||
@@ -808,8 +823,8 @@ Header::Response Server::ResolveQuestionBySrp(const char *aName,
|
|||||||
(aAdditional && ptrQueryMatched &&
|
(aAdditional && ptrQueryMatched &&
|
||||||
!HasQuestion(aResponseHeader, aResponseMessage, instanceName, ResourceRecord::kTypeTxt)))
|
!HasQuestion(aResponseHeader, aResponseMessage, instanceName, ResourceRecord::kTypeTxt)))
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = AppendTxtRecord(aResponseMessage, instanceName, service->GetTxtData(),
|
SuccessOrExit(error = AppendTxtRecord(aResponseMessage, instanceName, service.GetTxtData(),
|
||||||
service->GetTxtDataLength(), instanceTtl, aCompressInfo));
|
service.GetTxtDataLength(), instanceTtl, aCompressInfo));
|
||||||
IncResourceRecordCount(aResponseHeader, aAdditional);
|
IncResourceRecordCount(aResponseHeader, aAdditional);
|
||||||
response = Header::kResponseSuccess;
|
response = Header::kResponseSuccess;
|
||||||
}
|
}
|
||||||
@@ -817,13 +832,13 @@ Header::Response Server::ResolveQuestionBySrp(const char *aName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle AAAA query
|
// Handle AAAA query
|
||||||
if ((!aAdditional && qtype == ResourceRecord::kTypeAaaa && host->Matches(aName)) ||
|
if ((!aAdditional && qtype == ResourceRecord::kTypeAaaa && host.Matches(aName)) ||
|
||||||
(aAdditional && needAdditionalAaaaRecord &&
|
(aAdditional && needAdditionalAaaaRecord &&
|
||||||
!HasQuestion(aResponseHeader, aResponseMessage, hostName, ResourceRecord::kTypeAaaa)))
|
!HasQuestion(aResponseHeader, aResponseMessage, hostName, ResourceRecord::kTypeAaaa)))
|
||||||
{
|
{
|
||||||
uint8_t addrNum;
|
uint8_t addrNum;
|
||||||
const Ip6::Address *addrs = host->GetAddresses(addrNum);
|
const Ip6::Address *addrs = host.GetAddresses(addrNum);
|
||||||
uint32_t hostTtl = TimeMilli::MsecToSec(host->GetExpireTime() - now);
|
uint32_t hostTtl = TimeMilli::MsecToSec(host.GetExpireTime() - now);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < addrNum; i++)
|
for (uint8_t i = 0; i < addrNum; i++)
|
||||||
{
|
{
|
||||||
@@ -839,23 +854,6 @@ exit:
|
|||||||
return error == kErrorNone ? response : Header::kResponseServerFailure;
|
return error == kErrorNone ? response : Header::kResponseServerFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Srp::Server::Host *Server::GetNextSrpHost(const Srp::Server::Host *aHost)
|
|
||||||
{
|
|
||||||
const Srp::Server::Host *host = Get<Srp::Server>().GetNextHost(aHost);
|
|
||||||
|
|
||||||
while (host != nullptr && host->IsDeleted())
|
|
||||||
{
|
|
||||||
host = Get<Srp::Server>().GetNextHost(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Srp::Server::Service *Server::GetNextSrpService(const Srp::Server::Host &aHost,
|
|
||||||
const Srp::Server::Service *aService)
|
|
||||||
{
|
|
||||||
return aHost.FindNextService(aService, Srp::Server::kFlagsAnyTypeActiveService);
|
|
||||||
}
|
|
||||||
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||||
|
|
||||||
Error Server::ResolveByQueryCallbacks(Header &aResponseHeader,
|
Error Server::ResolveByQueryCallbacks(Header &aResponseHeader,
|
||||||
|
|||||||
@@ -485,18 +485,15 @@ private:
|
|||||||
const Ip6::MessageInfo &aMessageInfo,
|
const Ip6::MessageInfo &aMessageInfo,
|
||||||
Ip6::Udp::Socket &aSocket);
|
Ip6::Udp::Socket &aSocket);
|
||||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||||
Header::Response ResolveBySrp(Header &aResponseHeader,
|
Header::Response ResolveBySrp(Header &aResponseHeader,
|
||||||
Message &aResponseMessage,
|
Message &aResponseMessage,
|
||||||
Server::NameCompressInfo &aCompressInfo);
|
Server::NameCompressInfo &aCompressInfo);
|
||||||
Header::Response ResolveQuestionBySrp(const char *aName,
|
Header::Response ResolveQuestionBySrp(const char *aName,
|
||||||
const Question &aQuestion,
|
const Question &aQuestion,
|
||||||
Header &aResponseHeader,
|
Header &aResponseHeader,
|
||||||
Message &aResponseMessage,
|
Message &aResponseMessage,
|
||||||
NameCompressInfo &aCompressInfo,
|
NameCompressInfo &aCompressInfo,
|
||||||
bool aAdditional);
|
bool aAdditional);
|
||||||
const Srp::Server::Host *GetNextSrpHost(const Srp::Server::Host *aHost);
|
|
||||||
static const Srp::Server::Service *GetNextSrpService(const Srp::Server::Host &aHost,
|
|
||||||
const Srp::Server::Service *aService);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||||
|
|||||||
+262
-448
@@ -308,15 +308,6 @@ const Server::Host *Server::GetNextHost(const Server::Host *aHost)
|
|||||||
return (aHost == nullptr) ? mHosts.GetHead() : aHost->GetNext();
|
return (aHost == nullptr) ? mHosts.GetHead() : aHost->GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method adds a SRP service host and takes ownership of it.
|
|
||||||
// The caller MUST make sure that there is no existing host with the same hostname.
|
|
||||||
void Server::AddHost(Host &aHost)
|
|
||||||
{
|
|
||||||
LogInfo("Add new host %s", aHost.GetFullName());
|
|
||||||
|
|
||||||
OT_ASSERT(mHosts.FindMatching(aHost.GetFullName()) == nullptr);
|
|
||||||
IgnoreError(mHosts.Add(aHost));
|
|
||||||
}
|
|
||||||
void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
||||||
{
|
{
|
||||||
VerifyOrExit(aHost != nullptr);
|
VerifyOrExit(aHost != nullptr);
|
||||||
@@ -376,7 +367,7 @@ bool Server::HasNameConflictsWith(Host &aHost) const
|
|||||||
|
|
||||||
for (const Host &host : mHosts)
|
for (const Host &host : mHosts)
|
||||||
{
|
{
|
||||||
if (host.HasServiceInstance(service.GetInstanceName()) &&
|
if (host.HasService(service.GetInstanceName()) &&
|
||||||
aHost.GetKeyRecord()->GetKey() != host.GetKeyRecord()->GetKey())
|
aHost.GetKeyRecord()->GetKey() != host.GetKeyRecord()->GetKey())
|
||||||
{
|
{
|
||||||
LogWarn("Name conflict: service name %s has already been allocated", service.GetInstanceName());
|
LogWarn("Name conflict: service name %s has already been allocated", service.GetInstanceName());
|
||||||
@@ -442,15 +433,18 @@ void Server::CommitSrpUpdate(Error aError,
|
|||||||
const TtlConfig &aTtlConfig,
|
const TtlConfig &aTtlConfig,
|
||||||
const LeaseConfig &aLeaseConfig)
|
const LeaseConfig &aLeaseConfig)
|
||||||
{
|
{
|
||||||
Host *existingHost;
|
Host *existingHost = nullptr;
|
||||||
uint32_t grantedTtl;
|
uint32_t grantedTtl = 0;
|
||||||
uint32_t hostLease = 0;
|
uint32_t hostLease = 0;
|
||||||
uint32_t hostKeyLease = 0;
|
uint32_t hostKeyLease = 0;
|
||||||
uint32_t grantedLease = 0;
|
uint32_t grantedLease = 0;
|
||||||
uint32_t grantedKeyLease = 0;
|
uint32_t grantedKeyLease = 0;
|
||||||
bool shouldFreeHost = true;
|
|
||||||
|
|
||||||
SuccessOrExit(aError);
|
if (aError != kErrorNone)
|
||||||
|
{
|
||||||
|
aHost.Free();
|
||||||
|
ExitNow();
|
||||||
|
}
|
||||||
|
|
||||||
hostLease = aHost.GetLease();
|
hostLease = aHost.GetLease();
|
||||||
hostKeyLease = aHost.GetKeyLease();
|
hostKeyLease = aHost.GetKeyLease();
|
||||||
@@ -458,66 +452,86 @@ void Server::CommitSrpUpdate(Error aError,
|
|||||||
grantedKeyLease = aHost.ShouldUseShortLeaseOption() ? grantedLease : aLeaseConfig.GrantKeyLease(hostKeyLease);
|
grantedKeyLease = aHost.ShouldUseShortLeaseOption() ? grantedLease : aLeaseConfig.GrantKeyLease(hostKeyLease);
|
||||||
grantedTtl = aTtlConfig.GrantTtl(grantedLease, aHost.GetTtl());
|
grantedTtl = aTtlConfig.GrantTtl(grantedLease, aHost.GetTtl());
|
||||||
|
|
||||||
|
existingHost = mHosts.RemoveMatching(aHost.GetFullName());
|
||||||
|
|
||||||
|
LogInfo("Committing update for %s host %s", (existingHost != nullptr) ? "existing" : "new", aHost.GetFullName());
|
||||||
|
LogInfo(" Granted lease:%lu, key-lease:%lu, ttl:%lu", ToUlong(grantedLease), ToUlong(grantedKeyLease),
|
||||||
|
ToUlong(grantedTtl));
|
||||||
|
|
||||||
aHost.SetLease(grantedLease);
|
aHost.SetLease(grantedLease);
|
||||||
aHost.SetKeyLease(grantedKeyLease);
|
aHost.SetKeyLease(grantedKeyLease);
|
||||||
aHost.SetTtl(grantedTtl);
|
aHost.SetTtl(grantedTtl);
|
||||||
|
|
||||||
|
if (grantedKeyLease == 0)
|
||||||
|
{
|
||||||
|
VerifyOrExit(existingHost != nullptr);
|
||||||
|
LogInfo("Fully remove host %s", aHost.GetFullName());
|
||||||
|
ExitNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
mHosts.Push(aHost);
|
||||||
|
|
||||||
for (Service &service : aHost.mServices)
|
for (Service &service : aHost.mServices)
|
||||||
{
|
{
|
||||||
service.mDescription->mLease = grantedLease;
|
service.mLease = grantedLease;
|
||||||
service.mDescription->mKeyLease = grantedKeyLease;
|
service.mKeyLease = grantedKeyLease;
|
||||||
service.mDescription->mTtl = grantedTtl;
|
service.mTtl = grantedTtl;
|
||||||
}
|
service.mIsCommitted = true;
|
||||||
|
|
||||||
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||||
|
|
||||||
if (aHost.GetLease() == 0)
|
|
||||||
{
|
|
||||||
if (aHost.GetKeyLease() == 0)
|
|
||||||
{
|
{
|
||||||
LogInfo("Remove key of host %s", aHost.GetFullName());
|
Service::Action action = Service::kAddNew;
|
||||||
RemoveHost(existingHost, kDeleteName, kDoNotNotifyServiceHandler);
|
|
||||||
}
|
|
||||||
else if (existingHost != nullptr)
|
|
||||||
{
|
|
||||||
existingHost->SetKeyLease(aHost.GetKeyLease());
|
|
||||||
RemoveHost(existingHost, kRetainName, kDoNotNotifyServiceHandler);
|
|
||||||
|
|
||||||
for (Service &service : existingHost->mServices)
|
if (service.mIsDeleted)
|
||||||
{
|
{
|
||||||
existingHost->RemoveService(&service, kRetainName, kDoNotNotifyServiceHandler);
|
action = Service::kRemoveButRetainName;
|
||||||
|
}
|
||||||
|
else if ((existingHost != nullptr) && existingHost->HasService(service.GetInstanceName()))
|
||||||
|
{
|
||||||
|
action = Service::kUpdateExisting;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (existingHost != nullptr)
|
|
||||||
{
|
|
||||||
SuccessOrExit(aError = existingHost->MergeServicesAndResourcesFrom(aHost));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddHost(aHost);
|
|
||||||
shouldFreeHost = false;
|
|
||||||
|
|
||||||
for (Service &service : aHost.GetServices())
|
service.Log(action);
|
||||||
{
|
|
||||||
service.mIsCommitted = true;
|
|
||||||
service.Log(Service::kAddNew);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
|
||||||
if (!mHasRegisteredAnyService && (mAddressMode == kAddressModeUnicast))
|
|
||||||
{
|
|
||||||
Settings::SrpServerInfo info;
|
|
||||||
|
|
||||||
mHasRegisteredAnyService = true;
|
|
||||||
info.SetPort(GetSocket().mSockName.mPort);
|
|
||||||
IgnoreError(Get<Settings>().Save(info));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-schedule the lease timer.
|
if (existingHost != nullptr)
|
||||||
HandleLeaseTimer();
|
{
|
||||||
|
// Move any existing service that is not included in the new
|
||||||
|
// update into `aHost`.
|
||||||
|
|
||||||
|
Service *existingService;
|
||||||
|
|
||||||
|
while ((existingService = existingHost->mServices.Pop()) != nullptr)
|
||||||
|
{
|
||||||
|
if (!aHost.HasService(existingService->GetInstanceName()))
|
||||||
|
{
|
||||||
|
aHost.AddService(*existingService);
|
||||||
|
existingService->Log(Service::kKeepUnchanged);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existingService->Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||||
|
if (!mHasRegisteredAnyService && (mAddressMode == kAddressModeUnicast))
|
||||||
|
{
|
||||||
|
Settings::SrpServerInfo info;
|
||||||
|
|
||||||
|
mHasRegisteredAnyService = true;
|
||||||
|
info.SetPort(GetSocket().mSockName.mPort);
|
||||||
|
IgnoreError(Get<Settings>().Save(info));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!aHost.IsDeleted())
|
||||||
|
{
|
||||||
|
mLeaseTimer.FireAtIfEarlier(Min(aHost.GetExpireTime(), aHost.GetKeyExpireTime()));
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (aMessageInfo != nullptr)
|
if (aMessageInfo != nullptr)
|
||||||
@@ -532,9 +546,9 @@ exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldFreeHost)
|
if (existingHost != nullptr)
|
||||||
{
|
{
|
||||||
aHost.Free();
|
existingHost->Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,8 +760,6 @@ void Server::ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata)
|
|||||||
// Parse lease time and validate signature.
|
// Parse lease time and validate signature.
|
||||||
SuccessOrExit(error = ProcessAdditionalSection(host, aMessage, aMetadata));
|
SuccessOrExit(error = ProcessAdditionalSection(host, aMessage, aMetadata));
|
||||||
|
|
||||||
SuccessOrExit(error = ValidateServiceSubTypes(*host, aMetadata));
|
|
||||||
|
|
||||||
HandleUpdate(*host, aMetadata);
|
HandleUpdate(*host, aMetadata);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -846,7 +858,7 @@ Error Server::ProcessHostDescriptionInstruction(Host &aHost,
|
|||||||
|
|
||||||
// A "Delete All RRsets from a name" RR can only apply to a Service or Host Description.
|
// A "Delete All RRsets from a name" RR can only apply to a Service or Host Description.
|
||||||
|
|
||||||
if (!aHost.HasServiceInstance(name))
|
if (!aHost.HasService(name))
|
||||||
{
|
{
|
||||||
// If host name is already set to a different name, `SetFullName()`
|
// If host name is already set to a different name, `SetFullName()`
|
||||||
// will return `kErrorFailed`.
|
// will return `kErrorFailed`.
|
||||||
@@ -924,6 +936,7 @@ Error Server::ProcessServiceDiscoveryInstructions(Host &aHost,
|
|||||||
const char *subServiceName;
|
const char *subServiceName;
|
||||||
Service *service;
|
Service *service;
|
||||||
bool isSubType;
|
bool isSubType;
|
||||||
|
bool isDelete;
|
||||||
|
|
||||||
SuccessOrExit(error = Dns::Name::ReadName(aMessage, offset, serviceName, sizeof(serviceName)));
|
SuccessOrExit(error = Dns::Name::ReadName(aMessage, offset, serviceName, sizeof(serviceName)));
|
||||||
VerifyOrExit(Dns::Name::IsSubDomainOf(serviceName, GetDomain()), error = kErrorSecurity);
|
VerifyOrExit(Dns::Name::IsSubDomainOf(serviceName, GetDomain()), error = kErrorSecurity);
|
||||||
@@ -944,11 +957,12 @@ Error Server::ProcessServiceDiscoveryInstructions(Host &aHost,
|
|||||||
instanceServiceName, sizeof(instanceServiceName)));
|
instanceServiceName, sizeof(instanceServiceName)));
|
||||||
instanceName.Append("%s.%s", instanceLabel, instanceServiceName);
|
instanceName.Append("%s.%s", instanceLabel, instanceServiceName);
|
||||||
|
|
||||||
VerifyOrExit(ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone ||
|
// Class None indicates "Delete an RR from an RRset".
|
||||||
ptrRecord.GetClass() == aMetadata.mDnsZone.GetClass(),
|
isDelete = (ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone);
|
||||||
error = kErrorFailed);
|
|
||||||
|
|
||||||
// Check if the `serviceName` is a subtype with the name
|
VerifyOrExit(isDelete || ptrRecord.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorParse);
|
||||||
|
|
||||||
|
// Check if the `serviceName` is a sub-type with name
|
||||||
// format: "<sub-label>._sub.<service-labels>.<domain>."
|
// format: "<sub-label>._sub.<service-labels>.<domain>."
|
||||||
|
|
||||||
subServiceName = StringFind(serviceName, kServiceSubTypeLabel, kStringCaseInsensitiveMatch);
|
subServiceName = StringFind(serviceName, kServiceSubTypeLabel, kStringCaseInsensitiveMatch);
|
||||||
@@ -965,22 +979,61 @@ Error Server::ProcessServiceDiscoveryInstructions(Host &aHost,
|
|||||||
VerifyOrExit(Dns::Name::IsSubDomainOf(instanceName.AsCString(), isSubType ? subServiceName : serviceName),
|
VerifyOrExit(Dns::Name::IsSubDomainOf(instanceName.AsCString(), isSubType ? subServiceName : serviceName),
|
||||||
error = kErrorFailed);
|
error = kErrorFailed);
|
||||||
|
|
||||||
// Ensure the same service does not exist already.
|
// Find a matching existing service or allocate a new one.
|
||||||
VerifyOrExit(aHost.FindService(serviceName, instanceName.AsCString()) == nullptr, error = kErrorFailed);
|
|
||||||
|
|
||||||
service =
|
service = aHost.FindService(instanceName.AsCString());
|
||||||
aHost.AddNewService(serviceName, instanceName.AsCString(), instanceLabel, isSubType, aMetadata.mRxTime);
|
|
||||||
VerifyOrExit(service != nullptr, error = kErrorNoBufs);
|
|
||||||
|
|
||||||
// This RR is a "Delete an RR from an RRset" update when the CLASS is NONE.
|
if (service == nullptr)
|
||||||
service->mIsDeleted = (ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone);
|
{
|
||||||
|
service = aHost.AddNewService(instanceName.AsCString(), instanceLabel, aMetadata.mRxTime);
|
||||||
|
VerifyOrExit(service != nullptr, error = kErrorNoBufs);
|
||||||
|
}
|
||||||
|
|
||||||
if (!service->mIsDeleted)
|
if (isSubType)
|
||||||
|
{
|
||||||
|
VerifyOrExit(!service->HasSubTypeServiceName(serviceName), error = kErrorFailed);
|
||||||
|
|
||||||
|
// Ignore a sub-type service delete.
|
||||||
|
|
||||||
|
if (!isDelete)
|
||||||
|
{
|
||||||
|
Heap::String *newSubTypeLabel = service->mSubTypes.PushBack();
|
||||||
|
|
||||||
|
VerifyOrExit(newSubTypeLabel != nullptr, error = kErrorNoBufs);
|
||||||
|
SuccessOrExit(error = newSubTypeLabel->Set(serviceName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Processed PTR record is the base service (not a
|
||||||
|
// sub-type). `mServiceName` is only set when base
|
||||||
|
// service is processed.
|
||||||
|
|
||||||
|
VerifyOrExit(service->mServiceName.IsNull(), error = kErrorFailed);
|
||||||
|
SuccessOrExit(error = service->mServiceName.Set(serviceName));
|
||||||
|
service->mIsDeleted = isDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDelete)
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = aHost.ProcessTtl(ptrRecord.GetTtl()));
|
SuccessOrExit(error = aHost.ProcessTtl(ptrRecord.GetTtl()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that for all services, a PTR record was processed for
|
||||||
|
// the base service (`mServiceName` is set), and for a deleted
|
||||||
|
// service, no PTR record was seen adding a sub-type.
|
||||||
|
|
||||||
|
for (const Service &service : aHost.mServices)
|
||||||
|
{
|
||||||
|
VerifyOrExit(!service.mServiceName.IsNull(), error = kErrorParse);
|
||||||
|
|
||||||
|
if (service.mIsDeleted)
|
||||||
|
{
|
||||||
|
VerifyOrExit(service.mSubTypes.GetLength() == 0, error = kErrorParse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (error != kErrorNone)
|
if (error != kErrorNone)
|
||||||
{
|
{
|
||||||
@@ -999,9 +1052,9 @@ Error Server::ProcessServiceDescriptionInstructions(Host &aHost,
|
|||||||
|
|
||||||
for (uint16_t numRecords = aMetadata.mDnsHeader.GetUpdateRecordCount(); numRecords > 0; numRecords--)
|
for (uint16_t numRecords = aMetadata.mDnsHeader.GetUpdateRecordCount(); numRecords > 0; numRecords--)
|
||||||
{
|
{
|
||||||
RetainPtr<Service::Description> desc;
|
char name[Dns::Name::kMaxNameSize];
|
||||||
char name[Dns::Name::kMaxNameSize];
|
Dns::ResourceRecord record;
|
||||||
Dns::ResourceRecord record;
|
Service *service;
|
||||||
|
|
||||||
SuccessOrExit(error = Dns::Name::ReadName(aMessage, offset, name, sizeof(name)));
|
SuccessOrExit(error = Dns::Name::ReadName(aMessage, offset, name, sizeof(name)));
|
||||||
SuccessOrExit(error = aMessage.Read(offset, record));
|
SuccessOrExit(error = aMessage.Read(offset, record));
|
||||||
@@ -1011,12 +1064,12 @@ Error Server::ProcessServiceDescriptionInstructions(Host &aHost,
|
|||||||
// Delete All RRsets from a name.
|
// Delete All RRsets from a name.
|
||||||
VerifyOrExit(IsValidDeleteAllRecord(record), error = kErrorFailed);
|
VerifyOrExit(IsValidDeleteAllRecord(record), error = kErrorFailed);
|
||||||
|
|
||||||
desc = aHost.FindServiceDescription(name);
|
service = aHost.FindService(name);
|
||||||
|
|
||||||
if (desc != nullptr)
|
if (service != nullptr)
|
||||||
{
|
{
|
||||||
desc->ClearResources();
|
VerifyOrExit(!service->mParsedDeleteAllRrset);
|
||||||
desc->mUpdateTime = aMetadata.mRxTime;
|
service->mParsedDeleteAllRrset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += record.GetSize();
|
offset += record.GetSize();
|
||||||
@@ -1040,16 +1093,16 @@ Error Server::ProcessServiceDescriptionInstructions(Host &aHost,
|
|||||||
VerifyOrExit(Dns::Name::IsSubDomainOf(name, GetDomain()), error = kErrorSecurity);
|
VerifyOrExit(Dns::Name::IsSubDomainOf(name, GetDomain()), error = kErrorSecurity);
|
||||||
VerifyOrExit(aHost.Matches(hostName), error = kErrorFailed);
|
VerifyOrExit(aHost.Matches(hostName), error = kErrorFailed);
|
||||||
|
|
||||||
desc = aHost.FindServiceDescription(name);
|
service = aHost.FindService(name);
|
||||||
VerifyOrExit(desc != nullptr, error = kErrorFailed);
|
VerifyOrExit(service != nullptr, error = kErrorFailed);
|
||||||
|
|
||||||
// Make sure that this is the first SRV RR for this service description
|
VerifyOrExit(!service->mParsedSrv, error = kErrorParse);
|
||||||
VerifyOrExit(desc->mPort == 0, error = kErrorFailed);
|
service->mParsedSrv = true;
|
||||||
desc->mTtl = srvRecord.GetTtl();
|
|
||||||
desc->mPriority = srvRecord.GetPriority();
|
service->mTtl = srvRecord.GetTtl();
|
||||||
desc->mWeight = srvRecord.GetWeight();
|
service->mPriority = srvRecord.GetPriority();
|
||||||
desc->mPort = srvRecord.GetPort();
|
service->mWeight = srvRecord.GetWeight();
|
||||||
desc->mUpdateTime = aMetadata.mRxTime;
|
service->mPort = srvRecord.GetPort();
|
||||||
}
|
}
|
||||||
else if (record.GetType() == Dns::ResourceRecord::kTypeTxt)
|
else if (record.GetType() == Dns::ResourceRecord::kTypeTxt)
|
||||||
{
|
{
|
||||||
@@ -1057,11 +1110,13 @@ Error Server::ProcessServiceDescriptionInstructions(Host &aHost,
|
|||||||
|
|
||||||
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||||
|
|
||||||
desc = aHost.FindServiceDescription(name);
|
service = aHost.FindService(name);
|
||||||
VerifyOrExit(desc != nullptr, error = kErrorFailed);
|
VerifyOrExit(service != nullptr, error = kErrorFailed);
|
||||||
|
|
||||||
|
service->mParsedTxt = true;
|
||||||
|
|
||||||
offset += sizeof(record);
|
offset += sizeof(record);
|
||||||
SuccessOrExit(error = desc->SetTxtDataFromMessage(aMessage, offset, record.GetLength()));
|
SuccessOrExit(error = service->SetTxtDataFromMessage(aMessage, offset, record.GetLength()));
|
||||||
offset += record.GetLength();
|
offset += record.GetLength();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1070,20 +1125,15 @@ Error Server::ProcessServiceDescriptionInstructions(Host &aHost,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that all service descriptions on `aHost` are updated. Note
|
for (const Service &service : aHost.mServices)
|
||||||
// that `mUpdateTime` on a new `Service::Description` is set to
|
|
||||||
// `GetNow().GetDistantPast()`.
|
|
||||||
|
|
||||||
for (Service &service : aHost.mServices)
|
|
||||||
{
|
{
|
||||||
VerifyOrExit(service.mDescription->mUpdateTime == aMetadata.mRxTime, error = kErrorFailed);
|
VerifyOrExit(service.mParsedDeleteAllRrset, error = kErrorFailed);
|
||||||
|
VerifyOrExit(service.mParsedSrv == service.mParsedTxt, error = kErrorFailed);
|
||||||
|
|
||||||
// Check that either both `mPort` and `mTxtData` are set
|
if (!service.mIsDeleted)
|
||||||
// (i.e., we saw both SRV and TXT record) or both are default
|
{
|
||||||
// (cleared) value (i.e., we saw neither of them).
|
VerifyOrExit(service.mParsedSrv, error = kErrorFailed);
|
||||||
|
}
|
||||||
VerifyOrExit((service.mDescription->mPort == 0) == service.mDescription->mTxtData.IsNull(),
|
|
||||||
error = kErrorFailed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aMetadata.mOffset = offset;
|
aMetadata.mOffset = offset;
|
||||||
@@ -1235,68 +1285,6 @@ exit:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Server::ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata)
|
|
||||||
{
|
|
||||||
Error error = kErrorNone;
|
|
||||||
Host *existingHost;
|
|
||||||
|
|
||||||
// Verify that there is a matching base type service for all
|
|
||||||
// sub-type services in `aHost` (which is from the received
|
|
||||||
// and parsed SRP Update message).
|
|
||||||
|
|
||||||
for (const Service &service : aHost.GetServices())
|
|
||||||
{
|
|
||||||
if (service.IsSubType() && (aHost.FindBaseService(service.GetInstanceName()) == nullptr))
|
|
||||||
{
|
|
||||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
|
|
||||||
char subLabel[Dns::Name::kMaxLabelSize];
|
|
||||||
|
|
||||||
IgnoreError(service.GetServiceSubTypeLabel(subLabel, sizeof(subLabel)));
|
|
||||||
LogWarn("Message contains instance %s with subtype %s without base type", service.GetInstanceName(),
|
|
||||||
subLabel);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ExitNow(error = kErrorParse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SRP server must treat the update instructions for a service type
|
|
||||||
// and all its sub-types as atomic, i.e., when a service and its
|
|
||||||
// sub-types are being updated, whatever information appears in the
|
|
||||||
// SRP Update is the entirety of information about that service and
|
|
||||||
// its sub-types. Any previously registered sub-type that does not
|
|
||||||
// appear in a new SRP Update, must be removed.
|
|
||||||
//
|
|
||||||
// We go though the list of registered services for the same host
|
|
||||||
// and if the base service is included in the new SRP Update
|
|
||||||
// message, we add any previously registered service sub-type that
|
|
||||||
// does not appear in new Update message as "deleted".
|
|
||||||
|
|
||||||
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
|
||||||
VerifyOrExit(existingHost != nullptr);
|
|
||||||
|
|
||||||
for (const Service &baseService : existingHost->GetServices())
|
|
||||||
{
|
|
||||||
if (baseService.IsSubType() || (aHost.FindBaseService(baseService.GetInstanceName()) == nullptr))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const Service &subService : existingHost->GetServices())
|
|
||||||
{
|
|
||||||
if (!subService.IsSubType() || !subService.MatchesInstanceName(baseService.GetInstanceName()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(subService, aMetadata.mRxTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
@@ -1315,14 +1303,21 @@ void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
|||||||
// when removing a host. We copy and append any missing services to
|
// when removing a host. We copy and append any missing services to
|
||||||
// `aHost` from the `existingHost` and mark them as deleted.
|
// `aHost` from the `existingHost` and mark them as deleted.
|
||||||
|
|
||||||
for (Service &service : existingHost->mServices)
|
for (const Service &existingService : existingHost->mServices)
|
||||||
{
|
{
|
||||||
if (service.mIsDeleted)
|
Service *service;
|
||||||
|
|
||||||
|
if (existingService.mIsDeleted || aHost.HasService(existingService.GetInstanceName()))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(service, aMetadata.mRxTime));
|
service = aHost.AddNewService(existingService.GetInstanceName(), existingService.GetInstanceLabel(),
|
||||||
|
aMetadata.mRxTime);
|
||||||
|
VerifyOrExit(service != nullptr, error = kErrorNoBufs);
|
||||||
|
|
||||||
|
SuccessOrExit(error = service->mServiceName.Set(existingService.GetServiceName()));
|
||||||
|
service->mIsDeleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -1337,7 +1332,7 @@ void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const Messag
|
|||||||
uint8_t numAddrs;
|
uint8_t numAddrs;
|
||||||
const Ip6::Address *addrs;
|
const Ip6::Address *addrs;
|
||||||
|
|
||||||
LogInfo("Processed DNS update info");
|
LogInfo("Processed SRP update info");
|
||||||
LogInfo(" Host:%s", aHost.GetFullName());
|
LogInfo(" Host:%s", aHost.GetFullName());
|
||||||
LogInfo(" Lease:%lu, key-lease:%lu, ttl:%lu", ToUlong(aHost.GetLease()), ToUlong(aHost.GetKeyLease()),
|
LogInfo(" Lease:%lu, key-lease:%lu, ttl:%lu", ToUlong(aHost.GetLease()), ToUlong(aHost.GetKeyLease()),
|
||||||
ToUlong(aHost.GetTtl()));
|
ToUlong(aHost.GetTtl()));
|
||||||
@@ -1358,19 +1353,22 @@ void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const Messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Service &service : aHost.GetServices())
|
for (const Service &service : aHost.mServices)
|
||||||
{
|
{
|
||||||
char subLabel[Dns::Name::kMaxLabelSize];
|
LogInfo(" %s service '%s'", service.IsDeleted() ? "Deleting" : "Adding", service.GetInstanceName());
|
||||||
|
|
||||||
IgnoreError(service.GetServiceSubTypeLabel(subLabel, sizeof(subLabel)));
|
for (const Heap::String &subType : service.mSubTypes)
|
||||||
|
{
|
||||||
|
char label[Dns::Name::kMaxLabelSize];
|
||||||
|
|
||||||
LogInfo(" %s service '%s'%s%s", service.IsDeleted() ? "Deleting" : "Adding", service.GetInstanceName(),
|
IgnoreError(Service::ParseSubTypeServiceName(subType.AsCString(), label, sizeof(label)));
|
||||||
service.IsSubType() ? " subtype:" : "", subLabel);
|
LogInfo(" sub-type: %s", label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogInfo("Error %s processing received DNS update", ErrorToString(aError));
|
LogInfo("Error %s processing received SRP update", ErrorToString(aError));
|
||||||
}
|
}
|
||||||
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||||
|
|
||||||
@@ -1705,43 +1703,63 @@ void Server::UpdateResponseCounters(Dns::UpdateHeader::Response aResponseCode)
|
|||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
// Server::Service
|
// Server::Service
|
||||||
|
|
||||||
Error Server::Service::Init(const char *aServiceName, Description &aDescription, bool aIsSubType, TimeMilli aUpdateTime)
|
Error Server::Service::Init(const char *aInstanceName, const char *aInstanceLabel, Host &aHost, TimeMilli aUpdateTime)
|
||||||
{
|
{
|
||||||
mDescription.Reset(&aDescription);
|
Error error;
|
||||||
|
|
||||||
mNext = nullptr;
|
mNext = nullptr;
|
||||||
|
mHost = &aHost;
|
||||||
|
mPriority = 0;
|
||||||
|
mWeight = 0;
|
||||||
|
mTtl = 0;
|
||||||
|
mPort = 0;
|
||||||
|
mLease = 0;
|
||||||
|
mKeyLease = 0;
|
||||||
mUpdateTime = aUpdateTime;
|
mUpdateTime = aUpdateTime;
|
||||||
mIsDeleted = false;
|
mIsDeleted = false;
|
||||||
mIsSubType = aIsSubType;
|
|
||||||
mIsCommitted = false;
|
mIsCommitted = false;
|
||||||
|
|
||||||
return mServiceName.Set(aServiceName);
|
mParsedDeleteAllRrset = false;
|
||||||
|
mParsedSrv = false;
|
||||||
|
mParsedTxt = false;
|
||||||
|
|
||||||
|
SuccessOrExit(error = mInstanceLabel.Set(aInstanceLabel));
|
||||||
|
error = mInstanceName.Set(aInstanceName);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Server::Service::GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const
|
const char *Server::Service::GetSubTypeServiceNameAt(uint16_t aIndex) const
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
const Heap::String *subType = mSubTypes.At(aIndex);
|
||||||
const char *serviceName = GetServiceName();
|
|
||||||
const char *subServiceName;
|
return (subType == nullptr) ? nullptr : subType->AsCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Server::Service::ParseSubTypeServiceName(const char *aSubTypeServiceName, char *aLabel, uint8_t aLabelSize)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
const char *subPos;
|
||||||
uint8_t labelLength;
|
uint8_t labelLength;
|
||||||
|
|
||||||
memset(aLabel, 0, aMaxSize);
|
aLabel[0] = kNullChar;
|
||||||
|
|
||||||
VerifyOrExit(IsSubType(), error = kErrorInvalidArgs);
|
subPos = StringFind(aSubTypeServiceName, kServiceSubTypeLabel, kStringCaseInsensitiveMatch);
|
||||||
|
VerifyOrExit(subPos != nullptr, error = kErrorInvalidArgs);
|
||||||
|
|
||||||
subServiceName = StringFind(serviceName, kServiceSubTypeLabel, kStringCaseInsensitiveMatch);
|
if (subPos - aSubTypeServiceName < aLabelSize)
|
||||||
OT_ASSERT(subServiceName != nullptr);
|
|
||||||
|
|
||||||
if (subServiceName - serviceName < aMaxSize)
|
|
||||||
{
|
{
|
||||||
labelLength = static_cast<uint8_t>(subServiceName - serviceName);
|
labelLength = static_cast<uint8_t>(subPos - aSubTypeServiceName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
labelLength = aMaxSize - 1;
|
labelLength = aLabelSize - 1;
|
||||||
error = kErrorNoBufs;
|
error = kErrorNoBufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(aLabel, serviceName, labelLength);
|
memcpy(aLabel, aSubTypeServiceName, labelLength);
|
||||||
|
aLabel[labelLength] = kNullChar;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return error;
|
return error;
|
||||||
@@ -1752,13 +1770,10 @@ TimeMilli Server::Service::GetExpireTime(void) const
|
|||||||
OT_ASSERT(!mIsDeleted);
|
OT_ASSERT(!mIsDeleted);
|
||||||
OT_ASSERT(!GetHost().IsDeleted());
|
OT_ASSERT(!GetHost().IsDeleted());
|
||||||
|
|
||||||
return mUpdateTime + Time::SecToMsec(mDescription->mLease);
|
return mUpdateTime + Time::SecToMsec(mLease);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeMilli Server::Service::GetKeyExpireTime(void) const
|
TimeMilli Server::Service::GetKeyExpireTime(void) const { return mUpdateTime + Time::SecToMsec(mKeyLease); }
|
||||||
{
|
|
||||||
return mUpdateTime + Time::SecToMsec(mDescription->mKeyLease);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::Service::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
void Server::Service::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
||||||
{
|
{
|
||||||
@@ -1781,42 +1796,32 @@ void Server::Service::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::Service::MatchesInstanceName(const char *aInstanceName) const
|
bool Server::Service::MatchesInstanceName(const char *aInstanceName) const { return Matches(aInstanceName); }
|
||||||
{
|
|
||||||
return StringMatch(mDescription->mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::Service::MatchesServiceName(const char *aServiceName) const
|
bool Server::Service::MatchesServiceName(const char *aServiceName) const
|
||||||
{
|
{
|
||||||
return StringMatch(mServiceName.AsCString(), aServiceName, kStringCaseInsensitiveMatch);
|
return StringMatch(mServiceName.AsCString(), aServiceName, kStringCaseInsensitiveMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::Service::MatchesFlags(Flags aFlags) const
|
bool Server::Service::Matches(const char *aInstanceName) const
|
||||||
{
|
{
|
||||||
bool matches = false;
|
return StringMatch(mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsSubType())
|
bool Server::Service::HasSubTypeServiceName(const char *aSubTypeServiceName) const
|
||||||
|
{
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
for (const Heap::String &subType : mSubTypes)
|
||||||
{
|
{
|
||||||
VerifyOrExit(aFlags & kFlagSubType);
|
if (StringMatch(subType.AsCString(), aSubTypeServiceName, kStringCaseInsensitiveMatch))
|
||||||
}
|
{
|
||||||
else
|
has = true;
|
||||||
{
|
break;
|
||||||
VerifyOrExit(aFlags & kFlagBaseType);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDeleted())
|
return has;
|
||||||
{
|
|
||||||
VerifyOrExit(aFlags & kFlagDeleted);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VerifyOrExit(aFlags & kFlagActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
matches = true;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return matches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||||
@@ -1825,20 +1830,20 @@ void Server::Service::Log(Action aAction) const
|
|||||||
static const char *const kActionStrings[] = {
|
static const char *const kActionStrings[] = {
|
||||||
"Add new", // (0) kAddNew
|
"Add new", // (0) kAddNew
|
||||||
"Update existing", // (1) kUpdateExisting
|
"Update existing", // (1) kUpdateExisting
|
||||||
"Remove but retain name of", // (2) kRemoveButRetainName
|
"Keep unchanged", // (2) kKeepUnchanged
|
||||||
"Fully remove", // (3) kFullyRemove
|
"Remove but retain name of", // (3) kRemoveButRetainName
|
||||||
"LEASE expired for", // (4) kLeaseExpired
|
"Fully remove", // (4) kFullyRemove
|
||||||
"KEY LEASE expired for", // (5) kKeyLeaseExpired
|
"LEASE expired for", // (5) kLeaseExpired
|
||||||
|
"KEY LEASE expired for", // (6) kKeyLeaseExpired
|
||||||
};
|
};
|
||||||
|
|
||||||
char subLabel[Dns::Name::kMaxLabelSize];
|
|
||||||
|
|
||||||
static_assert(0 == kAddNew, "kAddNew value is incorrect");
|
static_assert(0 == kAddNew, "kAddNew value is incorrect");
|
||||||
static_assert(1 == kUpdateExisting, "kUpdateExisting value is incorrect");
|
static_assert(1 == kUpdateExisting, "kUpdateExisting value is incorrect");
|
||||||
static_assert(2 == kRemoveButRetainName, "kRemoveButRetainName value is incorrect");
|
static_assert(2 == kKeepUnchanged, "kKeepUnchanged value is incorrect");
|
||||||
static_assert(3 == kFullyRemove, "kFullyRemove value is incorrect");
|
static_assert(3 == kRemoveButRetainName, "kRemoveButRetainName value is incorrect");
|
||||||
static_assert(4 == kLeaseExpired, "kLeaseExpired value is incorrect");
|
static_assert(4 == kFullyRemove, "kFullyRemove value is incorrect");
|
||||||
static_assert(5 == kKeyLeaseExpired, "kKeyLeaseExpired value is incorrect");
|
static_assert(5 == kLeaseExpired, "kLeaseExpired value is incorrect");
|
||||||
|
static_assert(6 == kKeyLeaseExpired, "kKeyLeaseExpired value is incorrect");
|
||||||
|
|
||||||
// We only log if the `Service` is marked as committed. This
|
// We only log if the `Service` is marked as committed. This
|
||||||
// ensures that temporary `Service` entries associated with a
|
// ensures that temporary `Service` entries associated with a
|
||||||
@@ -1847,67 +1852,22 @@ void Server::Service::Log(Action aAction) const
|
|||||||
|
|
||||||
if (mIsCommitted)
|
if (mIsCommitted)
|
||||||
{
|
{
|
||||||
IgnoreError(GetServiceSubTypeLabel(subLabel, sizeof(subLabel)));
|
LogInfo("%s service '%s'", kActionStrings[aAction], GetInstanceName());
|
||||||
|
|
||||||
LogInfo("%s service '%s'%s%s", kActionStrings[aAction], GetInstanceName(), IsSubType() ? " subtype:" : "",
|
for (const Heap::String &subType : mSubTypes)
|
||||||
subLabel);
|
{
|
||||||
|
char label[Dns::Name::kMaxLabelSize];
|
||||||
|
|
||||||
|
IgnoreError(ParseSubTypeServiceName(subType.AsCString(), label, sizeof(label)));
|
||||||
|
LogInfo(" sub-type: %s", subType.AsCString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void Server::Service::Log(Action) const {}
|
void Server::Service::Log(Action) const {}
|
||||||
#endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
#endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
Error Server::Service::SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
||||||
// Server::Service::Description
|
|
||||||
|
|
||||||
Error Server::Service::Description::Init(const char *aInstanceName, const char *aInstanceLabel, Host &aHost)
|
|
||||||
{
|
|
||||||
Error error;
|
|
||||||
|
|
||||||
mNext = nullptr;
|
|
||||||
mHost = &aHost;
|
|
||||||
mPriority = 0;
|
|
||||||
mWeight = 0;
|
|
||||||
mTtl = 0;
|
|
||||||
mPort = 0;
|
|
||||||
mLease = 0;
|
|
||||||
mKeyLease = 0;
|
|
||||||
mUpdateTime = TimerMilli::GetNow().GetDistantPast();
|
|
||||||
mTxtData.Free();
|
|
||||||
|
|
||||||
SuccessOrExit(error = mInstanceLabel.Set(aInstanceLabel));
|
|
||||||
error = mInstanceName.Set(aInstanceName);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::Service::Description::Matches(const char *aInstanceName) const
|
|
||||||
{
|
|
||||||
return StringMatch(mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::Service::Description::ClearResources(void)
|
|
||||||
{
|
|
||||||
mPort = 0;
|
|
||||||
mTxtData.Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::Service::Description::TakeResourcesFrom(Description &aDescription)
|
|
||||||
{
|
|
||||||
mTxtData.SetFrom(static_cast<Heap::Data &&>(aDescription.mTxtData));
|
|
||||||
|
|
||||||
mPriority = aDescription.mPriority;
|
|
||||||
mWeight = aDescription.mWeight;
|
|
||||||
mPort = aDescription.mPort;
|
|
||||||
|
|
||||||
mTtl = aDescription.mTtl;
|
|
||||||
mLease = aDescription.mLease;
|
|
||||||
mKeyLease = aDescription.mKeyLease;
|
|
||||||
mUpdateTime = TimerMilli::GetNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Server::Service::Description::SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
@@ -2022,64 +1982,28 @@ exit:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Server::Service *Server::Host::FindNextService(const Service *aPrevService,
|
const Server::Service *Server::Host::GetNextService(const Service *aPrevService) const
|
||||||
Service::Flags aFlags,
|
|
||||||
const char *aServiceName,
|
|
||||||
const char *aInstanceName) const
|
|
||||||
{
|
{
|
||||||
const Service *service = (aPrevService == nullptr) ? GetServices().GetHead() : aPrevService->GetNext();
|
return (aPrevService == nullptr) ? mServices.GetHead() : aPrevService->GetNext();
|
||||||
|
|
||||||
for (; service != nullptr; service = service->GetNext())
|
|
||||||
{
|
|
||||||
if (!service->MatchesFlags(aFlags))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((aServiceName != nullptr) && !service->MatchesServiceName(aServiceName))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((aInstanceName != nullptr) && !service->MatchesInstanceName(aInstanceName))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return service;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Service *Server::Host::AddNewService(const char *aServiceName,
|
Server::Service *Server::Host::AddNewService(const char *aInstanceName,
|
||||||
const char *aInstanceName,
|
|
||||||
const char *aInstanceLabel,
|
const char *aInstanceLabel,
|
||||||
bool aIsSubType,
|
|
||||||
TimeMilli aUpdateTime)
|
TimeMilli aUpdateTime)
|
||||||
{
|
{
|
||||||
Service *service = nullptr;
|
Service *service = Service::AllocateAndInit(aInstanceName, aInstanceLabel, *this, aUpdateTime);
|
||||||
RetainPtr<Service::Description> desc(FindServiceDescription(aInstanceName));
|
|
||||||
|
|
||||||
if (desc == nullptr)
|
|
||||||
{
|
|
||||||
desc.Reset(Service::Description::AllocateAndInit(aInstanceName, aInstanceLabel, *this));
|
|
||||||
VerifyOrExit(desc != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
service = Service::AllocateAndInit(aServiceName, *desc, aIsSubType, aUpdateTime);
|
|
||||||
VerifyOrExit(service != nullptr);
|
VerifyOrExit(service != nullptr);
|
||||||
|
AddService(*service);
|
||||||
mServices.Push(*service);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Service *Server::Host::AddNewService(const Service &aService, TimeMilli aUpdateTime)
|
void Server::Host::AddService(Service &aService)
|
||||||
{
|
{
|
||||||
return AddNewService(aService.GetServiceName(), aService.GetInstanceName(), aService.GetInstanceLabel(),
|
aService.mHost = this;
|
||||||
aService.IsSubType(), aUpdateTime);
|
mServices.Push(aService);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Host::RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
void Server::Host::RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
||||||
@@ -2115,24 +2039,6 @@ exit:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Server::Host::AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime)
|
|
||||||
{
|
|
||||||
Error error = kErrorNone;
|
|
||||||
Service *newService;
|
|
||||||
|
|
||||||
VerifyOrExit(FindService(aService.GetServiceName(), aService.GetInstanceName()) == nullptr);
|
|
||||||
|
|
||||||
newService = AddNewService(aService, aUpdateTime);
|
|
||||||
|
|
||||||
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
|
||||||
|
|
||||||
newService->mDescription->mUpdateTime = aUpdateTime;
|
|
||||||
newService->mIsDeleted = true;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::Host::FreeAllServices(void)
|
void Server::Host::FreeAllServices(void)
|
||||||
{
|
{
|
||||||
while (!mServices.IsEmpty())
|
while (!mServices.IsEmpty())
|
||||||
@@ -2143,106 +2049,14 @@ void Server::Host::FreeAllServices(void)
|
|||||||
|
|
||||||
void Server::Host::ClearResources(void) { mAddresses.Free(); }
|
void Server::Host::ClearResources(void) { mAddresses.Free(); }
|
||||||
|
|
||||||
Error Server::Host::MergeServicesAndResourcesFrom(Host &aHost)
|
Server::Service *Server::Host::FindService(const char *aInstanceName) { return mServices.FindMatching(aInstanceName); }
|
||||||
|
|
||||||
|
const Server::Service *Server::Host::FindService(const char *aInstanceName) const
|
||||||
{
|
{
|
||||||
// This method merges services, service descriptions, and other
|
return mServices.FindMatching(aInstanceName);
|
||||||
// resources from another `aHost` into current host. It can
|
|
||||||
// possibly take ownership of some items from `aHost`.
|
|
||||||
|
|
||||||
Error error = kErrorNone;
|
|
||||||
|
|
||||||
LogInfo("Update host %s", GetFullName());
|
|
||||||
|
|
||||||
mAddresses.TakeFrom(static_cast<Heap::Array<Ip6::Address> &&>(aHost.mAddresses));
|
|
||||||
mKeyRecord = aHost.mKeyRecord;
|
|
||||||
mTtl = aHost.mTtl;
|
|
||||||
mLease = aHost.mLease;
|
|
||||||
mKeyLease = aHost.mKeyLease;
|
|
||||||
mUpdateTime = TimerMilli::GetNow();
|
|
||||||
|
|
||||||
for (Service &service : aHost.mServices)
|
|
||||||
{
|
|
||||||
Service *existingService = FindService(service.GetServiceName(), service.GetInstanceName());
|
|
||||||
Service *newService;
|
|
||||||
|
|
||||||
if (service.mIsDeleted)
|
|
||||||
{
|
|
||||||
// `RemoveService()` does nothing if `existingService` is `nullptr`.
|
|
||||||
RemoveService(existingService, kRetainName, kDoNotNotifyServiceHandler);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add/Merge `service` into the existing service or a allocate a new one
|
|
||||||
|
|
||||||
newService = (existingService != nullptr) ? existingService : AddNewService(service, service.GetUpdateTime());
|
|
||||||
|
|
||||||
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
|
||||||
|
|
||||||
newService->mIsDeleted = false;
|
|
||||||
newService->mIsCommitted = true;
|
|
||||||
newService->mUpdateTime = TimerMilli::GetNow();
|
|
||||||
|
|
||||||
if (!service.mIsSubType)
|
|
||||||
{
|
|
||||||
// (1) Service description is shared across a base type and all its subtypes.
|
|
||||||
// (2) `TakeResourcesFrom()` releases resources pinned to its argument.
|
|
||||||
// Therefore, make sure the function is called only for the base type.
|
|
||||||
newService->mDescription->TakeResourcesFrom(*service.mDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
newService->Log((existingService != nullptr) ? Service::kUpdateExisting : Service::kAddNew);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::Host::HasServiceInstance(const char *aInstanceName) const
|
bool Server::Host::HasService(const char *aInstanceName) const { return mServices.ContainsMatching(aInstanceName); }
|
||||||
{
|
|
||||||
return (FindServiceDescription(aInstanceName) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
const RetainPtr<Server::Service::Description> Server::Host::FindServiceDescription(const char *aInstanceName) const
|
|
||||||
{
|
|
||||||
const Service::Description *desc = nullptr;
|
|
||||||
|
|
||||||
for (const Service &service : mServices)
|
|
||||||
{
|
|
||||||
if (service.mDescription->Matches(aInstanceName))
|
|
||||||
{
|
|
||||||
desc = service.mDescription.Get();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RetainPtr<Service::Description>(AsNonConst(desc));
|
|
||||||
}
|
|
||||||
|
|
||||||
RetainPtr<Server::Service::Description> Server::Host::FindServiceDescription(const char *aInstanceName)
|
|
||||||
{
|
|
||||||
return AsNonConst(AsConst(this)->FindServiceDescription(aInstanceName));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Server::Service *Server::Host::FindService(const char *aServiceName, const char *aInstanceName) const
|
|
||||||
{
|
|
||||||
return FindNextService(/* aPrevService */ nullptr, kFlagsAnyService, aServiceName, aInstanceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Server::Service *Server::Host::FindService(const char *aServiceName, const char *aInstanceName)
|
|
||||||
{
|
|
||||||
return AsNonConst(AsConst(this)->FindService(aServiceName, aInstanceName));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Server::Service *Server::Host::FindBaseService(const char *aInstanceName) const
|
|
||||||
{
|
|
||||||
return FindNextService(/*a PrevService */ nullptr, kFlagsBaseTypeServiceOnly, /* aServiceName */ nullptr,
|
|
||||||
aInstanceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Server::Service *Server::Host::FindBaseService(const char *aInstanceName)
|
|
||||||
{
|
|
||||||
return AsNonConst(AsConst(this)->FindBaseService(aInstanceName));
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Server::Host::AddIp6Address(const Ip6::Address &aIp6Address)
|
Error Server::Host::AddIp6Address(const Ip6::Address &aIp6Address)
|
||||||
{
|
{
|
||||||
|
|||||||
+99
-165
@@ -187,37 +187,6 @@ public:
|
|||||||
friend class Heap::Allocatable<Service>;
|
friend class Heap::Allocatable<Service>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Represents the flags which indicates which services to include or exclude when searching in (or
|
|
||||||
* iterating over) the list of SRP services.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef otSrpServerServiceFlags Flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This `Flags` constant indicates to include base services (not a sub-type).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Flags kFlagBaseType = OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This `Flags` constant indicates to include sub-type services.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Flags kFlagSubType = OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This `Flags` constant indicates to include active (not deleted) services.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Flags kFlagActive = OT_SRP_SERVER_SERVICE_FLAG_ACTIVE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This `Flags` constant indicates to include deleted services.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Flags kFlagDeleted = OT_SRP_SERVER_SERVICE_FLAG_DELETED;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells if the SRP service has been deleted.
|
* Tells if the SRP service has been deleted.
|
||||||
*
|
*
|
||||||
@@ -230,22 +199,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool IsDeleted(void) const { return mIsDeleted; }
|
bool IsDeleted(void) const { return mIsDeleted; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the SRP service is a sub-type.
|
|
||||||
*
|
|
||||||
* @retval TRUE If the service is a sub-type.
|
|
||||||
* @retval FALSE If the service is not a sub-type.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool IsSubType(void) const { return mIsSubType; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the full service instance name of the service.
|
* Gets the full service instance name of the service.
|
||||||
*
|
*
|
||||||
* @returns A pointer service instance name (as a null-terminated C string).
|
* @returns A pointer service instance name (as a null-terminated C string).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const char *GetInstanceName(void) const { return mDescription->GetInstanceName(); }
|
const char *GetInstanceName(void) const { return mInstanceName.AsCString(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the service instance label of the service.
|
* Gets the service instance label of the service.
|
||||||
@@ -253,7 +213,7 @@ public:
|
|||||||
* @returns A pointer service instance label (as a null-terminated C string).
|
* @returns A pointer service instance label (as a null-terminated C string).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const char *GetInstanceLabel(void) const { return mDescription->GetInstanceLabel(); }
|
const char *GetInstanceLabel(void) const { return mInstanceLabel.AsCString(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the full service name of the service.
|
* Gets the full service name of the service.
|
||||||
@@ -264,23 +224,52 @@ public:
|
|||||||
const char *GetServiceName(void) const { return mServiceName.AsCString(); }
|
const char *GetServiceName(void) const { return mServiceName.AsCString(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the sub-type label from service name.
|
* Gets number of sub-types of this service.
|
||||||
*
|
*
|
||||||
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.". This
|
* @returns The number of sub-types.
|
||||||
* method copies the `<sub-label>` into the @p aLabel buffer.
|
|
||||||
*
|
|
||||||
* The @p aLabel is ensured to always be null-terminated after returning even in case of failure.
|
|
||||||
*
|
|
||||||
* @param[out] aLabel A pointer to a buffer to copy the sub-type label name.
|
|
||||||
* @param[in] aMaxSize Maximum size of @p aLabel buffer.
|
|
||||||
*
|
|
||||||
* @retval kErrorNone @p aLabel was updated successfully.
|
|
||||||
* @retval kErrorNoBufs The sub-type label could not fit in @p aLabel buffer (number of chars from label
|
|
||||||
* that could fit are copied in @p aLabel ensuring it is null-terminated).
|
|
||||||
* @retval kErrorInvalidArgs SRP service is not a sub-type.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
|
uint16_t GetNumberOfSubTypes(void) const { return mSubTypes.GetLength(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sub-type service name (full name) at a given index.
|
||||||
|
*
|
||||||
|
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.".
|
||||||
|
*
|
||||||
|
* @param[in] aIndex The index to get.
|
||||||
|
*
|
||||||
|
* @returns A pointer to sub-type service name at @p aIndex, or `nullptr` if none at this index.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *GetSubTypeServiceNameAt(uint16_t aIndex) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not service has a given sub-type.
|
||||||
|
*
|
||||||
|
* @param[in] aSubTypeServiceName The sub-type service name (full name).
|
||||||
|
*
|
||||||
|
* @retval TRUE Service contains the sub-type @p aSubTypeServiceName.
|
||||||
|
* @retval FALSE Service does not contain the sub-type @p aSubTypeServiceName.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool HasSubTypeServiceName(const char *aSubTypeServiceName) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a sub-type service name (full name) and extracts the sub-type label.
|
||||||
|
*
|
||||||
|
* The full service name for a sub-type service follows "<sub-label>._sub.<service-labels>.<domain>.".
|
||||||
|
*
|
||||||
|
* @param[in] aSubTypeServiceName A sub-type service name (full name).
|
||||||
|
* @param[out] aLabel A pointer to a buffer to copy the extracted sub-type label.
|
||||||
|
* @param[in] aLabelSize Maximum size of @p aLabel buffer.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Name was successfully parsed and @p aLabel was updated.
|
||||||
|
* @retval kErrorNoBufs The sub-type label could not fit in @p aLabel buffer (number of chars from label
|
||||||
|
* that could fit are copied in @p aLabel ensuring it is null-terminated).
|
||||||
|
* @retval kErrorInvalidArgs @p aSubTypeServiceName is not a valid sub-type format.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static Error ParseSubTypeServiceName(const char *aSubTypeServiceName, char *aLabel, uint8_t aLabelSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the TTL of the service instance.
|
* Returns the TTL of the service instance.
|
||||||
@@ -288,7 +277,7 @@ public:
|
|||||||
* @returns The TTL of the service instance.
|
* @returns The TTL of the service instance.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint32_t GetTtl(void) const { return mDescription->mTtl; }
|
uint32_t GetTtl(void) const { return mTtl; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the port of the service instance.
|
* Returns the port of the service instance.
|
||||||
@@ -296,7 +285,7 @@ public:
|
|||||||
* @returns The port of the service.
|
* @returns The port of the service.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint16_t GetPort(void) const { return mDescription->mPort; }
|
uint16_t GetPort(void) const { return mPort; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the weight of the service instance.
|
* Returns the weight of the service instance.
|
||||||
@@ -304,7 +293,7 @@ public:
|
|||||||
* @returns The weight of the service.
|
* @returns The weight of the service.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint16_t GetWeight(void) const { return mDescription->mWeight; }
|
uint16_t GetWeight(void) const { return mWeight; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the priority of the service instance.
|
* Returns the priority of the service instance.
|
||||||
@@ -312,7 +301,7 @@ public:
|
|||||||
* @returns The priority of the service.
|
* @returns The priority of the service.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint16_t GetPriority(void) const { return mDescription->mPriority; }
|
uint16_t GetPriority(void) const { return mPriority; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the TXT record data of the service instance.
|
* Returns the TXT record data of the service instance.
|
||||||
@@ -320,7 +309,7 @@ public:
|
|||||||
* @returns A pointer to the buffer containing the TXT record data.
|
* @returns A pointer to the buffer containing the TXT record data.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const uint8_t *GetTxtData(void) const { return mDescription->mTxtData.GetBytes(); }
|
const uint8_t *GetTxtData(void) const { return mTxtData.GetBytes(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the TXT record data length of the service instance.
|
* Returns the TXT record data length of the service instance.
|
||||||
@@ -328,7 +317,7 @@ public:
|
|||||||
* @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`).
|
* @return The TXT record data length (number of bytes in buffer returned from `GetTxtData()`).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint16_t GetTxtDataLength(void) const { return mDescription->mTxtData.GetLength(); }
|
uint16_t GetTxtDataLength(void) const { return mTxtData.GetLength(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the host which the service instance reside on.
|
* Returns the host which the service instance reside on.
|
||||||
@@ -336,7 +325,7 @@ public:
|
|||||||
* @returns A reference to the host instance.
|
* @returns A reference to the host instance.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const Host &GetHost(void) const { return *mDescription->mHost; }
|
const Host &GetHost(void) const { return *mHost; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the LEASE time of the service.
|
* Returns the LEASE time of the service.
|
||||||
@@ -344,7 +333,7 @@ public:
|
|||||||
* @returns The LEASE time in seconds.
|
* @returns The LEASE time in seconds.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint32_t GetLease(void) const { return mDescription->mLease; }
|
uint32_t GetLease(void) const { return mLease; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the KEY-LEASE time of the key of the service.
|
* Returns the KEY-LEASE time of the key of the service.
|
||||||
@@ -352,7 +341,7 @@ public:
|
|||||||
* @returns The KEY-LEASE time in seconds.
|
* @returns The KEY-LEASE time in seconds.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; }
|
uint32_t GetKeyLease(void) const { return mKeyLease; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the expire time (in milliseconds) of the service.
|
* Returns the expire time (in milliseconds) of the service.
|
||||||
@@ -402,55 +391,41 @@ public:
|
|||||||
bool MatchesServiceName(const char *aServiceName) const;
|
bool MatchesServiceName(const char *aServiceName) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Description : public LinkedListEntry<Description>,
|
|
||||||
public Heap::Allocatable<Description>,
|
|
||||||
public RetainCountable,
|
|
||||||
private NonCopyable
|
|
||||||
{
|
|
||||||
Error Init(const char *aInstanceName, const char *aInstanceLabel, Host &aHost);
|
|
||||||
const char *GetInstanceName(void) const { return mInstanceName.AsCString(); }
|
|
||||||
const char *GetInstanceLabel(void) const { return mInstanceLabel.AsCString(); }
|
|
||||||
bool Matches(const char *aInstanceName) const;
|
|
||||||
void ClearResources(void);
|
|
||||||
void TakeResourcesFrom(Description &aDescription);
|
|
||||||
Error SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
|
|
||||||
|
|
||||||
Description *mNext;
|
|
||||||
Heap::String mInstanceName;
|
|
||||||
Heap::String mInstanceLabel;
|
|
||||||
Host *mHost;
|
|
||||||
Heap::Data mTxtData;
|
|
||||||
uint16_t mPriority;
|
|
||||||
uint16_t mWeight;
|
|
||||||
uint16_t mPort;
|
|
||||||
uint32_t mTtl; // The TTL in seconds.
|
|
||||||
uint32_t mLease; // The LEASE time in seconds.
|
|
||||||
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
|
||||||
TimeMilli mUpdateTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Action : uint8_t
|
enum Action : uint8_t
|
||||||
{
|
{
|
||||||
kAddNew,
|
kAddNew,
|
||||||
kUpdateExisting,
|
kUpdateExisting,
|
||||||
|
kKeepUnchanged,
|
||||||
kRemoveButRetainName,
|
kRemoveButRetainName,
|
||||||
kFullyRemove,
|
kFullyRemove,
|
||||||
kLeaseExpired,
|
kLeaseExpired,
|
||||||
kKeyLeaseExpired,
|
kKeyLeaseExpired,
|
||||||
};
|
};
|
||||||
|
|
||||||
Error Init(const char *aServiceName, Description &aDescription, bool aIsSubType, TimeMilli aUpdateTime);
|
Error Init(const char *aInstanceName, const char *aInstanceLabel, Host &aHost, TimeMilli aUpdateTime);
|
||||||
bool MatchesFlags(Flags aFlags) const;
|
Error SetTxtDataFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
|
||||||
const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; }
|
bool Matches(const char *aInstanceName) const;
|
||||||
void Log(Action aAction) const;
|
void Log(Action aAction) const;
|
||||||
|
|
||||||
Heap::String mServiceName;
|
Service *mNext;
|
||||||
RetainPtr<Description> mDescription;
|
Heap::String mInstanceName;
|
||||||
Service *mNext;
|
Heap::String mInstanceLabel;
|
||||||
TimeMilli mUpdateTime;
|
Heap::String mServiceName;
|
||||||
bool mIsDeleted : 1;
|
Heap::Array<Heap::String> mSubTypes;
|
||||||
bool mIsSubType : 1;
|
Host *mHost;
|
||||||
bool mIsCommitted : 1;
|
Heap::Data mTxtData;
|
||||||
|
uint16_t mPriority;
|
||||||
|
uint16_t mWeight;
|
||||||
|
uint16_t mPort;
|
||||||
|
uint32_t mTtl; // In seconds
|
||||||
|
uint32_t mLease; // In seconds
|
||||||
|
uint32_t mKeyLease; // In seconds
|
||||||
|
TimeMilli mUpdateTime;
|
||||||
|
bool mIsDeleted : 1;
|
||||||
|
bool mIsCommitted : 1;
|
||||||
|
bool mParsedDeleteAllRrset : 1;
|
||||||
|
bool mParsedSrv : 1;
|
||||||
|
bool mParsedTxt : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -568,21 +543,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
const LinkedList<Service> &GetServices(void) const { return mServices; }
|
const LinkedList<Service> &GetServices(void) const { return mServices; }
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Finds the next matching service on the host.
|
* Returns the next service.
|
||||||
*
|
*
|
||||||
* @param[in] aPrevService A pointer to the previous service or `nullptr` to start from beginning of the list.
|
* @param[in] aPrevService A pointer to the previous service or `nullptr` to start from beginning of the list.
|
||||||
* @param[in] aFlags Flags indicating which services to include (base/sub-type, active/deleted).
|
|
||||||
* @param[in] aServiceName The service name to match. Set to `nullptr` to accept any name.
|
|
||||||
* @param[in] aInstanceName The service instance name to match. Set to `nullptr` to accept any name.
|
|
||||||
*
|
*
|
||||||
* @returns A pointer to the next matching service or `nullptr` if no matching service could be found.
|
* @returns A pointer to the next service or `nullptr` if no more services can be found.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const Service *FindNextService(const Service *aPrevService,
|
const Service *GetNextService(const Service *aPrevService) const;
|
||||||
Service::Flags aFlags = kFlagsAnyService,
|
|
||||||
const char *aServiceName = nullptr,
|
|
||||||
const char *aInstanceName = nullptr) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells whether the host matches a given full name.
|
* Tells whether the host matches a given full name.
|
||||||
@@ -607,26 +576,15 @@ public:
|
|||||||
bool ShouldUseShortLeaseOption(void) const { return mUseShortLeaseOption; }
|
bool ShouldUseShortLeaseOption(void) const { return mUseShortLeaseOption; }
|
||||||
Error ProcessTtl(uint32_t aTtl);
|
Error ProcessTtl(uint32_t aTtl);
|
||||||
|
|
||||||
LinkedList<Service> &GetServices(void) { return mServices; }
|
Service *AddNewService(const char *aInstanceName, const char *aInstanceLabel, TimeMilli aUpdateTime);
|
||||||
Service *AddNewService(const char *aServiceName,
|
void AddService(Service &aService);
|
||||||
const char *aInstanceName,
|
void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
||||||
const char *aInstanceLabel,
|
bool HasService(const char *aInstanceName) const;
|
||||||
bool aIsSubType,
|
Service *FindService(const char *aInstanceName);
|
||||||
TimeMilli aUpdateTime);
|
const Service *FindService(const char *aInstanceName) const;
|
||||||
Service *AddNewService(const Service &aService, TimeMilli aUpdateTime);
|
void FreeAllServices(void);
|
||||||
void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
void ClearResources(void);
|
||||||
Error AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime);
|
Error AddIp6Address(const Ip6::Address &aIp6Address);
|
||||||
void FreeAllServices(void);
|
|
||||||
void ClearResources(void);
|
|
||||||
Error MergeServicesAndResourcesFrom(Host &aHost);
|
|
||||||
Error AddIp6Address(const Ip6::Address &aIp6Address);
|
|
||||||
bool HasServiceInstance(const char *aInstanceName) const;
|
|
||||||
RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName);
|
|
||||||
const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
|
|
||||||
Service *FindService(const char *aServiceName, const char *aInstanceName);
|
|
||||||
const Service *FindService(const char *aServiceName, const char *aInstanceName) const;
|
|
||||||
Service *FindBaseService(const char *aInstanceName);
|
|
||||||
const Service *FindBaseService(const char *aInstanceName) const;
|
|
||||||
|
|
||||||
Host *mNext;
|
Host *mNext;
|
||||||
Heap::String mFullName;
|
Heap::String mFullName;
|
||||||
@@ -684,36 +642,6 @@ public:
|
|||||||
uint32_t GrantKeyLease(uint32_t aKeyLease) const;
|
uint32_t GrantKeyLease(uint32_t aKeyLease) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines a `Service::Flags` combination accepting any service (base/sub-type, active/deleted).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Service::Flags kFlagsAnyService = OT_SRP_SERVER_FLAGS_ANY_SERVICE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines a `Service::Flags` combination accepting base services only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Service::Flags kFlagsBaseTypeServiceOnly = OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines a `Service::Flags` combination accepting sub-type services only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Service::Flags kFlagsSubTypeServiceOnly = OT_SRP_SERVER_FLAGS_SUB_TYPE_SERVICE_ONLY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines a `Service::Flags` combination accepting any active services (not deleted).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Service::Flags kFlagsAnyTypeActiveService = OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines a `Service::Flags` combination accepting any deleted services.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static constexpr Service::Flags kFlagsAnyTypeDeletedService = OT_SRP_SERVER_FLAGS_ANY_TYPE_DELETED_SERVICE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the SRP server object.
|
* Initializes the SRP server object.
|
||||||
*
|
*
|
||||||
@@ -901,6 +829,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
Error SetLeaseConfig(const LeaseConfig &aLeaseConfig);
|
Error SetLeaseConfig(const LeaseConfig &aLeaseConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the `Host` linked list.
|
||||||
|
*
|
||||||
|
* @returns The `Host` linked list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const LinkedList<Host> &GetHosts(void) const { return mHosts; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next registered SRP host.
|
* Returns the next registered SRP host.
|
||||||
*
|
*
|
||||||
@@ -1037,7 +973,6 @@ private:
|
|||||||
uint16_t aSigRdataOffset,
|
uint16_t aSigRdataOffset,
|
||||||
uint16_t aSigRdataLength,
|
uint16_t aSigRdataLength,
|
||||||
const char *aSignerName) const;
|
const char *aSignerName) const;
|
||||||
Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata);
|
|
||||||
Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
|
Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
|
||||||
Error ProcessHostDescriptionInstruction(Host &aHost,
|
Error ProcessHostDescriptionInstruction(Host &aHost,
|
||||||
const Message &aMessage,
|
const Message &aMessage,
|
||||||
@@ -1050,7 +985,6 @@ private:
|
|||||||
static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord);
|
static bool IsValidDeleteAllRecord(const Dns::ResourceRecord &aRecord);
|
||||||
|
|
||||||
void HandleUpdate(Host &aHost, const MessageMetadata &aMetadata);
|
void HandleUpdate(Host &aHost, const MessageMetadata &aMetadata);
|
||||||
void AddHost(Host &aHost);
|
|
||||||
void RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
void RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
||||||
bool HasNameConflictsWith(Host &aHost) const;
|
bool HasNameConflictsWith(Host &aHost) const;
|
||||||
void SendResponse(const Dns::UpdateHeader &aHeader,
|
void SendResponse(const Dns::UpdateHeader &aHeader,
|
||||||
|
|||||||
Reference in New Issue
Block a user