mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 09:57:47 +00:00
[dns-client] service discovery (DNS-SD) support and enhancements (#6116)
This commit re-designs the `Dns::Client` module enhancing the address resolution implementation and also adding support for DNS-Based Service Discovery (DNS-SD). With regards to address resolution query the new model relaxes the requirements of the public OT APIs such that caller does not need to persist the query info (e.g., the host name string buffer can be a temporary variable and does not need to persist during the query) and it is all managed by the `Dns::Client` core implementation itself. The new model also supports the case where the response contains multiple IPv6 addresses providing new APIs to allow the user to iterate through the list of addresses and retrieve them one by one. The implementation also handles the case where the DNS query response contains CNAME record mapping the queried host name to a canonical name for which a list of addresses are then provided. The core implementation is also simplified, instead of cloning a query message and saving it for possible retx, the new code saves the query related info from which it can re-construct the query message for retx if/when needed. This commit also adds support for DNS-SD in `Dns::Client`. The config `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` can be used to disable service discovery feature. The implementation supports "service instance enumeration" which is referred to as "browsing" and "service instance resolution". Callbacks are used to notify the user when a response is received. In the callback a pointer to an opaque response object is given to the user which can then be used with the new set of APIs to get more info about the response, such as the list of discovered service instances or more details about a specific service instance (e.g., port number, host name and its address) or iterate through address lists. This provides a flexible and scalable solution to handle larger lists in the response without adding memory overhead in the implementation.
This commit is contained in:
committed by
Jonathan Hui
parent
159efe77c0
commit
7084422a0e
+1
-1
@@ -51,7 +51,7 @@ openthread_headers = \
|
||||
openthread/dataset_ftd.h \
|
||||
openthread/dataset_updater.h \
|
||||
openthread/diag.h \
|
||||
openthread/dns.h \
|
||||
openthread/dns_client.h \
|
||||
openthread/entropy.h \
|
||||
openthread/error.h \
|
||||
openthread/heap.h \
|
||||
|
||||
@@ -72,7 +72,7 @@ source_set("openthread") {
|
||||
"dataset_ftd.h",
|
||||
"dataset_updater.h",
|
||||
"diag.h",
|
||||
"dns.h",
|
||||
"dns_client.h",
|
||||
"entropy.h",
|
||||
"error.h",
|
||||
"heap.h",
|
||||
|
||||
@@ -29,14 +29,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file defines the top-level dns functions for the OpenThread library.
|
||||
* This file defines the top-level DNS functions for the OpenThread library.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_DNS_H_
|
||||
#define OPENTHREAD_DNS_H_
|
||||
|
||||
#include <openthread/ip6.h>
|
||||
#include <openthread/message.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -52,10 +51,9 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#define OT_DNS_MAX_HOSTNAME_LENGTH 62 ///< Maximum allowed hostname length (maximum label size - 1 for compression).
|
||||
#define OT_DNS_MAX_NAME_SIZE 255 ///< Maximum name string size (includes null char at the end of string).
|
||||
|
||||
#define OT_DNS_DEFAULT_SERVER_IP "2001:4860:4860::8888" ///< Defines default DNS Server address - Google DNS.
|
||||
#define OT_DNS_DEFAULT_SERVER_PORT 53 ///< Defines default DNS Server port.
|
||||
#define OT_DNS_MAX_LABEL_SIZE 64 ///< Maximum label string size (include null char at the end of string)
|
||||
|
||||
/**
|
||||
* Initializer for otDnsTxtIterator.
|
||||
@@ -96,56 +94,6 @@ typedef struct otDnsTxtEntry
|
||||
uint8_t mKeyLength; ///< Number of bytes in `mKey` buffer. MUST be set even if `mKey` is a null-terminated string.
|
||||
} otDnsTxtEntry;
|
||||
|
||||
/**
|
||||
* This structure implements DNS Query parameters.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnsQuery
|
||||
{
|
||||
const char * mHostname; ///< Identifies hostname to be found. It shall not change during resolving.
|
||||
const otMessageInfo *mMessageInfo; ///< A reference to the message info related with DNS Server.
|
||||
bool mNoRecursion; ///< If cleared, it directs name server to pursue the query recursively.
|
||||
} otDnsQuery;
|
||||
|
||||
/**
|
||||
* This function pointer is called when a DNS response is received.
|
||||
*
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* @param[in] aHostname Identifies hostname related with DNS response.
|
||||
* @param[in] aAddress A pointer to the IPv6 address received in DNS response. May be null.
|
||||
* @param[in] aTtl Specifies the maximum time in seconds that the resource record may be cached.
|
||||
* @param[in] aResult A result of the DNS transaction.
|
||||
*
|
||||
* @retval OT_ERROR_NONE A response was received successfully and IPv6 address is provided
|
||||
* in @p aAddress.
|
||||
* @retval OT_ERROR_ABORT A DNS transaction was aborted by stack.
|
||||
* @retval OT_ERROR_RESPONSE_TIMEOUT No DNS response has been received within timeout.
|
||||
* @retval OT_ERROR_NOT_FOUND A response was received but no IPv6 address has been found.
|
||||
* @retval OT_ERROR_FAILED A response was received but status code is different than success.
|
||||
*
|
||||
*/
|
||||
typedef void (*otDnsResponseHandler)(void * aContext,
|
||||
const char * aHostname,
|
||||
const otIp6Address *aAddress,
|
||||
uint32_t aTtl,
|
||||
otError aResult);
|
||||
|
||||
/**
|
||||
* This function sends a DNS query for AAAA (IPv6) record.
|
||||
*
|
||||
* This function is available only if feature `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aQuery A pointer to specify DNS query parameters.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
otError otDnsClientQuery(otInstance * aInstance,
|
||||
const otDnsQuery * aQuery,
|
||||
otDnsResponseHandler aHandler,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file defines the top-level DNS functions for the OpenThread library.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_DNS_CLIENT_H_
|
||||
#define OPENTHREAD_DNS_CLIENT_H_
|
||||
|
||||
#include <openthread/dns.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-dns
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions that control DNS communication.
|
||||
*
|
||||
* The functions in this module are available only if feature `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is enabled.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
#define OT_DNS_DEFAULT_SERVER_PORT 53 ///< The default DNS Server port.
|
||||
|
||||
#define OT_DNS_DEFAULT_SERVER_IP "2001:4860:4860::8888" ///< Defines default DNS Server address - Google DNS.
|
||||
|
||||
/**
|
||||
* This type is an opaque representation of a response to an address resolution DNS query.
|
||||
*
|
||||
* Pointers to instance of this type are provided from callback `otDnsAddressCallback`.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnsAddressResponse otDnsAddressResponse;
|
||||
|
||||
/**
|
||||
* This function pointer is called when a DNS response is received for an address resolution query.
|
||||
*
|
||||
* Within this callback the user can use `otDnsAddressResponseGet{Item}()` functions along with the @p aResponse
|
||||
* pointer to get more info about the response.
|
||||
*
|
||||
* The @p aResponse pointer can only be used within this callback and after returning from this function it will not
|
||||
* stay valid, so the user MUST NOT retain the @p aResponse pointer for later use.
|
||||
*
|
||||
* @param[in] aError The result of the DNS transaction.
|
||||
* @param[in] aResponse A pointer to the response (it is always non-NULL).
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* The @p aError can have the following:
|
||||
*
|
||||
* - OT_ERROR_NONE A response was received successfully.
|
||||
* - OT_ERROR_ABORT A DNS transaction was aborted by stack.
|
||||
* - OT_ERROR_RESPONSE_TIMEOUT No DNS response has been received within timeout.
|
||||
*
|
||||
* If the server rejects the address resolution request the error code from server is mapped as follow:
|
||||
*
|
||||
* (0) NOERROR Success (no error condition) -> OT_ERROR_NONE
|
||||
* (1) FORMERR Server unable to interpret due to format error -> OT_ERROR_PARSE
|
||||
* (2) SERVFAIL Server encountered an internal failure -> OT_ERROR_FAILED
|
||||
* (3) NXDOMAIN Name that ought to exist, does not exist -> OT_ERROR_NOT_FOUND
|
||||
* (4) NOTIMP Server does not support the query type (OpCode) -> OT_ERROR_NOT_IMPLEMENTED
|
||||
* (5) REFUSED Server refused for policy/security reasons -> OT_ERROR_SECURITY
|
||||
* (6) YXDOMAIN Some name that ought not to exist, does exist -> OT_ERROR_DUPLICATED
|
||||
* (7) YXRRSET Some RRset that ought not to exist, does exist -> OT_ERROR_DUPLICATED
|
||||
* (8) NXRRSET Some RRset that ought to exist, does not exist -> OT_ERROR_NOT_FOUND
|
||||
* (9) NOTAUTH Service is not authoritative for zone -> OT_ERROR_SECURITY
|
||||
* (10) NOTZONE A name is not in the zone -> OT_ERROR_PARSE
|
||||
* (20) BADNAME Bad name -> OT_ERROR_PARSE
|
||||
* (21) BADALG Bad algorithm -> OT_ERROR_SECURITY
|
||||
* (22) BADTRUN Bad truncation -> OT_ERROR_PARSE
|
||||
* Other response codes -> OT_ERROR_FAILED
|
||||
*
|
||||
*/
|
||||
typedef void (*otDnsAddressCallback)(otError aError, const otDnsAddressResponse *aResponse, void *aContext);
|
||||
|
||||
/**
|
||||
* This function sends an address resolution DNS query for AAAA (IPv6) record(s) for a given host name.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aServerSockAddr A pointer to the server socket address.
|
||||
* @param[in] aHostName The host name for which to query the address (MUST NOT be NULL).
|
||||
* @param[in] aNoRecursion Indicates whether name server can resolve the query recursively or not.
|
||||
* @param[in] aCallback A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query.
|
||||
*
|
||||
*/
|
||||
otError otDnsClientResolveAddress(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aHostName,
|
||||
bool aNoRecursion,
|
||||
otDnsAddressCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function gets the full host name associated with an address resolution DNS response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsAddressCallback`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[out] aNameBuffer A buffer to char array to output the full host name (MUST NOT be NULL).
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The full host name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
*
|
||||
*/
|
||||
otError otDnsAddressResponseGetHostName(const otDnsAddressResponse *aResponse,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize);
|
||||
|
||||
/**
|
||||
* This function gets an IPv6 address associated with an address resolution DNS response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsAddressCallback`.
|
||||
*
|
||||
* The response may include multiple IPv6 address records. @p aIndex can be used to iterate through the list of
|
||||
* addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is
|
||||
* returned.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL).
|
||||
* @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does not
|
||||
* want to get the TTL.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record in @p aResponse at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsAddressResponseGetAddress(const otDnsAddressResponse *aResponse,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl);
|
||||
|
||||
/**
|
||||
* This type is an opaque representation of a response to a browse (service instance enumeration) DNS query.
|
||||
*
|
||||
* Pointers to instance of this type are provided from callback `otDnsBrowseCallback`.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnsBrowseResponse otDnsBrowseResponse;
|
||||
|
||||
/**
|
||||
* This function pointer is called when a DNS response is received for a browse (service instance enumeration) query.
|
||||
*
|
||||
* Within this callback the user can use `otDnsBrowseResponseGet{Item}()` functions along with the @p aResponse
|
||||
* pointer to get more info about the response.
|
||||
*
|
||||
* The @p aResponse pointer can only be used within this callback and after returning from this function it will not
|
||||
* stay valid, so the user MUST NOT retain the @p aResponse pointer for later use.
|
||||
*
|
||||
* @param[in] aError The result of the DNS transaction.
|
||||
* @param[in] aResponse A pointer to the response (it is always non-NULL).
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* For the full list of possible values for @p aError, please see `otDnsAddressCallback()`.
|
||||
*
|
||||
*/
|
||||
typedef void (*otDnsBrowseCallback)(otError aError, const otDnsBrowseResponse *aResponse, void *aContext);
|
||||
|
||||
/**
|
||||
* This structure provides info for a DNS service instance.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnsServiceInfo
|
||||
{
|
||||
uint32_t mTtl; ///< Service record TTL (in seconds).
|
||||
uint16_t mPort; ///< Service port number.
|
||||
uint16_t mPriority; ///< Service priority.
|
||||
uint16_t mWeight; ///< Service weight.
|
||||
char * mHostNameBuffer; ///< Buffer to output the service host name (can be NULL if not needed).
|
||||
uint16_t mHostNameBufferSize; ///< Size of `mHostNameBuffer`.
|
||||
otIp6Address mHostAddress; ///< The host IPv6 address. Set to all zero if not available.
|
||||
uint32_t mHostAddressTtl; ///< The host address TTL.
|
||||
uint8_t * mTxtData; ///< Buffer to output TXT data (can be NULL if not needed).
|
||||
uint16_t mTxtDataSize; ///< On input, size of `mTxtData` buffer. On output `mTxtData` length.
|
||||
uint32_t mTxtDataTtl; ///< The TXT data TTL.
|
||||
} otDnsServiceInfo;
|
||||
|
||||
/**
|
||||
* This function sends a DNS browse (service instance enumeration) query for a given service name.
|
||||
*
|
||||
* This function is available when `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aServerSockAddr A pointer to the server socket address.
|
||||
* @param[in] aServiceName The service name to query for (MUST NOT be NULL).
|
||||
* @param[in] aCallback A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query.
|
||||
*
|
||||
*/
|
||||
otError otDnsClientBrowse(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aServiceName,
|
||||
otDnsBrowseCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function gets the service name associated with a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsBrowseCallback`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[out] aNameBuffer A buffer to char array to output the service name (MUST NOT be NULL).
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
*
|
||||
*/
|
||||
otError otDnsBrowseResponseGetServiceName(const otDnsBrowseResponse *aResponse,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize);
|
||||
|
||||
/**
|
||||
* This function gets a service instance associated with a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsBrowseCallback`.
|
||||
*
|
||||
* The response may include multiple service instance records. @p aIndex can be used to iterate through the list. Index
|
||||
* zero gives the the first record. When we reach end of the list, `OT_ERROR_NOT_FOUND` is returned.
|
||||
*
|
||||
* Note that this function gets the service instance label and not the full service instance name which is of the form
|
||||
* `<Instance>.<Service>.<Domain>`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[in] aIndex The service instance record index to retrieve.
|
||||
* @param[out] aLabelBuffer A buffer to char array to output the service instance label (MUST NOT be NULL).
|
||||
* @param[in] aLabelBufferSize The size of @p aLabelBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
* @retval OT_ERROR_NOT_FOUND No service instance record in @p aResponse at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsBrowseResponseGetServiceInstance(const otDnsBrowseResponse *aResponse,
|
||||
uint16_t aIndex,
|
||||
char * aLabelBuffer,
|
||||
uint8_t aLabelBufferSize);
|
||||
|
||||
/**
|
||||
* This function gets info for a service instance from a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsBrowseCallback`.
|
||||
*
|
||||
* A browse DNS response should include the SRV, TXT, and AAAA records for the service instances that are enumerated
|
||||
* (note that it is a SHOULD and not a MUST requirement). This function tries to retrieve this info for a given service
|
||||
* instance when available.
|
||||
*
|
||||
* If no matching SRV record is found in @p aResponse, `OT_ERROR_NOT_FOUND` is returned.
|
||||
* If a matching SRV record is found in @p aResponse, @p aServiceInfo is updated and `OT_ERROR_NONE` is returned.
|
||||
* If no matching TXT record is found in @p aResponse, `mTxtDataSize` in @p aServiceInfo is set to zero.
|
||||
* If no matching AAAA record is found in @p aResponse, `mHostAddress is set to all zero or unspecified address.
|
||||
* If there are multiple AAAA records for the host name in @p aResponse, `mHostAddress` is set to the first one. The
|
||||
* other addresses can be retrieved using `otDnsBrowseResponseGetHostAddress()`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[in] aInstanceLabel The service instance label (MUST NOT be NULL).
|
||||
* @param[out] aServiceInfo A `ServiceInfo` to output the service instance information (MUST NOT be NULL).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated.
|
||||
* @retval OT_ERROR_NOT_FOUND Could not find a matching SRV record for @p aInstanceLabel.
|
||||
* @retval OT_ERROR_NO_BUFS The host name and/or TXT data could not fit in the given buffers.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsBrowseResponseGetServiceInfo(const otDnsBrowseResponse *aResponse,
|
||||
const char * aInstanceLabel,
|
||||
otDnsServiceInfo * aServiceInfo);
|
||||
|
||||
/**
|
||||
* This function gets the host IPv6 address from a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsBrowseCallback`.
|
||||
*
|
||||
* The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the list of
|
||||
* addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is
|
||||
* returned.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[in] aHostName The host name to get the address (MUST NOT be NULL).
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL).
|
||||
* @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does
|
||||
* not want to get the TTL.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record for @p aHostname in @p aResponse at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsBrowseResponseGetHostAddress(const otDnsBrowseResponse *aResponse,
|
||||
const char * aHostName,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl);
|
||||
|
||||
/**
|
||||
* This type is an opaque representation of a response to a service instance resolution DNS query.
|
||||
*
|
||||
* Pointers to instance of this type are provided from callback `otDnsAddressCallback`.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnsServiceResponse otDnsServiceResponse;
|
||||
|
||||
/**
|
||||
* This function pointer is called when a DNS response is received for a service instance resolution query.
|
||||
*
|
||||
* Within this callback the user can use `otDnsServiceResponseGet{Item}()` functions along with the @p aResponse
|
||||
* pointer to get more info about the response.
|
||||
*
|
||||
* The @p aResponse pointer can only be used within this callback and after returning from this function it will not
|
||||
* stay valid, so the user MUST NOT retain the @p aResponse pointer for later use.
|
||||
*
|
||||
* @param[in] aError The result of the DNS transaction.
|
||||
* @param[in] aResponse A pointer to the response (it is always non-NULL).
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* For the full list of possible values for @p aError, please see `otDnsAddressCallback()`.
|
||||
*
|
||||
*/
|
||||
typedef void (*otDnsServiceCallback)(otError aError, const otDnsServiceResponse *aResponse, void *aContext);
|
||||
|
||||
/**
|
||||
* This function sends a DNS service instance resolution query for a given service instance.
|
||||
*
|
||||
* This function is available when `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aServerSockAddr A pointer to the server socket address.
|
||||
* @param[in] aInstanceLabel The service instance label.
|
||||
* @param[in] aServiceName The service name (together with @p aInstanceLabel form full instance name).
|
||||
* @param[in] aCallback A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query.
|
||||
*
|
||||
*/
|
||||
otError otDnsClientResolveService(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aInstanceLabel,
|
||||
const char * aServiceName,
|
||||
otDnsServiceCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function gets the service instance name associated with a DNS service instance resolution response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsServiceCallback`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[out] aLabelBuffer A buffer to char array to output the service instance label (MUST NOT be NULL).
|
||||
* @param[in] aLabelBufferSize The size of @p aLabelBuffer.
|
||||
* @param[out] aNameBuffer A buffer to char array to output the rest of service name (can be NULL if user is
|
||||
* not interested in getting the name.
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS Either the label or name does not fit in the given buffers.
|
||||
*
|
||||
*/
|
||||
otError otDnsServiceResponseGetServiceName(const otDnsServiceResponse *aResponse,
|
||||
char * aLabelBuffer,
|
||||
uint8_t aLabelBufferSize,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize);
|
||||
|
||||
/**
|
||||
* This function gets info for a service instance from a DNS service instance resolution response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsServiceCallback`.
|
||||
*
|
||||
* If no matching SRV record is found in @p aResponse, `OT_ERROR_NOT_FOUND` is returned.
|
||||
* If a matching SRV record is found in @p aResponse, @p aServiceInfo is updated and `OT_ERROR_NONE` is returned.
|
||||
* If no matching TXT record is found in @p aResponse, `mTxtDataSize` in @p aServiceInfo is set to zero.
|
||||
* If no matching AAAA record is found in @p aResponse, `mHostAddress is set to all zero or unspecified address.
|
||||
* If there are multiple AAAA records for the host name in @p aResponse, `mHostAddress` is set to the first one. The
|
||||
* other addresses can be retrieved using `otDnsServiceResponseGetHostAddress()`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[out] aServiceInfo A `ServiceInfo` to output the service instance information (MUST NOT be NULL).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated.
|
||||
* @retval OT_ERROR_NOT_FOUND Could not find a matching SRV record in @p aResponse.
|
||||
* @retval OT_ERROR_NO_BUFS The host name and/or TXT data could not fit in the given buffers.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsServiceResponseGetServiceInfo(const otDnsServiceResponse *aResponse, otDnsServiceInfo *aServiceInfo);
|
||||
|
||||
/**
|
||||
* This function gets the host IPv6 address from a DNS service instance resolution response.
|
||||
*
|
||||
* This function MUST only be used from `otDnsServiceCallback`.
|
||||
*
|
||||
* The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the list of
|
||||
* addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is
|
||||
* returned.
|
||||
*
|
||||
* @param[in] aResponse A pointer to the response.
|
||||
* @param[in] aHostName The host name to get the address (MUST NOT be NULL).
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL).
|
||||
* @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does
|
||||
* not want to get the TTL.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record for @p aHostname in @p aResponse at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError otDnsServiceResponseGetHostAddress(const otDnsServiceResponse *aResponse,
|
||||
const char * aHostName,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_DNS_CLIENT_H_
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (69)
|
||||
#define OPENTHREAD_API_VERSION (70)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
+29
-43
@@ -121,9 +121,6 @@ Interpreter::Interpreter(Instance *aInstance)
|
||||
, mPingAllowZeroHopLimit(false)
|
||||
, mPingIdentifier(0)
|
||||
, mPingTimer(*aInstance, Interpreter::HandlePingTimer)
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
, mResolvingInProgress(false)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
, mSntpQueryingInProgress(false)
|
||||
#endif
|
||||
@@ -159,10 +156,6 @@ Interpreter::Interpreter(Instance *aInstance)
|
||||
mIcmpHandler.mReceiveCallback = Interpreter::HandleIcmpReceive;
|
||||
mIcmpHandler.mContext = this;
|
||||
IgnoreError(otIcmp6RegisterHandler(mInstance, &mIcmpHandler));
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
memset(mResolvingHostname, 0, sizeof(mResolvingHostname));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Interpreter::OutputResult(otError aError)
|
||||
@@ -1344,45 +1337,34 @@ exit:
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
otError Interpreter::ProcessDns(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t port = OT_DNS_DEFAULT_SERVER_PORT;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
otDnsQuery query;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otSockAddr serverSockAddr;
|
||||
|
||||
serverSockAddr.mPort = OT_DNS_DEFAULT_SERVER_PORT;
|
||||
|
||||
VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(aArgs[0], "resolve") == 0)
|
||||
{
|
||||
VerifyOrExit(!mResolvingInProgress, error = OT_ERROR_BUSY);
|
||||
VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(strlen(aArgs[1]) < OT_DNS_MAX_HOSTNAME_LENGTH, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
strcpy(mResolvingHostname, aArgs[1]);
|
||||
|
||||
if (aArgsLength > 2)
|
||||
{
|
||||
SuccessOrExit(error = ParseAsIp6Address(aArgs[2], messageInfo.GetPeerAddr()));
|
||||
SuccessOrExit(error = ParseAsIp6Address(aArgs[2], serverSockAddr.mAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use IPv6 address of default DNS server.
|
||||
SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(OT_DNS_DEFAULT_SERVER_IP));
|
||||
SuccessOrExit(error = otIp6AddressFromString(OT_DNS_DEFAULT_SERVER_IP, &serverSockAddr.mAddress));
|
||||
}
|
||||
|
||||
if (aArgsLength > 3)
|
||||
{
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[3], port));
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[3], serverSockAddr.mPort));
|
||||
}
|
||||
|
||||
messageInfo.SetPeerPort(port);
|
||||
|
||||
query.mHostname = mResolvingHostname;
|
||||
query.mMessageInfo = static_cast<const otMessageInfo *>(&messageInfo);
|
||||
query.mNoRecursion = false;
|
||||
|
||||
SuccessOrExit(error = otDnsClientQuery(mInstance, &query, &Interpreter::HandleDnsResponse, this));
|
||||
|
||||
mResolvingInProgress = true;
|
||||
SuccessOrExit(error = otDnsClientResolveAddress(mInstance, &serverSockAddr, aArgs[1], /* aNoRecursion */ false,
|
||||
&Interpreter::HandleDnsResponse, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1395,32 +1377,36 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Interpreter::HandleDnsResponse(void * aContext,
|
||||
const char * aHostname,
|
||||
const otIp6Address *aAddress,
|
||||
uint32_t aTtl,
|
||||
otError aResult)
|
||||
void Interpreter::HandleDnsResponse(otError aError, const otDnsAddressResponse *aResponse, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleDnsResponse(aHostname, static_cast<const Ip6::Address *>(aAddress),
|
||||
aTtl, aResult);
|
||||
static_cast<Interpreter *>(aContext)->HandleDnsResponse(aError, aResponse);
|
||||
}
|
||||
|
||||
void Interpreter::HandleDnsResponse(const char *aHostname, const Ip6::Address *aAddress, uint32_t aTtl, otError aResult)
|
||||
void Interpreter::HandleDnsResponse(otError aError, const otDnsAddressResponse *aResponse)
|
||||
{
|
||||
OutputFormat("DNS response for %s - ", aHostname);
|
||||
char hostName[OT_DNS_MAX_NAME_SIZE];
|
||||
otIp6Address address;
|
||||
uint32_t ttl;
|
||||
|
||||
if (aResult == OT_ERROR_NONE)
|
||||
IgnoreError(otDnsAddressResponseGetHostName(aResponse, hostName, sizeof(hostName)));
|
||||
|
||||
OutputFormat("DNS response for %s - ", hostName);
|
||||
|
||||
if (aError == OT_ERROR_NONE)
|
||||
{
|
||||
if (aAddress != nullptr)
|
||||
uint16_t index = 0;
|
||||
|
||||
while (otDnsAddressResponseGetAddress(aResponse, index, &address, &ttl) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputIp6Address(*aAddress);
|
||||
OutputIp6Address(address);
|
||||
OutputFormat(" TTL: %u ", ttl);
|
||||
index++;
|
||||
}
|
||||
OutputLine(" TTL: %d", aTtl);
|
||||
|
||||
OutputLine("");
|
||||
}
|
||||
|
||||
OutputResult(aResult);
|
||||
|
||||
mResolvingInProgress = false;
|
||||
OutputResult(aError);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
|
||||
|
||||
+3
-14
@@ -41,7 +41,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <openthread/cli.h>
|
||||
#include <openthread/dns.h>
|
||||
#include <openthread/dns_client.h>
|
||||
#include <openthread/ip6.h>
|
||||
#include <openthread/sntp.h>
|
||||
#include <openthread/udp.h>
|
||||
@@ -554,11 +554,8 @@ private:
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
static void HandleDnsResponse(void * aContext,
|
||||
const char * aHostname,
|
||||
const otIp6Address *aAddress,
|
||||
uint32_t aTtl,
|
||||
otError aResult);
|
||||
static void HandleDnsResponse(otError aError, const otDnsAddressResponse *aResponse, void *aContext);
|
||||
void HandleDnsResponse(otError aError, const otDnsAddressResponse *aResponse);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
@@ -570,9 +567,6 @@ private:
|
||||
void HandleActiveScanResult(otActiveScanResult *aResult);
|
||||
void HandleEnergyScanResult(otEnergyScanResult *aResult);
|
||||
void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
void HandleDnsResponse(const char *aHostname, const Ip6::Address *aAddress, uint32_t aTtl, otError aResult);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
void HandleSntpResponse(uint64_t aTime, otError aResult);
|
||||
#endif
|
||||
@@ -796,11 +790,6 @@ private:
|
||||
otIp6Address mPingDestAddress;
|
||||
TimerMilli mPingTimer;
|
||||
otIcmp6Handler mIcmpHandler;
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
bool mResolvingInProgress;
|
||||
char mResolvingHostname[OT_DNS_MAX_HOSTNAME_LENGTH];
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
bool mSntpQueryingInProgress;
|
||||
#endif
|
||||
|
||||
+133
-4
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/dns.h>
|
||||
#include <openthread/dns_client.h>
|
||||
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
@@ -42,10 +42,139 @@
|
||||
using namespace ot;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
otError otDnsClientQuery(otInstance *aInstance, const otDnsQuery *aQuery, otDnsResponseHandler aHandler, void *aContext)
|
||||
|
||||
otError otDnsClientResolveAddress(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aHostName,
|
||||
bool aNoRecursion,
|
||||
otDnsAddressCallback aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Dns::Client>().Query(*static_cast<const Dns::Client::QueryInfo *>(aQuery), aHandler, aContext);
|
||||
return instance.Get<Dns::Client>().ResolveAddress(*static_cast<const Ip6::SockAddr *>(aServerSockAddr), aHostName,
|
||||
aNoRecursion, aCallback, aContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
otError otDnsAddressResponseGetHostName(const otDnsAddressResponse *aResponse,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize)
|
||||
{
|
||||
const Dns::Client::AddressResponse &response = *static_cast<const Dns::Client::AddressResponse *>(aResponse);
|
||||
|
||||
return response.GetHostName(aNameBuffer, aNameBufferSize);
|
||||
}
|
||||
|
||||
otError otDnsAddressResponseGetAddress(const otDnsAddressResponse *aResponse,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl)
|
||||
{
|
||||
const Dns::Client::AddressResponse &response = *static_cast<const Dns::Client::AddressResponse *>(aResponse);
|
||||
uint32_t ttl;
|
||||
|
||||
return response.GetAddress(aIndex, *static_cast<Ip6::Address *>(aAddress), (aTtl != nullptr) ? *aTtl : ttl);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
otError otDnsClientBrowse(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aServiceName,
|
||||
otDnsBrowseCallback aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Dns::Client>().Browse(*static_cast<const Ip6::SockAddr *>(aServerSockAddr), aServiceName,
|
||||
aCallback, aContext);
|
||||
}
|
||||
|
||||
otError otDnsBrowseResponseGetServiceName(const otDnsBrowseResponse *aResponse,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize)
|
||||
{
|
||||
const Dns::Client::BrowseResponse &response = *static_cast<const Dns::Client::BrowseResponse *>(aResponse);
|
||||
|
||||
return response.GetServiceName(aNameBuffer, aNameBufferSize);
|
||||
}
|
||||
|
||||
otError otDnsBrowseResponseGetServiceInstance(const otDnsBrowseResponse *aResponse,
|
||||
uint16_t aIndex,
|
||||
char * aLabelBuffer,
|
||||
uint8_t aLabelBufferSize)
|
||||
{
|
||||
const Dns::Client::BrowseResponse &response = *static_cast<const Dns::Client::BrowseResponse *>(aResponse);
|
||||
|
||||
return response.GetServiceInstance(aIndex, aLabelBuffer, aLabelBufferSize);
|
||||
}
|
||||
|
||||
otError otDnsBrowseResponseGetServiceInfo(const otDnsBrowseResponse *aResponse,
|
||||
const char * aInstanceLabel,
|
||||
otDnsServiceInfo * aServiceInfo)
|
||||
{
|
||||
const Dns::Client::BrowseResponse &response = *static_cast<const Dns::Client::BrowseResponse *>(aResponse);
|
||||
|
||||
return response.GetServiceInfo(aInstanceLabel, *static_cast<Dns::Client::ServiceInfo *>(aServiceInfo));
|
||||
}
|
||||
|
||||
otError otDnsBrowseResponseGetHostAddress(const otDnsBrowseResponse *aResponse,
|
||||
const char * aHostName,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl)
|
||||
{
|
||||
const Dns::Client::BrowseResponse &response = *static_cast<const Dns::Client::BrowseResponse *>(aResponse);
|
||||
uint32_t ttl;
|
||||
|
||||
return response.GetHostAddress(aHostName, aIndex, *static_cast<Ip6::Address *>(aAddress),
|
||||
aTtl != nullptr ? *aTtl : ttl);
|
||||
}
|
||||
|
||||
otError otDnsClientResolveService(otInstance * aInstance,
|
||||
const otSockAddr * aServerSockAddr,
|
||||
const char * aInstanceLabel,
|
||||
const char * aServiceName,
|
||||
otDnsServiceCallback aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Dns::Client>().ResolveService(*static_cast<const Ip6::SockAddr *>(aServerSockAddr),
|
||||
aInstanceLabel, aServiceName, aCallback, aContext);
|
||||
}
|
||||
|
||||
otError otDnsServiceResponseGetServiceName(const otDnsServiceResponse *aResponse,
|
||||
char * aLabelBuffer,
|
||||
uint8_t aLabelBufferSize,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize)
|
||||
{
|
||||
const Dns::Client::ServiceResponse &response = *static_cast<const Dns::Client::ServiceResponse *>(aResponse);
|
||||
|
||||
return response.GetServiceName(aLabelBuffer, aLabelBufferSize, aNameBuffer, aNameBufferSize);
|
||||
}
|
||||
|
||||
otError otDnsServiceResponseGetServiceInfo(const otDnsServiceResponse *aResponse, otDnsServiceInfo *aServiceInfo)
|
||||
{
|
||||
const Dns::Client::ServiceResponse &response = *static_cast<const Dns::Client::ServiceResponse *>(aResponse);
|
||||
|
||||
return response.GetServiceInfo(*static_cast<Dns::Client::ServiceInfo *>(aServiceInfo));
|
||||
}
|
||||
|
||||
otError otDnsServiceResponseGetHostAddress(const otDnsServiceResponse *aResponse,
|
||||
const char * aHostName,
|
||||
uint16_t aIndex,
|
||||
otIp6Address * aAddress,
|
||||
uint32_t * aTtl)
|
||||
{
|
||||
const Dns::Client::ServiceResponse &response = *static_cast<const Dns::Client::ServiceResponse *>(aResponse);
|
||||
uint32_t ttl;
|
||||
|
||||
return response.GetHostAddress(aHostName, aIndex, *static_cast<Ip6::Address *>(aAddress),
|
||||
(aTtl != nullptr) ? *aTtl : ttl);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
|
||||
@@ -65,4 +65,14 @@
|
||||
#define OPENTHREAD_CONFIG_DNS_MAX_RETRANSMIT 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
*
|
||||
* Define to 1 to enable DNS based Service Discovery (DNS-SD) client.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
#define OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE 1
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_DNS_CLIENT_H_
|
||||
|
||||
+672
-252
File diff suppressed because it is too large
Load Diff
+437
-90
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, The OpenThread Authors.
|
||||
* Copyright (c) 2017-2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,8 +31,9 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/dns.h>
|
||||
#include <openthread/dns_client.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/timer.hpp"
|
||||
@@ -45,6 +46,34 @@
|
||||
* This file includes definitions for the DNS client.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This struct represents an opaque (and empty) type for a response to an address resolution DNS query.
|
||||
*
|
||||
*/
|
||||
struct otDnsAddressResponse
|
||||
{
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
/**
|
||||
* This struct represents an opaque (and empty) type for a response to browse (service instance enumeration) DNS query.
|
||||
*
|
||||
*/
|
||||
struct otDnsBrowseResponse
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* This struct represents an opaque (and empty) type for a response to service inst resolution DNS query.
|
||||
*
|
||||
*/
|
||||
struct otDnsServiceResponse
|
||||
{
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
namespace ot {
|
||||
namespace Dns {
|
||||
|
||||
@@ -52,57 +81,309 @@ namespace Dns {
|
||||
* This class implements DNS client.
|
||||
*
|
||||
*/
|
||||
class Client : private NonCopyable
|
||||
class Client : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
typedef Message Query; // `Message` is used to save `Query` related info.
|
||||
|
||||
public:
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
/**
|
||||
* This type represents a DNS Query info/parameters.
|
||||
* This structure provides info for a DNS service instance.
|
||||
*
|
||||
*/
|
||||
class QueryInfo : public otDnsQuery
|
||||
typedef otDnsServiceInfo ServiceInfo;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class represents a DNS query response.
|
||||
*
|
||||
*/
|
||||
class Response : public Clearable<Response>,
|
||||
public otDnsAddressResponse
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
,
|
||||
public otDnsBrowseResponse,
|
||||
public otDnsServiceResponse
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method indicates whether the `QueryInfo` object is valid or not.
|
||||
*
|
||||
* @returns TRUE if the `QueryInfo` is valid, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return (mHostname != nullptr) && (mMessageInfo != nullptr); }
|
||||
friend class Client;
|
||||
|
||||
/**
|
||||
* This method gets the host name in a DNS query.
|
||||
*
|
||||
* @return The host name.
|
||||
*
|
||||
*/
|
||||
const char *GetHostname(void) const { return mHostname; }
|
||||
|
||||
/**
|
||||
* This method gets the `MessageInfo` related to DNS Server.
|
||||
*
|
||||
* @returns The `MessageInfo` of DNS Server.
|
||||
*
|
||||
*/
|
||||
const Ip6::MessageInfo &GetMessageInfo(void) const
|
||||
protected:
|
||||
enum Section : uint8_t
|
||||
{
|
||||
return *static_cast<const Ip6::MessageInfo *>(mMessageInfo);
|
||||
}
|
||||
kAnswerSection,
|
||||
kAdditionalDataSection,
|
||||
};
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the name server can pursue the query recursively.
|
||||
*
|
||||
* @returns TRUE if no recursion is allowed, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsNoRecursion(void) const { return mNoRecursion; }
|
||||
Response(void) { Clear(); }
|
||||
|
||||
otError GetName(char *aNameBuffer, uint16_t aNameBufferSize) const;
|
||||
void SelectSection(Section aSection, uint16_t &aOffset, uint16_t &aNumRecord) const;
|
||||
otError FindHostAddress(Section aSection,
|
||||
const Name & aHostName,
|
||||
uint16_t aIndex,
|
||||
Ip6::Address &aAddress,
|
||||
uint32_t & aTtl) const;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
otError FindServiceInfo(Section aSection, const Name &aName, ServiceInfo &aServiceInfo) const;
|
||||
#endif
|
||||
|
||||
Query * mQuery; // The associated query.
|
||||
const Message *mMessage; // The response message.
|
||||
uint16_t mAnswerOffset; // Answer section offset in `mMessage`.
|
||||
uint16_t mAnswerRecordCount; // Number of records in answer section.
|
||||
uint16_t mAdditionalOffset; // Additional data section offset in `mMessage`.
|
||||
uint16_t mAdditionalRecordCount; // Number of records in additional data section.
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents the function pointer type which is called when a DNS response is received.
|
||||
* This type represents the function pointer callback which is called when a DNS response for an address resolution
|
||||
* query is received.
|
||||
*
|
||||
*/
|
||||
typedef otDnsResponseHandler ResponseHandler;
|
||||
typedef otDnsAddressCallback AddressCallback;
|
||||
|
||||
/**
|
||||
* This type represents an address resolution query DNS response.
|
||||
*
|
||||
*/
|
||||
class AddressResponse : public Response
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method gets the host name associated with an address resolution DNS response.
|
||||
*
|
||||
* This method MUST only be used from `AddressCallback`.
|
||||
*
|
||||
* @param[out] aNameBuffer A buffer to char array to output the host name.
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
*
|
||||
*/
|
||||
otError GetHostName(char *aNameBuffer, uint16_t aNameBufferSize) const
|
||||
{
|
||||
return GetName(aNameBuffer, aNameBufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the IPv6 address associated with an address resolution DNS response.
|
||||
*
|
||||
* This method MUST only be used from `AddressCallback`.
|
||||
*
|
||||
* The response may include multiple IPv6 address records. @p aIndex can be used to iterate through the list of
|
||||
* addresses. Index zero gets the the first address and so on. When we reach end of the list, this method
|
||||
* returns `OT_ERROR_NOT_FOUND`.
|
||||
*
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A reference to an IPv6 address to output the address.
|
||||
* @param[out] aTtl A reference to a `uint32_t` to output TTL for the address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records.
|
||||
*
|
||||
*/
|
||||
otError GetAddress(uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
/**
|
||||
* This type represents the function pointer callback which is called when a response for a browse (service
|
||||
* instance enumeration) DNS query is received.
|
||||
*
|
||||
*/
|
||||
typedef otDnsBrowseCallback BrowseCallback;
|
||||
|
||||
/**
|
||||
* This type represents a browse (service instance enumeration) DNS response.
|
||||
*
|
||||
*/
|
||||
class BrowseResponse : public Response
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method gets the service name associated with a DNS browse response.
|
||||
*
|
||||
* This method MUST only be used from `BrowseCallback`.
|
||||
*
|
||||
* @param[out] aNameBuffer A buffer to char array to output the host name.
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The host name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
*
|
||||
*/
|
||||
otError GetServiceName(char *aNameBuffer, uint16_t aNameBufferSize) const
|
||||
{
|
||||
return GetName(aNameBuffer, aNameBufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets a service instance associated with a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This method MUST only be used from `BrowseCallback`.
|
||||
*
|
||||
* A response may include multiple service instance records. @p aIndex can be used to iterate through the list.
|
||||
* Index zero gives the the first record. When we reach end of the list, `OT_ERROR_NOT_FOUND` is returned.
|
||||
*
|
||||
* Note that this method gets the service instance label and not the full service instance name which is of the
|
||||
* form `<Instance>.<Service>.<Domain>`.
|
||||
*
|
||||
* @param[in] aResponse A pointer to a response.
|
||||
* @param[in] aIndex The service instance record index to retrieve.
|
||||
* @param[out] aLabelBuffer A char array to output the service instance label (MUST NOT be NULL).
|
||||
* @param[in] aLabelBufferSize The size of @p aLabelBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer.
|
||||
* @retval OT_ERROR_NOT_FOUND No service instance record at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records.
|
||||
*
|
||||
*/
|
||||
otError GetServiceInstance(uint16_t aIndex, char *aLabelBuffer, uint8_t aLabelBufferSize) const;
|
||||
|
||||
/**
|
||||
* This method gets info for a service instance from a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This method MUST only be used from `BrowseCallback`.
|
||||
*
|
||||
* A browse DNS response should include the SRV, TXT, and AAAA records for the service instances that are
|
||||
* enumerated (note that it is a SHOULD and not a MUST requirement). This method tries to retrieve this info
|
||||
* for a given service instance.
|
||||
*
|
||||
* If no matching SRV record is found, `OT_ERROR_NOT_FOUND` is returned.
|
||||
* If a matching SRV record is found, @p aServiceInfo is updated returning `OT_ERROR_NONE`.
|
||||
* If no matching TXT record is found, `mTxtDataSize` in @p aServiceInfo is set to zero.
|
||||
* If no matching AAAA record is found, `mHostAddress is set to all zero or unspecified address.
|
||||
* If there are multiple AAAA records for the host name `mHostAddress` is set to the first one.
|
||||
* The other addresses can be retrieved using `GetHostAddress()` method.
|
||||
*
|
||||
* @param[in] aInstanceLabel The service instance label (MUST NOT be `nullptr`).
|
||||
* @param[out] aServiceInfo A `ServiceInfo` to output the service instance information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated.
|
||||
* @retval OT_ERROR_NOT_FOUND Could not find a matching SRV record for @p aInstanceLabel.
|
||||
* @retval OT_ERROR_NO_BUFS The host name and/or the TXT data could not fit in given buffers.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records.
|
||||
*
|
||||
*/
|
||||
otError GetServiceInfo(const char *aInstanceLabel, ServiceInfo &aServiceInfo) const;
|
||||
|
||||
/**
|
||||
* This method gets the host IPv6 address from a DNS browse (service instance enumeration) response.
|
||||
*
|
||||
* This method MUST only be used from `BrowseCallback`.
|
||||
*
|
||||
* The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the
|
||||
* list of addresses. Index zero gets the first address and so on. When we reach end of the list, this method
|
||||
* returns `OT_ERROR_NOT_FOUND`.
|
||||
*
|
||||
* @param[in] aHostName The host name to get the address (MUST NOT be `nullptr`).
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A reference to an IPv6 address to output the address.
|
||||
* @param[out] aTtl A reference to a `uint32_t` to output TTL for the address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record for @p aHostname at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records.
|
||||
*
|
||||
*/
|
||||
otError GetHostAddress(const char *aHostName, uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;
|
||||
|
||||
private:
|
||||
otError FindPtrRecord(const char *aInstanceLabel, Name &aInstanceName) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents the function pointer callback which is called when a response for a service instance
|
||||
* resolution DNS query is received.
|
||||
*
|
||||
*/
|
||||
typedef otDnsServiceCallback ServiceCallback;
|
||||
|
||||
/**
|
||||
* This type represents a service instance resolution DNS response.
|
||||
*
|
||||
*/
|
||||
class ServiceResponse : public Response
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method gets the service instance name associated with a DNS service instance resolution response.
|
||||
*
|
||||
* This method MUST only be used from `ServiceCallback`.
|
||||
*
|
||||
* @param[out] aLabelBuffer A buffer to char array to output the service instance label (MUST NOT be NULL).
|
||||
* @param[in] aLabelBufferSize The size of @p aLabelBuffer.
|
||||
* @param[out] aNameBuffer A buffer to char array to output the rest of service name (can be NULL if user
|
||||
* is not interested in getting the name).
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance name was read successfully.
|
||||
* @retval OT_ERROR_NO_BUFS Either the label or name does not fit in the given buffers.
|
||||
*
|
||||
*/
|
||||
otError GetServiceName(char * aLabelBuffer,
|
||||
uint8_t aLabelBufferSize,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize) const;
|
||||
|
||||
/**
|
||||
* This method gets info for a service instance from a DNS service instance resolution response.
|
||||
*
|
||||
* This method MUST only be used from `ServiceCallback`.
|
||||
*
|
||||
* If no matching SRV record is found, `OT_ERROR_NOT_FOUND` is returned.
|
||||
* If a matching SRV record is found, @p aServiceInfo is updated and `OT_ERROR_NONE` is returned.
|
||||
* If no matching TXT record is found, `mTxtDataSize` in @p aServiceInfo is set to zero.
|
||||
* If no matching AAAA record is found, `mHostAddress is set to all zero or unspecified address.
|
||||
* If there are multiple AAAA records for the host name, `mHostAddress` is set to the first one.
|
||||
* The other addresses can be retrieved using `GetHostAddress()` method.
|
||||
*
|
||||
* @param[out] aServiceInfo A `ServiceInfo` to output the service instance information
|
||||
*
|
||||
* @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated.
|
||||
* @retval OT_ERROR_NOT_FOUND Could not find a matching SRV record.
|
||||
* @retval OT_ERROR_NO_BUFS The host name and/or TXT data could not fit in the given buffers.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||
*
|
||||
*/
|
||||
otError GetServiceInfo(ServiceInfo &aServiceInfo) const;
|
||||
|
||||
/**
|
||||
* This method gets the host IPv6 address from a DNS service instance resolution response.
|
||||
*
|
||||
* This method MUST only be used from `ServiceCallback`.
|
||||
*
|
||||
* The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the
|
||||
* list of addresses. Index zero gets the first address and so on. When we reach end of the list, this method
|
||||
* returns `OT_ERROR_NOT_FOUND`.
|
||||
*
|
||||
* @param[in] aHostName The host name to get the address (MUST NOT be `nullptr`).
|
||||
* @param[in] aIndex The address record index to retrieve.
|
||||
* @param[out] aAddress A reference to an IPv6 address to output the address.
|
||||
* @param[out] aTtl A reference to a `uint32_t` to output TTL for the address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The address was read successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND No address record for @p aHostname at @p aIndex.
|
||||
* @retval OT_ERROR_PARSE Could not parse the records.
|
||||
*
|
||||
*/
|
||||
otError GetHostAddress(const char *aHostName, uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
@@ -124,84 +405,150 @@ public:
|
||||
/**
|
||||
* This method stops the DNS client.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully stopped the DNS client.
|
||||
*
|
||||
*/
|
||||
otError Stop(void);
|
||||
void Stop(void);
|
||||
|
||||
/**
|
||||
* This method sends a DNS query.
|
||||
* This method sends an address resolution DNS query for AAAA (IPv6) record for a given host name.
|
||||
*
|
||||
* @param[in] aQuery A pointer to specify DNS query parameters.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aServerSockAddr The server socket address.
|
||||
* @param[in] aHostName The host name for which to query the address (MUST NOT be `nullptr`).
|
||||
* @param[in] aNoRecursion Indicates whether name server can resolve the query recursively or not.
|
||||
* @param[in] aCallback A callback function pointer to report the result of query.
|
||||
* @param[in] aContext A pointer to arbitrary context information passed to @p aCallback.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully sent DNS query.
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data.
|
||||
* @retval OT_ERROR_INVALID_ARGS Invalid arguments supplied.
|
||||
* @retval OT_ERROR_NONE Successfully sent DNS query.
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data.
|
||||
* @retval OT_ERROR_INVALID_ARGS The host name is not valid format.
|
||||
* @retval OT_ERROR_INVALID_STATE Cannot send query since Thread interface is not up.
|
||||
*
|
||||
*/
|
||||
otError Query(const QueryInfo &aQuery, ResponseHandler aHandler, void *aContext);
|
||||
otError ResolveAddress(const Ip6::SockAddr &aServerSockAddr,
|
||||
const char * aHostName,
|
||||
bool aNoRecursion,
|
||||
AddressCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
/**
|
||||
* This method sends a browse (service instance enumeration) DNS query for a given service name.
|
||||
*
|
||||
* @param[in] aServerSockAddr The server socket address.
|
||||
* @param[in] aServiceName The service name to query for (MUST NOT be `nullptr`).
|
||||
* @param[in] aCallback The callback to report the response or errors (such as time-out).
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query.
|
||||
*
|
||||
*/
|
||||
otError Browse(const Ip6::SockAddr &aServerSockAddr,
|
||||
const char * aServiceName,
|
||||
BrowseCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function sends a DNS service instance resolution query for a given service instance.
|
||||
*
|
||||
* @param[in] aServerSockAddr The server socket address.
|
||||
* @param[in] aInstanceLabel The service instance label.
|
||||
* @param[in] aServiceName The service name (together with @p aInstanceLabel form full instance name).
|
||||
* @param[in] aCallback A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query.
|
||||
*
|
||||
*/
|
||||
otError ResolveService(const Ip6::SockAddr &aServerSockAddr,
|
||||
const char * aInstanceLabel,
|
||||
const char * aServiceName,
|
||||
otDnsServiceCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
|
||||
private:
|
||||
/**
|
||||
* Retransmission parameters.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kResponseTimeout = OPENTHREAD_CONFIG_DNS_RESPONSE_TIMEOUT,
|
||||
kResponseTimeout = OPENTHREAD_CONFIG_DNS_RESPONSE_TIMEOUT, // in msec
|
||||
kMaxRetransmit = OPENTHREAD_CONFIG_DNS_MAX_RETRANSMIT,
|
||||
};
|
||||
|
||||
enum
|
||||
enum QueryType : uint8_t
|
||||
{
|
||||
kBufSize = 16
|
||||
kAddressQuery, // Address resolution.
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
kBrowseQuery, // Browse (service instance enumeration).
|
||||
kServiceQuery, // Service instance resolution.
|
||||
#endif
|
||||
};
|
||||
|
||||
struct QueryMetadata
|
||||
union Callback
|
||||
{
|
||||
otError AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
void UpdateIn(Message &aMessage) const;
|
||||
|
||||
const char * mHostname;
|
||||
ResponseHandler mResponseHandler;
|
||||
void * mResponseContext;
|
||||
TimeMilli mTransmissionTime;
|
||||
Ip6::Address mSourceAddress;
|
||||
Ip6::Address mDestinationAddress;
|
||||
uint16_t mDestinationPort;
|
||||
uint8_t mRetransmissionCount;
|
||||
AddressCallback mAddressCallback;
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
BrowseCallback mBrowseCallback;
|
||||
ServiceCallback mServiceCallback;
|
||||
#endif
|
||||
};
|
||||
|
||||
Message *NewMessage(const Header &aHeader);
|
||||
Message *CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata);
|
||||
void DequeueMessage(Message &aMessage);
|
||||
otError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
typedef MessageQueue QueryList; // List of queries.
|
||||
|
||||
otError GenerateUniqueRandomId(uint16_t &aRandomId);
|
||||
struct QueryInfo : public Clearable<QueryInfo> // Query related Info
|
||||
{
|
||||
void ReadFrom(const Query &aQuery) { IgnoreError(aQuery.Read(0, *this)); }
|
||||
|
||||
otError CompareQuestions(Message &aMessageResponse, Message &aMessageQuery, uint16_t &aOffset);
|
||||
QueryType mQueryType;
|
||||
uint16_t mMessageId;
|
||||
Ip6::SockAddr mServerSockAddr;
|
||||
Callback mCallback;
|
||||
void * mCallbackContext;
|
||||
TimeMilli mRetransmissionTime;
|
||||
uint8_t mRetransmissionCount;
|
||||
bool mNoRecursion;
|
||||
// Followed by the name (service, host, instance) encoded as a `Dns::Name`.
|
||||
};
|
||||
|
||||
Message *FindQueryById(uint16_t aMessageId);
|
||||
void FinalizeDnsTransaction(Message & aQuery,
|
||||
const QueryMetadata &aQueryMetadata,
|
||||
const Ip6::Address * aAddress,
|
||||
uint32_t aTtl,
|
||||
otError aResult);
|
||||
enum : uint16_t
|
||||
{
|
||||
kNameOffsetInQuery = sizeof(QueryInfo),
|
||||
};
|
||||
|
||||
static void HandleRetransmissionTimer(Timer &aTimer);
|
||||
void HandleRetransmissionTimer(void);
|
||||
otError StartQuery(QueryInfo & aInfo,
|
||||
const Ip6::SockAddr &aServerSockAddr,
|
||||
const char * aLabel,
|
||||
const char * aName,
|
||||
void * aContext);
|
||||
otError AllocateQuery(const QueryInfo &aInfo, const char *aLabel, const char *aName, Query *&aQuery);
|
||||
void FreeQuery(Query &aQuery);
|
||||
void UpdateQuery(Query &aQuery, const QueryInfo &aInfo) { aQuery.Write(0, aInfo); }
|
||||
void SendQuery(Query &aQuery);
|
||||
void SendQuery(Query &aQuery, QueryInfo &aInfo, bool aUpdateTimer);
|
||||
void FinalizeQuery(Query &aQuery, otError aError);
|
||||
void FinalizeQuery(Response &Response, QueryType aType, otError aError);
|
||||
static void GetCallback(const Query &aQuery, Callback &aCallback, void *&aContext);
|
||||
otError AppendNameFromQuery(const Query &aQuery, Message &aMessage);
|
||||
Query * FindQueryById(uint16_t aMessageId);
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMsgInfo);
|
||||
void ProcessResponse(const Message &aMessage);
|
||||
otError ParseResponse(Response &aResponse, QueryType &aType, otError &aResponseError);
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
static const uint8_t kQuestionCount[];
|
||||
static const uint16_t *kQuestionRecordTypes[];
|
||||
|
||||
static const uint16_t kAddressQueryRecordTypes[];
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
|
||||
static const uint16_t kBrowseQueryRecordTypes[];
|
||||
static const uint16_t kServiceQueryRecordTypes[];
|
||||
#endif
|
||||
|
||||
Ip6::Udp::Socket mSocket;
|
||||
|
||||
MessageQueue mPendingQueries;
|
||||
TimerMilli mRetransmissionTimer;
|
||||
QueryList mQueries;
|
||||
TimerMilli mTimer;
|
||||
};
|
||||
|
||||
} // namespace Dns
|
||||
|
||||
@@ -102,7 +102,7 @@ otError Header::ResponseCodeToError(Response aResponse)
|
||||
|
||||
otError Name::AppendLabel(const char *aLabel, Message &aMessage)
|
||||
{
|
||||
return AppendLabel(aLabel, static_cast<uint8_t>(StringLength(aLabel, kMaxLabelLength + 1)), aMessage);
|
||||
return AppendLabel(aLabel, static_cast<uint8_t>(StringLength(aLabel, kMaxLabelSize)), aMessage);
|
||||
}
|
||||
|
||||
otError Name::AppendLabel(const char *aLabel, uint8_t aLength, Message &aMessage)
|
||||
@@ -120,7 +120,7 @@ exit:
|
||||
|
||||
otError Name::AppendMultipleLabels(const char *aLabels, Message &aMessage)
|
||||
{
|
||||
return AppendMultipleLabels(aLabels, kMaxLength, aMessage);
|
||||
return AppendMultipleLabels(aLabels, kMaxNameLength, aMessage);
|
||||
}
|
||||
|
||||
otError Name::AppendMultipleLabels(const char *aLabels, uint8_t aLength, Message &aMessage)
|
||||
@@ -270,7 +270,7 @@ otError Name::ReadName(const Message &aMessage, uint16_t &aOffset, char *aNameBu
|
||||
// here since `iterator.ReadLabel()` would verify it.
|
||||
}
|
||||
|
||||
labelLength = static_cast<uint8_t>(OT_MIN(kMaxLabelLength + 1, aNameBufferSize));
|
||||
labelLength = static_cast<uint8_t>(OT_MIN(static_cast<uint8_t>(kMaxLabelSize), aNameBufferSize));
|
||||
SuccessOrExit(error = iterator.ReadLabel(aNameBuffer, labelLength, /* aAllowDotCharInLabel */ false));
|
||||
aNameBuffer += labelLength;
|
||||
aNameBufferSize -= labelLength;
|
||||
@@ -548,8 +548,8 @@ bool Name::LabelIterator::CompareLabel(const LabelIterator &aOtherIterator) cons
|
||||
bool Name::IsSubDomainOf(const char *aName, const char *aDomain)
|
||||
{
|
||||
bool match = false;
|
||||
uint16_t nameLength = StringLength(aName, kMaxLength);
|
||||
uint16_t domainLength = StringLength(aDomain, kMaxLength);
|
||||
uint16_t nameLength = StringLength(aName, kMaxNameLength);
|
||||
uint16_t domainLength = StringLength(aDomain, kMaxNameLength);
|
||||
|
||||
if (nameLength > 0 && aName[nameLength - 1] == kLabelSeperatorChar)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/dns.h>
|
||||
#include <openthread/dns_client.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
@@ -490,9 +491,29 @@ class Name : public Clearable<Name>
|
||||
public:
|
||||
enum : uint8_t
|
||||
{
|
||||
kMaxLabelLength = 63, ///< Max number of characters in a label.
|
||||
kMaxLength = 254, ///< Max number of characters in a name.
|
||||
kMaxEncodedLength = 255, ///< Max length of an encoded name.
|
||||
/**
|
||||
* Max size (number of chars) in a name string array (includes null char at the end of string).
|
||||
*
|
||||
*/
|
||||
kMaxNameSize = OT_DNS_MAX_NAME_SIZE,
|
||||
|
||||
/**
|
||||
* Maximum length in a name string (does not include null char at the end of string).
|
||||
*
|
||||
*/
|
||||
kMaxNameLength = kMaxNameSize - 1,
|
||||
|
||||
/**
|
||||
* Max size (number of chars) in a label string array (includes null char at the end of the string).
|
||||
*
|
||||
*/
|
||||
kMaxLabelSize = OT_DNS_MAX_LABEL_SIZE,
|
||||
|
||||
/**
|
||||
* Maximum length in a label string (does not include null char at the end of string).
|
||||
*
|
||||
*/
|
||||
kMaxLabelLength = kMaxLabelSize - 1,
|
||||
};
|
||||
|
||||
enum : char
|
||||
@@ -972,6 +993,8 @@ private:
|
||||
kLabelTypeMask = 0xc0, // 0b1100_0000 (first two bits)
|
||||
kTextLabelType = 0x00, // Text label type (00)
|
||||
kPointerLabelType = 0xc0, // Pointer label type - compressed name (11)
|
||||
|
||||
kMaxEncodedLength = 255, ///< Max length of an encoded name.
|
||||
};
|
||||
|
||||
enum : uint16_t
|
||||
@@ -1085,17 +1108,18 @@ public:
|
||||
*/
|
||||
enum : uint16_t
|
||||
{
|
||||
kTypeZero = 0, ///< Zero is used as a special indicator for the SIG RR (SIG(0) from RFC 2931).
|
||||
kTypeA = 1, ///< Address record (IPv4).
|
||||
kTypeSoa = 6, ///< Start of (zone of) authority.
|
||||
kTypePtr = 12, ///< PTR record.
|
||||
kTypeTxt = 16, ///< TXT record.
|
||||
kTypeSig = 24, ///< SIG record.
|
||||
kTypeKey = 25, ///< KEY record.
|
||||
kTypeAaaa = 28, ///< IPv6 address record.
|
||||
kTypeSrv = 33, ///< SRV locator record.
|
||||
kTypeOpt = 41, ///< Option record.
|
||||
kTypeAny = 255, ///< ANY record.
|
||||
kTypeZero = 0, ///< Zero is used as a special indicator for the SIG RR (SIG(0) from RFC 2931).
|
||||
kTypeA = 1, ///< Address record (IPv4).
|
||||
kTypeSoa = 6, ///< Start of (zone of) authority.
|
||||
kTypeCname = 5, ///< CNAME record.
|
||||
kTypePtr = 12, ///< PTR record.
|
||||
kTypeTxt = 16, ///< TXT record.
|
||||
kTypeSig = 24, ///< SIG record.
|
||||
kTypeKey = 25, ///< KEY record.
|
||||
kTypeAaaa = 28, ///< IPv6 address record.
|
||||
kTypeSrv = 33, ///< SRV locator record.
|
||||
kTypeOpt = 41, ///< Option record.
|
||||
kTypeAny = 255, ///< ANY record.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1373,6 +1397,60 @@ private:
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Resource Record body format of CNAME type.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class CnameRecord : public ResourceRecord
|
||||
{
|
||||
public:
|
||||
enum : uint16_t
|
||||
{
|
||||
kType = kTypeCname, ///< The CNAME record type.
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the CNAME Resource Record by setting its type and class.
|
||||
*
|
||||
* Other record fields (TTL, length) remain unchanged/uninitialized.
|
||||
*
|
||||
* @param[in] aClass The class of the resource record (default is `kClassInternet`).
|
||||
*
|
||||
*/
|
||||
void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeCname, aClass); }
|
||||
|
||||
/**
|
||||
* This method parses and reads the CNAME alias name from a message.
|
||||
*
|
||||
* This method also verifies that the CNAME record is well-formed (e.g., the record data length `GetLength()`
|
||||
* matches the CNAME encoded name).
|
||||
*
|
||||
* @param[in] aMessage The message to read from. `aMessage.GetOffset()` MUST point to the start of
|
||||
* DNS header.
|
||||
* @param[inout] aOffset On input, the offset in @p aMessage to start of CNAME name field.
|
||||
* On exit when successfully read, @p aOffset is updated to point to the byte
|
||||
* after the entire PTR record (skipping over the record).
|
||||
* @param[out] aNameBuffer A pointer to a char array to output the read name as a null-terminated C string
|
||||
* (MUST NOT be nullptr).
|
||||
* @param[in] aNameBufferSize The size of @p aNameBuffer.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The CNAME name was read successfully. @p aOffset and @p aNameBuffer are updated.
|
||||
* @retval OT_ERROR_PARSE The CNAME record in @p aMessage could not be parsed (invalid format).
|
||||
* @retval OT_ERROR_NO_BUFS Name could not fit in @p aNameBufferSize chars.
|
||||
*
|
||||
*/
|
||||
otError ReadCanonicalName(const Message &aMessage,
|
||||
uint16_t & aOffset,
|
||||
char * aNameBuffer,
|
||||
uint16_t aNameBufferSize) const
|
||||
{
|
||||
return ResourceRecord::ReadName(aMessage, aOffset, /* aStartOffset */ aOffset - sizeof(CnameRecord),
|
||||
aNameBuffer, aNameBufferSize, /* aSkipRecord */ true);
|
||||
}
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Resource Record body format of PTR type.
|
||||
*
|
||||
@@ -2424,10 +2502,10 @@ class Question
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor for Question.
|
||||
* Default constructor for Question
|
||||
*
|
||||
*/
|
||||
Question() = default;
|
||||
Question(void) = default;
|
||||
|
||||
/**
|
||||
* Constructor for Question.
|
||||
@@ -2471,21 +2549,9 @@ public:
|
||||
*/
|
||||
void SetClass(uint16_t aClass) { mClass = HostSwap16(aClass); }
|
||||
|
||||
/**
|
||||
* This method appends the question data to the message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully appended the question data.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
otError AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
|
||||
private:
|
||||
uint16_t mType; // The type of the data in question section.
|
||||
uint16_t mClass; // The class of the data in question section.
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
|
||||
@@ -116,7 +116,7 @@ void Server::ProcessQuery(Message &aMessage, Message &aResponse, const Header &a
|
||||
uint16_t readOffset, nameSerializeOffset;
|
||||
Question question;
|
||||
uint16_t qtype;
|
||||
char name[Dns::Name::kMaxLength + 1];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
otError error = OT_ERROR_NONE;
|
||||
NameCompressInfo compressInfo;
|
||||
|
||||
@@ -376,8 +376,8 @@ otError Server::AppendInstanceName(Message &aMessage, const char *aName, NameCom
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t serviceStart = static_cast<uint8_t>(StringLength(aName, Name::kMaxLength) -
|
||||
StringLength(aCompressInfo.GetServiceName(), Name::kMaxLength));
|
||||
uint8_t serviceStart = static_cast<uint8_t>(StringLength(aName, Name::kMaxNameLength) -
|
||||
StringLength(aCompressInfo.GetServiceName(), Name::kMaxNameLength));
|
||||
|
||||
aCompressInfo.SetInstanceNameOffset(aMessage.GetLength(), aName);
|
||||
|
||||
@@ -400,8 +400,8 @@ otError Server::AppendHostName(Message &aMessage, const char *aName, NameCompres
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t domainStart = static_cast<uint8_t>(StringLength(aName, Name::kMaxLength) -
|
||||
StringLength(aCompressInfo.GetDomainName(), Name::kMaxLength));
|
||||
uint8_t domainStart = static_cast<uint8_t>(StringLength(aName, Name::kMaxNameLength) -
|
||||
StringLength(aCompressInfo.GetDomainName(), Name::kMaxNameLength));
|
||||
|
||||
aCompressInfo.SetHostNameOffset(aMessage.GetLength(), aName);
|
||||
|
||||
@@ -427,8 +427,8 @@ void Server::IncResourceRecordCount(Header &aHeader, bool aAdditional)
|
||||
|
||||
otError Server::FindNameComponents(const char *aName, const char *aDomain, NameComponentsOffsetInfo &aInfo)
|
||||
{
|
||||
uint8_t nameLen = static_cast<uint8_t>(StringLength(aName, Name::kMaxLength));
|
||||
uint8_t domainLen = static_cast<uint8_t>(StringLength(aDomain, Name::kMaxLength));
|
||||
uint8_t nameLen = static_cast<uint8_t>(StringLength(aName, Name::kMaxNameLength));
|
||||
uint8_t domainLen = static_cast<uint8_t>(StringLength(aDomain, Name::kMaxNameLength));
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t labelBegin, labelEnd;
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ otError Server::SetDomain(const char *aDomain)
|
||||
|
||||
VerifyOrExit(!mEnabled, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
VerifyOrExit(length > 0 && length <= Dns::Name::kMaxLength, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(length > 0 && length < Dns::Name::kMaxNameSize, error = OT_ERROR_INVALID_ARGS);
|
||||
if (aDomain[length - 1] != '.')
|
||||
{
|
||||
appendTrailingDot = 1;
|
||||
@@ -556,7 +556,7 @@ otError Server::ProcessZoneSection(const Message & aMessage,
|
||||
Dns::Zone & aZone) const
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
char name[Dns::Name::kMaxLength + 1];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
Dns::Zone zone;
|
||||
|
||||
VerifyOrExit(aDnsHeader.GetZoneRecordCount() == 1, error = OT_ERROR_PARSE);
|
||||
@@ -618,7 +618,7 @@ otError Server::ProcessHostDescriptionInstruction(Host & aHost
|
||||
|
||||
for (uint16_t i = 0; i < aDnsHeader.GetUpdateRecordCount(); ++i)
|
||||
{
|
||||
char name[Dns::Name::kMaxLength + 1];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
Dns::ResourceRecord record;
|
||||
|
||||
SuccessOrExit(error = Dns::Name::ReadName(aMessage, aOffset, name, sizeof(name)));
|
||||
@@ -723,9 +723,9 @@ otError Server::ProcessServiceDiscoveryInstructions(Host & aHo
|
||||
|
||||
for (uint16_t i = 0; i < aDnsHeader.GetUpdateRecordCount(); ++i)
|
||||
{
|
||||
char name[Dns::Name::kMaxLength + 1];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
Dns::ResourceRecord record;
|
||||
char serviceName[Dns::Name::kMaxLength + 1];
|
||||
char serviceName[Dns::Name::kMaxNameSize];
|
||||
Service * service;
|
||||
|
||||
SuccessOrExit(error = Dns::Name::ReadName(aMessage, aOffset, name, sizeof(name)));
|
||||
@@ -774,7 +774,7 @@ otError Server::ProcessServiceDescriptionInstructions(Host & a
|
||||
|
||||
for (uint16_t i = 0; i < aDnsHeader.GetUpdateRecordCount(); ++i)
|
||||
{
|
||||
char name[Dns::Name::kMaxLength + 1];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
Dns::ResourceRecord record;
|
||||
|
||||
SuccessOrExit(error = Dns::Name::ReadName(aMessage, aOffset, name, sizeof(name)));
|
||||
@@ -798,7 +798,7 @@ otError Server::ProcessServiceDescriptionInstructions(Host & a
|
||||
if (record.GetType() == Dns::ResourceRecord::kTypeSrv)
|
||||
{
|
||||
Dns::SrvRecord srvRecord;
|
||||
char hostName[Dns::Name::kMaxLength + 1];
|
||||
char hostName[Dns::Name::kMaxNameSize];
|
||||
uint16_t hostNameLength = sizeof(hostName);
|
||||
|
||||
VerifyOrExit(record.GetClass() == aZone.GetClass(), error = OT_ERROR_FAILED);
|
||||
@@ -864,7 +864,7 @@ otError Server::ProcessAdditionalSection(Host * aHost,
|
||||
char name[2]; // The root domain name (".") is expected.
|
||||
uint16_t sigOffset;
|
||||
uint16_t sigRdataOffset;
|
||||
char signerName[Dns::Name::kMaxLength + 1];
|
||||
char signerName[Dns::Name::kMaxNameSize];
|
||||
uint16_t signatureLength;
|
||||
|
||||
VerifyOrExit(aDnsHeader.GetAdditionalRecordCount() == 2, error = OT_ERROR_FAILED);
|
||||
|
||||
@@ -182,7 +182,7 @@ void ThreadNetif::Down(void)
|
||||
VerifyOrExit(mIsUp);
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
|
||||
IgnoreError(Get<Dns::Client>().Stop());
|
||||
Get<Dns::Client>().Stop();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
IgnoreError(Get<Sntp::Client>().Stop());
|
||||
|
||||
@@ -478,6 +478,14 @@
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
*
|
||||
* Define to 1 to enable SRP Server support.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_CLIENT_DOMAIN_NAME_CHANGE_ENABLE
|
||||
*
|
||||
|
||||
@@ -42,9 +42,8 @@ void TestDnsName(void)
|
||||
{
|
||||
enum
|
||||
{
|
||||
kMaxSize = 300,
|
||||
kLabelSize = 64,
|
||||
kNameSize = 256,
|
||||
kMaxSize = 300,
|
||||
kMaxNameLength = Dns::Name::kMaxNameSize - 1,
|
||||
};
|
||||
|
||||
struct TestName
|
||||
@@ -62,9 +61,9 @@ void TestDnsName(void)
|
||||
uint8_t buffer[kMaxSize];
|
||||
uint16_t len;
|
||||
uint16_t offset;
|
||||
char label[kLabelSize];
|
||||
char label[Dns::Name::kMaxLabelSize];
|
||||
uint8_t labelLength;
|
||||
char name[kNameSize];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
|
||||
static const uint8_t kEncodedName1[] = {7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0};
|
||||
static const uint8_t kEncodedName2[] = {3, 'f', 'o', 'o', 1, 'a', 2, 'b', 'b', 3, 'e', 'd', 'u', 0};
|
||||
@@ -297,11 +296,11 @@ void TestDnsName(void)
|
||||
{
|
||||
if (maxLengthName[strlen(maxLengthName) - 1] == '.')
|
||||
{
|
||||
VerifyOrQuit(strlen(maxLengthName) == Dns::Name::kMaxLength, "invalid max length string");
|
||||
VerifyOrQuit(strlen(maxLengthName) == kMaxNameLength, "invalid max length string");
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(strlen(maxLengthName) == Dns::Name::kMaxLength - 1, "invalid max length string");
|
||||
VerifyOrQuit(strlen(maxLengthName) == kMaxNameLength - 1, "invalid max length string");
|
||||
}
|
||||
|
||||
IgnoreError(message->SetLength(0));
|
||||
@@ -742,8 +741,8 @@ void TestHeaderAndResourceRecords(void)
|
||||
Dns::ResourceRecord record;
|
||||
Ip6::Address hostAddress;
|
||||
|
||||
char label[Dns::Name::kMaxLabelLength + 1];
|
||||
char name[Dns::Name::kMaxLength];
|
||||
char label[Dns::Name::kMaxLabelSize];
|
||||
char name[Dns::Name::kMaxNameSize];
|
||||
uint8_t buffer[kMaxSize];
|
||||
|
||||
printf("================================================================\n");
|
||||
|
||||
Reference in New Issue
Block a user