mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[dnssd-server] implement DNS-SD discovery proxy functionality in core (#10050)
This commit implements a generic discovery proxy in the DNS-SD server. It uses a set of newly added `otPlatDnssd` platform DNS-SD(mDNS) APIs to start or stop browsers, SRV/TXT resolvers, and IPv6/IPv4 address resolvers. These APIs closely match the native OpenThread mDNS implementation. OpenThread DNS-SD's existing `QueryCallback` mechanism, enabling customized discovery proxy implementations, remains supported. This commit includes a comprehensive unit test. This test validates the discovery proxy's behavior, covering: standard use cases, request timeout, s hared resolver/browser usage for multiple queries with the same name, filtering of invalid addresses, and various edge cases.
This commit is contained in:
committed by
GitHub
parent
a8f07b57cf
commit
5dbbab175b
@@ -201,6 +201,7 @@ ot_option(OT_DNS_CLIENT OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE "DNS client")
|
||||
ot_option(OT_DNS_CLIENT_OVER_TCP OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE "Enable dns query over tcp")
|
||||
ot_option(OT_DNS_DSO OPENTHREAD_CONFIG_DNS_DSO_ENABLE "DNS Stateful Operations (DSO)")
|
||||
ot_option(OT_DNS_UPSTREAM_QUERY OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE "Allow sending DNS queries to upstream")
|
||||
ot_option(OT_DNSSD_DISCOVERY_PROXY OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE "DNS-SD discovery proxy")
|
||||
ot_option(OT_DNSSD_SERVER OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE "DNS-SD server")
|
||||
ot_option(OT_DUA OPENTHREAD_CONFIG_DUA_ENABLE "Domain Unicast Address (DUA)")
|
||||
ot_option(OT_ECDSA OPENTHREAD_CONFIG_ECDSA_ENABLE "ECDSA")
|
||||
|
||||
@@ -104,4 +104,64 @@ void otPlatDnssdUnregisterKey(otInstance *aInstance,
|
||||
OT_UNUSED_VARIABLE(aCallback);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (419)
|
||||
#define OPENTHREAD_API_VERSION (420)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
+44
-108
@@ -500,158 +500,94 @@ otError otMdnsGetNextService(otInstance *aInstance,
|
||||
*/
|
||||
otError otMdnsGetNextKey(otInstance *aInstance, otMdnsIterator *aIterator, otMdnsKey *aKey, otMdnsEntryState *aState);
|
||||
|
||||
typedef struct otMdnsBrowseResult otMdnsBrowseResult;
|
||||
typedef struct otMdnsSrvResult otMdnsSrvResult;
|
||||
typedef struct otMdnsTxtResult otMdnsTxtResult;
|
||||
typedef struct otMdnsAddressResult otMdnsAddressResult;
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report a browse result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The browse result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otMdnsBrowseCallback)(otInstance *aInstance, const otMdnsBrowseResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report an SRV resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The SRV resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otMdnsSrvCallback)(otInstance *aInstance, const otMdnsSrvResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report a TXT resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The TXT resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otMdnsTxtCallback)(otInstance *aInstance, const otMdnsTxtResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents the callback function use to report a IPv6/IPv4 address resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The address resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otMdnsAddressCallback)(otInstance *aInstance, const otMdnsAddressResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents a service browser.
|
||||
*
|
||||
* Refer to `otPlatDnssdBrowser` for documentation of member fields and `otMdnsStartBrowser()` for how they are used.
|
||||
*
|
||||
*/
|
||||
typedef struct otMdnsBrowser
|
||||
{
|
||||
const char *mServiceType; ///< The service type (e.g., "_mt._udp"). MUST NOT include domain name.
|
||||
const char *mSubTypeLabel; ///< The sub-type label if browsing for sub-type, NULL otherwise.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otMdnsBrowseCallback mCallback; ///< The callback to report result.
|
||||
} otMdnsBrowser;
|
||||
typedef otPlatDnssdBrowser otMdnsBrowser;
|
||||
|
||||
/**
|
||||
* Represents the callback function pointer type used to report a browse result.
|
||||
*
|
||||
*/
|
||||
typedef otPlatDnssdBrowseCallback otMdnsBrowseCallback;
|
||||
|
||||
/**
|
||||
* Represents a browse result.
|
||||
*
|
||||
*/
|
||||
struct otMdnsBrowseResult
|
||||
{
|
||||
const char *mServiceType; ///< The service type (e.g., "_mt._udp").
|
||||
const char *mSubTypeLabel; ///< The sub-type label if browsing for sub-type, NULL otherwise.
|
||||
const char *mServiceInstance; ///< Service instance label.
|
||||
uint32_t mTtl; ///< TTL in seconds. Zero TTL indicates that service is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
};
|
||||
typedef otPlatDnssdBrowseResult otMdnsBrowseResult;
|
||||
|
||||
/**
|
||||
* Represents an SRV service resolver.
|
||||
*
|
||||
* Refer to `otPlatDnssdSrvResolver` for documentation of member fields and `otMdnsStartSrvResolver()` for how they are
|
||||
* used.
|
||||
*
|
||||
*/
|
||||
typedef struct otMdnsSrvResolver
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otMdnsSrvCallback mCallback; ///< The callback to report result.
|
||||
} otMdnsSrvResolver;
|
||||
typedef otPlatDnssdSrvResolver otMdnsSrvResolver;
|
||||
|
||||
/**
|
||||
* Represents the callback function pointer type used to report an SRV resolve result.
|
||||
*
|
||||
*/
|
||||
typedef otPlatDnssdSrvCallback otMdnsSrvCallback;
|
||||
|
||||
/**
|
||||
* Represents an SRV resolver result.
|
||||
*
|
||||
*/
|
||||
struct otMdnsSrvResult
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance name label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
const char *mHostName; ///< The host name (e.g., "myhost"). Can be NULL when `mTtl` is zero.
|
||||
uint16_t mPort; ///< The service port number.
|
||||
uint16_t mPriority; ///< The service priority.
|
||||
uint16_t mWeight; ///< The service weight.
|
||||
uint32_t mTtl; ///< The service TTL in seconds. Zero TTL indicates SRV record is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
};
|
||||
typedef otPlatDnssdSrvResult otMdnsSrvResult;
|
||||
|
||||
/**
|
||||
* Represents a TXT service resolver.
|
||||
*
|
||||
* Refer to `otPlatDnssdTxtResolver` for documentation of member fields and `otMdnsStartTxtResolver()` for how they are
|
||||
* used.
|
||||
*
|
||||
*/
|
||||
typedef struct otMdnsTxtResolver
|
||||
{
|
||||
const char *mServiceInstance; ///< Service instance label.
|
||||
const char *mServiceType; ///< Service type.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otMdnsTxtCallback mCallback;
|
||||
} otMdnsTxtResolver;
|
||||
typedef otPlatDnssdTxtResolver otMdnsTxtResolver;
|
||||
|
||||
/**
|
||||
* Represents the callback function pointer type used to report a TXT resolve result.
|
||||
*
|
||||
*/
|
||||
typedef otPlatDnssdTxtCallback otMdnsTxtCallback;
|
||||
|
||||
/**
|
||||
* Represents a TXT resolver result.
|
||||
*
|
||||
*/
|
||||
struct otMdnsTxtResult
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance name label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
const uint8_t *mTxtData; ///< Encoded TXT data bytes. Can be NULL when `mTtl` is zero.
|
||||
uint16_t mTxtDataLength; ///< Length of TXT data.
|
||||
uint32_t mTtl; ///< The TXT data TTL in seconds. Zero TTL indicates record is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
};
|
||||
typedef otPlatDnssdTxtResult otMdnsTxtResult;
|
||||
|
||||
/**
|
||||
* Represents an address resolver.
|
||||
*
|
||||
* Refer to `otPlatDnssdAddressResolver` for documentation of member fields and `otMdnsStartIp6AddressResolver()` or
|
||||
* `otMdnsStartIp4AddressResolver()` for how they are used.
|
||||
*
|
||||
*/
|
||||
typedef struct otMdnsAddressResolver
|
||||
{
|
||||
const char *mHostName; ///< The host name (e.g., "myhost"). MUST NOT contain domain name.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otMdnsAddressCallback mCallback; ///< The callback to report result.
|
||||
} otMdnsAddressResolver;
|
||||
typedef otPlatDnssdAddressResolver otMdnsAddressResolver;
|
||||
|
||||
/**
|
||||
* Represents the callback function pointer type use to report an IPv6/IPv4 address resolve result.
|
||||
*
|
||||
*/
|
||||
typedef otPlatDnssdAddressCallback otMdnsAddressCallback;
|
||||
|
||||
/**
|
||||
* Represents a discovered host address and its TTL.
|
||||
*
|
||||
*/
|
||||
typedef struct otMdnsAddressAndTtl
|
||||
{
|
||||
otIp6Address mAddress; ///< The IPv6 address. For IPv4 address the IPv4-mapped IPv6 address format is used.
|
||||
uint32_t mTtl; ///< The TTL in seconds.
|
||||
} otMdnsAddressAndTtl;
|
||||
typedef otPlatDnssdAddressAndTtl otMdnsAddressAndTtl;
|
||||
|
||||
/**
|
||||
* Represents address resolver result.
|
||||
*
|
||||
*/
|
||||
struct otMdnsAddressResult
|
||||
{
|
||||
const char *mHostName; ///< The host name.
|
||||
const otMdnsAddressAndTtl *mAddresses; ///< Array of host addresses and their TTL. Can be NULL if empty.
|
||||
uint16_t mAddressesLength; ///< Number of entries in `mAddresses` array.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
};
|
||||
typedef otPlatDnssdAddressResult otMdnsAddressResult;
|
||||
|
||||
/**
|
||||
* Starts a service browser.
|
||||
|
||||
@@ -65,7 +65,7 @@ extern "C" {
|
||||
*/
|
||||
typedef enum otPlatDnssdState
|
||||
{
|
||||
OT_PLAT_DNSSD_STOPPED, ///< Stopped and unable to register any service or host.
|
||||
OT_PLAT_DNSSD_STOPPED, ///< Stopped and unable to register any service or host, or start any browser/resolver.
|
||||
OT_PLAT_DNSSD_READY, ///< Running and ready to register service or host.
|
||||
} otPlatDnssdState;
|
||||
|
||||
@@ -149,6 +149,9 @@ typedef struct otPlatDnssdKey
|
||||
* The OpenThread stack will call `otPlatDnssdGetState()` (from this callback or later) to get the new state. The
|
||||
* platform MUST therefore ensure that the returned state from `otPlatDnssdGetState()` is updated before calling this.
|
||||
*
|
||||
* When the platform signals a state change to `OT_PLAT_DNSSD_STOPPED` using this callback, all active browsers and
|
||||
* resolvers are considered to be stopped, and any previously registered host, service, key entries as removed.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
*
|
||||
*/
|
||||
@@ -415,6 +418,345 @@ void otPlatDnssdUnregisterKey(otInstance *aInstance,
|
||||
otPlatDnssdRequestId aRequestId,
|
||||
otPlatDnssdRegisterCallback aCallback);
|
||||
|
||||
//======================================================================================================================
|
||||
|
||||
/**
|
||||
* Represents a browse result.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdBrowseResult
|
||||
{
|
||||
const char *mServiceType; ///< The service type (e.g., "_mt._udp").
|
||||
const char *mSubTypeLabel; ///< The sub-type label if browsing for sub-type, NULL otherwise.
|
||||
const char *mServiceInstance; ///< Service instance label.
|
||||
uint32_t mTtl; ///< TTL in seconds. Zero TTL indicates that service is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
} otPlatDnssdBrowseResult;
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report a browse result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The browse result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otPlatDnssdBrowseCallback)(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents a service browser.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdBrowser
|
||||
{
|
||||
const char *mServiceType; ///< The service type (e.g., "_mt._udp"). MUST NOT include domain name.
|
||||
const char *mSubTypeLabel; ///< The sub-type label if browsing for sub-type, NULL otherwise.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otPlatDnssdBrowseCallback mCallback; ///< The callback to report result.
|
||||
} otPlatDnssdBrowser;
|
||||
|
||||
/**
|
||||
* Represents an SRV resolver result.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdSrvResult
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance name label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
const char *mHostName; ///< The host name (e.g., "myhost"). Can be NULL when `mTtl` is zero.
|
||||
uint16_t mPort; ///< The service port number.
|
||||
uint16_t mPriority; ///< The service priority.
|
||||
uint16_t mWeight; ///< The service weight.
|
||||
uint32_t mTtl; ///< The service TTL in seconds. Zero TTL indicates SRV record is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
} otPlatDnssdSrvResult;
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report an SRV resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The SRV resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otPlatDnssdSrvCallback)(otInstance *aInstance, const otPlatDnssdSrvResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents an SRV service resolver.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdSrvResolver
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otPlatDnssdSrvCallback mCallback; ///< The callback to report result.
|
||||
} otPlatDnssdSrvResolver;
|
||||
|
||||
/**
|
||||
* Represents a TXT resolver result.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdTxtResult
|
||||
{
|
||||
const char *mServiceInstance; ///< The service instance name label.
|
||||
const char *mServiceType; ///< The service type.
|
||||
const uint8_t *mTxtData; ///< Encoded TXT data bytes. Can be NULL when `mTtl` is zero.
|
||||
uint16_t mTxtDataLength; ///< Length of TXT data.
|
||||
uint32_t mTtl; ///< The TXT data TTL in seconds. Zero TTL indicates record is removed.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
} otPlatDnssdTxtResult;
|
||||
|
||||
/**
|
||||
* Represents the callback function used to report a TXT resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The TXT resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otPlatDnssdTxtCallback)(otInstance *aInstance, const otPlatDnssdTxtResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents a TXT service resolver.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdTxtResolver
|
||||
{
|
||||
const char *mServiceInstance; ///< Service instance label.
|
||||
const char *mServiceType; ///< Service type.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otPlatDnssdTxtCallback mCallback;
|
||||
} otPlatDnssdTxtResolver;
|
||||
|
||||
/**
|
||||
* Represents a discovered host address and its TTL.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdAddressAndTtl
|
||||
{
|
||||
otIp6Address mAddress; ///< The IPv6 address. For IPv4 address the IPv4-mapped IPv6 address format is used.
|
||||
uint32_t mTtl; ///< The TTL in seconds.
|
||||
} otPlatDnssdAddressAndTtl;
|
||||
|
||||
/**
|
||||
* Represents address resolver result.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdAddressResult
|
||||
{
|
||||
const char *mHostName; ///< The host name.
|
||||
const otPlatDnssdAddressAndTtl *mAddresses; ///< Array of host addresses and their TTL. Can be NULL if empty.
|
||||
uint16_t mAddressesLength; ///< Number of entries in `mAddresses` array.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
} otPlatDnssdAddressResult;
|
||||
|
||||
/**
|
||||
* Represents the callback function use to report a IPv6/IPv4 address resolve result.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResult The address resolve result.
|
||||
*
|
||||
*/
|
||||
typedef void (*otPlatDnssdAddressCallback)(otInstance *aInstance, const otPlatDnssdAddressResult *aResult);
|
||||
|
||||
/**
|
||||
* Represents an address resolver.
|
||||
*
|
||||
*/
|
||||
typedef struct otPlatDnssdAddressResolver
|
||||
{
|
||||
const char *mHostName; ///< The host name (e.g., "myhost"). MUST NOT contain domain name.
|
||||
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
|
||||
otPlatDnssdAddressCallback mCallback; ///< The callback to report result.
|
||||
} otPlatDnssdAddressResolver;
|
||||
|
||||
/**
|
||||
* Starts a service browser.
|
||||
*
|
||||
* Initiates a continuous search for the specified `mServiceType` in @p aBrowser. For sub-type services,
|
||||
* `mSubTypeLabel` specifies the sub-type, for base services, `mSubTypeLabel` is set to NULL.
|
||||
*
|
||||
* Discovered services should be reported through the `mCallback` function in @p aBrowser. Services that have been
|
||||
* removed are reported with a TTL value of zero. The callback may be invoked immediately with cached information
|
||||
* (if available) and potentially before this function returns. When cached results are used, the reported TTL value
|
||||
* should reflect the original TTL from the last received response.
|
||||
*
|
||||
* Multiple browsers can be started for the same service, provided they use different callback functions.
|
||||
*
|
||||
* The @p aBrowser and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aBrowser The browser to be started.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStartBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser);
|
||||
|
||||
/**
|
||||
* Stops a service browser.
|
||||
*
|
||||
* No action is performed if no matching browser with the same service and callback is currently active.
|
||||
*
|
||||
* The @p aBrowser and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aBrowser The browser to stop.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStopBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser);
|
||||
|
||||
/**
|
||||
* Starts an SRV record resolver.
|
||||
*
|
||||
* Initiates a continuous SRV record resolver for the specified service in @p aResolver.
|
||||
*
|
||||
* Discovered information should be reported through the `mCallback` function in @p aResolver. When the service is
|
||||
* removed it is reported with a TTL value of zero. In this case, `mHostName` may be NULL and other result fields (such
|
||||
* as `mPort`) will be ignored by the OpenThread stack.
|
||||
*
|
||||
* The callback may be invoked immediately with cached information (if available) and potentially before this function
|
||||
* returns. When cached result is used, the reported TTL value should reflect the original TTL from the last received
|
||||
* response.
|
||||
*
|
||||
* Multiple resolvers can be started for the same service, provided they use different callback functions.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStartSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops an SRV record resolver.
|
||||
*
|
||||
* No action is performed if no matching resolver with the same service and callback is currently active.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStopSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts a TXT record resolver.
|
||||
*
|
||||
* Initiates a continuous TXT record resolver for the specified service in @p aResolver.
|
||||
*
|
||||
* Discovered information should be reported through the `mCallback` function in @p aResolver. When the TXT record is
|
||||
* removed it is reported with a TTL value of zero. In this case, `mTxtData` may be NULL, and other result fields
|
||||
* (such as `mTxtDataLength`) will be ignored by the OpenThread stack.
|
||||
*
|
||||
* The callback may be invoked immediately with cached information (if available) and potentially before this function
|
||||
* returns. When cached result is used, the reported TTL value should reflect the original TTL from the last received
|
||||
* response.
|
||||
*
|
||||
* Multiple resolvers can be started for the same service, provided they use different callback functions.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStartTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops a TXT record resolver.
|
||||
*
|
||||
* No action is performed if no matching resolver with the same service and callback is currently active.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStopTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv6 address resolver.
|
||||
*
|
||||
* Initiates a continuous IPv6 address resolver for the specified host name in @p aResolver.
|
||||
*
|
||||
* Discovered addresses should be reported through the `mCallback` function in @p aResolver. The callback should be
|
||||
* invoked whenever addresses are added or removed, providing an updated list. If all addresses are removed, the
|
||||
* callback should be invoked with an empty list (`mAddressesLength` set to zero).
|
||||
*
|
||||
* The callback may be invoked immediately with cached information (if available) and potentially before this function
|
||||
* returns. When cached result is used, the reported TTL values should reflect the original TTL from the last received
|
||||
* response.
|
||||
*
|
||||
* Multiple resolvers can be started for the same host name, provided they use different callback functions.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStartIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv6 address resolver.
|
||||
*
|
||||
* No action is performed if no matching resolver with the same host name and callback is currently active.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStopIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv4 address resolver.
|
||||
*
|
||||
* Initiates a continuous IPv4 address resolver for the specified host name in @p aResolver.
|
||||
*
|
||||
* Discovered addresses should be reported through the `mCallback` function in @p aResolver. The IPv4 addresses are
|
||||
* represented using the IPv4-mapped IPv6 address format in `mAddresses` array. The callback should be invoked
|
||||
* whenever addresses are added or removed, providing an updated list. If all addresses are removed, the callback
|
||||
* should be invoked with an empty list (`mAddressesLength` set to zero).
|
||||
*
|
||||
* The callback may be invoked immediately with cached information (if available) and potentially before this function
|
||||
* returns. When cached result is used, the reported TTL values will reflect the original TTL from the last received
|
||||
* response.
|
||||
*
|
||||
* Multiple resolvers can be started for the same host name, provided they use different callback functions.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStartIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv4 address resolver.
|
||||
*
|
||||
* No action is performed if no matching resolver with the same host name and callback is currently active.
|
||||
*
|
||||
* The @p aResolver and all its contained information (strings) are only valid during this call. The platform MUST save
|
||||
* a copy of the information if it wants to retain the information after returning from this function.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void otPlatDnssdStopIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -52,6 +52,8 @@ OT_BUILD_OPTIONS=(
|
||||
"-DOT_DHCP6_CLIENT=ON"
|
||||
"-DOT_DHCP6_SERVER=ON"
|
||||
"-DOT_DIAGNOSTIC=ON"
|
||||
"-DOT_DNSSD_DISCOVERY_PROXY=ON"
|
||||
"-DOT_DNSSD_SERVER=ON"
|
||||
"-DOT_DNS_CLIENT=ON"
|
||||
"-DOT_DNS_DSO=ON"
|
||||
"-DOT_ECDSA=ON"
|
||||
|
||||
@@ -110,6 +110,7 @@ OT_CLANG_TIDY_BUILD_OPTS=(
|
||||
'-DOT_DNS_CLIENT=ON'
|
||||
'-DOT_DNS_DSO=ON'
|
||||
'-DOT_DNS_UPSTREAM_QUERY=ON'
|
||||
"-DOT_DNSSD_DISCOVERY_PROXY=ON"
|
||||
'-DOT_DNSSD_SERVER=ON'
|
||||
'-DOT_DUA=ON'
|
||||
'-DOT_MLR=ON'
|
||||
|
||||
@@ -156,6 +156,10 @@ Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning)
|
||||
Get<Srp::AdvertisingProxy>().HandleInfraIfStateChanged();
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE && OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
Get<Dns::ServiceDiscovery::Server>().HandleInfraIfStateChanged();
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF
|
||||
Get<Dns::Multicast::Core>().HandleInfraIfStateChanged();
|
||||
#endif
|
||||
|
||||
@@ -85,6 +85,16 @@
|
||||
#define OPENTHREAD_CONFIG_DNSSD_QUERY_TIMEOUT 6000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
*
|
||||
* Define to 1 to enable DNS-SD Discovery Proxy support.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
#define OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||
*
|
||||
|
||||
+233
-7
@@ -255,6 +255,237 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StartBrowser(const Browser &aBrowser)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StartBrowser(aBrowser));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStartBrowser(&GetInstance(), &aBrowser);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StopBrowser(const Browser &aBrowser)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StopBrowser(aBrowser));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStopBrowser(&GetInstance(), &aBrowser);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StartSrvResolver(const SrvResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StartSrvResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStartSrvResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StopSrvResolver(const SrvResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StopSrvResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStopSrvResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StartTxtResolver(const TxtResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StartTxtResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStartTxtResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StopTxtResolver(const TxtResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StopTxtResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStopTxtResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StartIp6AddressResolver(const AddressResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StartIp6AddressResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStartIp6AddressResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StopIp6AddressResolver(const AddressResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StopIp6AddressResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStopIp6AddressResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StartIp4AddressResolver(const AddressResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StartIp4AddressResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStartIp4AddressResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::StopIp4AddressResolver(const AddressResolver &aResolver)
|
||||
{
|
||||
VerifyOrExit(IsReady());
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
|
||||
if (mUseNativeMdns)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
{
|
||||
IgnoreError(Get<Dns::Multicast::Core>().StopIp4AddressResolver(aResolver));
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
otPlatDnssdStopIp4AddressResolver(&GetInstance(), &aResolver);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Dnssd::HandleStateChange(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE
|
||||
Get<Srp::AdvertisingProxy>().HandleDnssdPlatformStateChange();
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE && OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
Get<Dns::ServiceDiscovery::Server>().HandleDnssdPlatformStateChange();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
void Dnssd::HandleMdnsCoreStateChange(void)
|
||||
{
|
||||
@@ -267,17 +498,12 @@ void Dnssd::HandleMdnsCoreStateChange(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void Dnssd::HandleStateChange(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE
|
||||
Get<Srp::AdvertisingProxy>().HandleDnssdPlatformStateChange();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
extern "C" void otPlatDnssdStateHandleStateChange(otInstance *aInstance)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Dnssd>().HandleStateChange();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -93,6 +93,15 @@ public:
|
||||
|
||||
typedef otPlatDnssdRequestId RequestId; ///< A request ID.
|
||||
typedef otPlatDnssdRegisterCallback RegisterCallback; ///< The registration request callback
|
||||
typedef otPlatDnssdBrowseCallback BrowseCallback; ///< Browser callback.
|
||||
typedef otPlatDnssdSrvCallback SrvCallback; ///< SRV callback.
|
||||
typedef otPlatDnssdTxtCallback TxtCallback; ///< TXT callback.
|
||||
typedef otPlatDnssdAddressCallback AddressCallback; ///< Address callback
|
||||
typedef otPlatDnssdBrowseResult BrowseResult; ///< Browser result.
|
||||
typedef otPlatDnssdSrvResult SrvResult; ///< SRV result.
|
||||
typedef otPlatDnssdTxtResult TxtResult; ///< TXT result.
|
||||
typedef otPlatDnssdAddressResult AddressResult; ///< Address result.
|
||||
typedef otPlatDnssdAddressAndTtl AddressAndTtl; ///< Address and TTL.
|
||||
|
||||
class Host : public otPlatDnssdHost, public Clearable<Host> ///< Host information.
|
||||
{
|
||||
@@ -106,6 +115,22 @@ public:
|
||||
{
|
||||
};
|
||||
|
||||
class Browser : public otPlatDnssdBrowser, public Clearable<Browser> ///< Browser.
|
||||
{
|
||||
};
|
||||
|
||||
class SrvResolver : public otPlatDnssdSrvResolver, public Clearable<SrvResolver> ///< SRV resolver.
|
||||
{
|
||||
};
|
||||
|
||||
class TxtResolver : public otPlatDnssdTxtResolver, public Clearable<TxtResolver> ///< TXT resolver.
|
||||
{
|
||||
};
|
||||
|
||||
class AddressResolver : public otPlatDnssdAddressResolver, public Clearable<AddressResolver> ///< Address resolver.
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a range of `RequestId` values.
|
||||
*
|
||||
@@ -274,6 +299,116 @@ public:
|
||||
*/
|
||||
void UnregisterKey(const Key &aKey, RequestId aRequestId, RegisterCallback aCallback);
|
||||
|
||||
/**
|
||||
* Starts a service browser.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStartBrowser()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aBrowser The browser to be started.
|
||||
*
|
||||
*/
|
||||
void StartBrowser(const Browser &aBrowser);
|
||||
|
||||
/**
|
||||
* Stops a service browser.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStopBrowser()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aBrowser The browser to stop.
|
||||
*
|
||||
*/
|
||||
void StopBrowser(const Browser &aBrowser);
|
||||
|
||||
/**
|
||||
* Starts an SRV record resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStartSrvResolver()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void StartSrvResolver(const SrvResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Stops an SRV record resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStopSrvResolver()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void StopSrvResolver(const SrvResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Starts a TXT record resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStartTxtResolver()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void StartTxtResolver(const TxtResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Stops a TXT record resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStopTxtResolver()` for a more detailed description of the behavior
|
||||
* of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void StopTxtResolver(const TxtResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv6 address resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStartIp6AddressResolver()` for a more detailed description of the
|
||||
* behavior of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void StartIp6AddressResolver(const AddressResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv6 address resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStopIp6AddressResolver()` for a more detailed description of the
|
||||
* behavior of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void StopIp6AddressResolver(const AddressResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv4 address resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStartIp4AddressResolver()` for a more detailed description of the
|
||||
* behavior of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*
|
||||
*/
|
||||
void StartIp4AddressResolver(const AddressResolver &aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv4 address resolver.
|
||||
*
|
||||
* Refer to the documentation for `otPlatDnssdStopIp4AddressResolver()` for a more detailed description of the
|
||||
* behavior of this method.
|
||||
*
|
||||
* @param[in] aResolver The resolver to stop.
|
||||
*
|
||||
*/
|
||||
void StopIp4AddressResolver(const AddressResolver &aResolver);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
/**
|
||||
* Handles native mDNS state change.
|
||||
|
||||
+848
-17
@@ -64,6 +64,9 @@ const char *Server::kBlockedDomains[] = {"ipv4only.arpa."};
|
||||
Server::Server(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mSocket(aInstance)
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
, mDiscoveryProxy(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||
, mEnableUpstreamQuery(false)
|
||||
#endif
|
||||
@@ -88,6 +91,10 @@ Error Server::Start(void)
|
||||
|
||||
LogInfo("Started");
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
mDiscoveryProxy.UpdateState();
|
||||
#endif
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
@@ -104,6 +111,10 @@ void Server::Stop(void)
|
||||
Finalize(query, Header::kResponseServerFailure);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
mDiscoveryProxy.Stop();
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||
for (UpstreamQueryTransaction &txn : mUpstreamQueryTransactions)
|
||||
{
|
||||
@@ -586,22 +597,30 @@ Error Server::Response::AppendHostAddresses(const Ip6::Address *aAddrs, uint16_t
|
||||
|
||||
for (uint16_t index = 0; index < aAddrsLength; index++)
|
||||
{
|
||||
AaaaRecord aaaaRecord;
|
||||
|
||||
aaaaRecord.Init();
|
||||
aaaaRecord.SetTtl(aTtl);
|
||||
aaaaRecord.SetAddress(aAddrs[index]);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
|
||||
SuccessOrExit(error = mMessage->Append(aaaaRecord));
|
||||
|
||||
IncResourceRecordCount();
|
||||
SuccessOrExit(error = AppendAaaaRecord(aAddrs[index], aTtl));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Server::Response::AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl)
|
||||
{
|
||||
Error error;
|
||||
AaaaRecord aaaaRecord;
|
||||
|
||||
aaaaRecord.Init();
|
||||
aaaaRecord.SetTtl(aTtl);
|
||||
aaaaRecord.SetAddress(aAddress);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
|
||||
SuccessOrExit(error = mMessage->Append(aaaaRecord));
|
||||
IncResourceRecordCount();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
Error Server::Response::AppendTxtRecord(const Srp::Server::Service &aService)
|
||||
{
|
||||
@@ -915,9 +934,12 @@ void Server::ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessag
|
||||
{
|
||||
ProxyQuery *query;
|
||||
ProxyQueryInfo info;
|
||||
Name::Buffer name;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
VerifyOrExit(mQuerySubscribe.IsSet() || mDiscoveryProxy.IsRunning());
|
||||
#else
|
||||
VerifyOrExit(mQuerySubscribe.IsSet());
|
||||
#endif
|
||||
|
||||
// We try to convert `aResponse.mMessage` to a `ProxyQuery` by
|
||||
// appending `ProxyQueryInfo` to it.
|
||||
@@ -927,6 +949,10 @@ void Server::ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessag
|
||||
info.mExpireTime = TimerMilli::GetNow() + kQueryTimeout;
|
||||
info.mOffsets = aResponse.mOffsets;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
info.mAction = kNoAction;
|
||||
#endif
|
||||
|
||||
if (aResponse.mMessage->Append(info) != kErrorNone)
|
||||
{
|
||||
aResponse.SetResponseCode(Header::kResponseServerFailure);
|
||||
@@ -943,8 +969,21 @@ void Server::ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessag
|
||||
|
||||
mTimer.FireAtIfEarlier(info.mExpireTime);
|
||||
|
||||
ReadQueryName(*query, name);
|
||||
mQuerySubscribe.Invoke(name);
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
if (mQuerySubscribe.IsSet())
|
||||
#endif
|
||||
{
|
||||
Name::Buffer name;
|
||||
|
||||
ReadQueryName(*query, name);
|
||||
mQuerySubscribe.Invoke(name);
|
||||
}
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
else
|
||||
{
|
||||
mDiscoveryProxy.Resolve(*query, info);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -964,6 +1003,91 @@ bool Server::QueryNameMatches(const Message &aQuery, const char *aName)
|
||||
return (Name::CompareName(aQuery, offset, aName) == kErrorNone);
|
||||
}
|
||||
|
||||
void Server::ReadQueryInstanceName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName)
|
||||
{
|
||||
uint16_t offset = aInfo.mOffsets.mInstanceName;
|
||||
|
||||
IgnoreError(Name::ReadName(aQuery, offset, aName, sizeof(aName)));
|
||||
}
|
||||
|
||||
void Server::ReadQueryInstanceName(const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
Name::LabelBuffer &aInstanceLabel,
|
||||
Name::Buffer &aServiceType)
|
||||
{
|
||||
// Reads the service instance label and service type with domain
|
||||
// name stripped.
|
||||
|
||||
uint16_t offset = aInfo.mOffsets.mInstanceName;
|
||||
uint8_t labelLength = sizeof(aInstanceLabel);
|
||||
|
||||
IgnoreError(Dns::Name::ReadLabel(aQuery, offset, aInstanceLabel, labelLength));
|
||||
IgnoreError(Dns::Name::ReadName(aQuery, offset, aServiceType));
|
||||
IgnoreError(StripDomainName(aServiceType));
|
||||
}
|
||||
|
||||
bool Server::QueryInstanceNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName)
|
||||
{
|
||||
uint16_t offset = aInfo.mOffsets.mInstanceName;
|
||||
|
||||
return (Name::CompareName(aQuery, offset, aName) == kErrorNone);
|
||||
}
|
||||
|
||||
void Server::ReadQueryHostName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName)
|
||||
{
|
||||
uint16_t offset = aInfo.mOffsets.mHostName;
|
||||
|
||||
IgnoreError(Name::ReadName(aQuery, offset, aName, sizeof(aName)));
|
||||
}
|
||||
|
||||
bool Server::QueryHostNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName)
|
||||
{
|
||||
uint16_t offset = aInfo.mOffsets.mHostName;
|
||||
|
||||
return (Name::CompareName(aQuery, offset, aName) == kErrorNone);
|
||||
}
|
||||
|
||||
Error Server::StripDomainName(Name::Buffer &aName)
|
||||
{
|
||||
// In-place removes the domain name from `aName`.
|
||||
|
||||
return Name::StripName(aName, kDefaultDomainName);
|
||||
}
|
||||
|
||||
Error Server::StripDomainName(const char *aFullName, Name::Buffer &aLabels)
|
||||
{
|
||||
// Remove the domain name from `aFullName` and copies
|
||||
// the result into `aLabels`.
|
||||
|
||||
return Name::ExtractLabels(aFullName, kDefaultDomainName, aLabels, sizeof(aLabels));
|
||||
}
|
||||
|
||||
void Server::ConstructFullName(const char *aLabels, Name::Buffer &aFullName)
|
||||
{
|
||||
// Construct a full name by appending the default domain name
|
||||
// to `aLabels`.
|
||||
|
||||
StringWriter fullName(aFullName, sizeof(aFullName));
|
||||
|
||||
fullName.Append("%s.%s", aLabels, kDefaultDomainName);
|
||||
}
|
||||
|
||||
void Server::ConstructFullInstanceName(const char *aInstanceLabel, const char *aServiceType, Name::Buffer &aFullName)
|
||||
{
|
||||
StringWriter fullName(aFullName, sizeof(aFullName));
|
||||
|
||||
fullName.Append("%s.%s.%s", aInstanceLabel, aServiceType, kDefaultDomainName);
|
||||
}
|
||||
|
||||
void Server::ConstructFullServiceSubTypeName(const char *aServiceType,
|
||||
const char *aSubTypeLabel,
|
||||
Name::Buffer &aFullName)
|
||||
{
|
||||
StringWriter fullName(aFullName, sizeof(aFullName));
|
||||
|
||||
fullName.Append("%s._sub.%s.%s", aSubTypeLabel, aServiceType, kDefaultDomainName);
|
||||
}
|
||||
|
||||
void Server::ProxyQueryInfo::ReadFrom(const ProxyQuery &aQuery)
|
||||
{
|
||||
SuccessOrAssert(aQuery.Read(aQuery.GetLength() - sizeof(ProxyQueryInfo), *this));
|
||||
@@ -987,15 +1111,22 @@ Error Server::Response::ExtractServiceInstanceLabel(const char *aInstanceName, N
|
||||
return Name::ExtractLabels(aInstanceName, serviceName, aLabel);
|
||||
}
|
||||
|
||||
void Server::RemoveQueryAndPrepareResponse(ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Response &aResponse)
|
||||
void Server::RemoveQueryAndPrepareResponse(ProxyQuery &aQuery, ProxyQueryInfo &aInfo, Response &aResponse)
|
||||
{
|
||||
Name::Buffer name;
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
mDiscoveryProxy.CancelAction(aQuery, aInfo);
|
||||
#endif
|
||||
|
||||
mProxyQueries.Dequeue(aQuery);
|
||||
aInfo.RemoveFrom(aQuery);
|
||||
|
||||
ReadQueryName(aQuery, name);
|
||||
mQueryUnsubscribe.InvokeIfSet(name);
|
||||
if (mQueryUnsubscribe.IsSet())
|
||||
{
|
||||
Name::Buffer name;
|
||||
|
||||
ReadQueryName(aQuery, name);
|
||||
mQueryUnsubscribe.Invoke(name);
|
||||
}
|
||||
|
||||
aResponse.InitFrom(aQuery, aInfo);
|
||||
}
|
||||
@@ -1282,6 +1413,706 @@ void Server::ResetUpstreamQueryTransaction(UpstreamQueryTransaction &aTxn, Error
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
|
||||
Server::DiscoveryProxy::DiscoveryProxy(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mIsRunning(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::UpdateState(void)
|
||||
{
|
||||
if (Get<Server>().IsRunning() && Get<Dnssd>().IsReady() && Get<BorderRouter::InfraIf>().IsRunning())
|
||||
{
|
||||
Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::Start(void)
|
||||
{
|
||||
VerifyOrExit(!mIsRunning);
|
||||
mIsRunning = true;
|
||||
LogInfo("Started discovery proxy");
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::Stop(void)
|
||||
{
|
||||
VerifyOrExit(mIsRunning);
|
||||
|
||||
for (ProxyQuery &query : Get<Server>().mProxyQueries)
|
||||
{
|
||||
Get<Server>().Finalize(query, Header::kResponseSuccess);
|
||||
}
|
||||
|
||||
mIsRunning = false;
|
||||
LogInfo("Stopped discovery proxy");
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::Resolve(ProxyQuery &aQuery, ProxyQueryInfo &aInfo)
|
||||
{
|
||||
ProxyAction action = kNoAction;
|
||||
|
||||
switch (aInfo.mType)
|
||||
{
|
||||
case kPtrQuery:
|
||||
action = kBrowsing;
|
||||
break;
|
||||
|
||||
case kSrvQuery:
|
||||
case kSrvTxtQuery:
|
||||
action = kResolvingSrv;
|
||||
break;
|
||||
|
||||
case kTxtQuery:
|
||||
action = kResolvingTxt;
|
||||
break;
|
||||
|
||||
case kAaaaQuery:
|
||||
action = kResolvingIp6Address;
|
||||
break;
|
||||
}
|
||||
|
||||
Perform(action, aQuery, aInfo);
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::Perform(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo)
|
||||
{
|
||||
bool shouldStart;
|
||||
Name::Buffer name;
|
||||
|
||||
VerifyOrExit(aAction != kNoAction);
|
||||
|
||||
// The order of the steps below is crucial. First, we read the
|
||||
// name associated with the action. Then we check if another
|
||||
// query has an active browser/resolver for the same name. This
|
||||
// helps us determine if a new browser/resolver is needed. Then,
|
||||
// we update the `ProxyQueryInfo` within `aQuery` to reflect the
|
||||
// `aAction` being performed. Finally, if necessary, we start the
|
||||
// proper browser/resolver on DNS-SD/mDNS. Placing this last
|
||||
// ensures correct processing even if a DNS-SD/mDNS callback is
|
||||
// invoked immediately.
|
||||
|
||||
ReadNameFor(aAction, aQuery, aInfo, name);
|
||||
|
||||
shouldStart = !HasActive(aAction, name);
|
||||
|
||||
aInfo.mAction = aAction;
|
||||
aInfo.UpdateIn(aQuery);
|
||||
|
||||
VerifyOrExit(shouldStart);
|
||||
UpdateProxy(kStart, aAction, aQuery, aInfo, name);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::ReadNameFor(ProxyAction aAction,
|
||||
ProxyQuery &aQuery,
|
||||
ProxyQueryInfo &aInfo,
|
||||
Name::Buffer &aName) const
|
||||
{
|
||||
// Read the name corresponding to `aAction` from `aQuery`.
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kNoAction:
|
||||
break;
|
||||
case kBrowsing:
|
||||
ReadQueryName(aQuery, aName);
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
case kResolvingTxt:
|
||||
ReadQueryInstanceName(aQuery, aInfo, aName);
|
||||
break;
|
||||
case kResolvingIp6Address:
|
||||
ReadQueryHostName(aQuery, aInfo, aName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::CancelAction(ProxyQuery &aQuery, ProxyQueryInfo &aInfo)
|
||||
{
|
||||
// Cancel the current action for a given `aQuery`, then
|
||||
// determine if we need to stop any browser/resolver
|
||||
// on infrastructure.
|
||||
|
||||
ProxyAction action = aInfo.mAction;
|
||||
Name::Buffer name;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
VerifyOrExit(action != kNoAction);
|
||||
|
||||
// We first update the `aInfo` on `aQuery` before calling
|
||||
// `HasActive()`. This ensures that the current query is not
|
||||
// taken into account when we try to determine if any query
|
||||
// is waiting for same `aAction` browser/resolver.
|
||||
|
||||
ReadNameFor(action, aQuery, aInfo, name);
|
||||
|
||||
aInfo.mAction = kNoAction;
|
||||
aInfo.UpdateIn(aQuery);
|
||||
|
||||
VerifyOrExit(!HasActive(action, name));
|
||||
UpdateProxy(kStop, action, aQuery, aInfo, name);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::UpdateProxy(Command aCommand,
|
||||
ProxyAction aAction,
|
||||
const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
Name::Buffer &aName)
|
||||
{
|
||||
// Start or stop browser/resolver corresponding to `aAction`.
|
||||
// `aName` may be changed.
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kNoAction:
|
||||
break;
|
||||
case kBrowsing:
|
||||
StartOrStopBrowser(aCommand, aName);
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
StartOrStopSrvResolver(aCommand, aQuery, aInfo);
|
||||
break;
|
||||
case kResolvingTxt:
|
||||
StartOrStopTxtResolver(aCommand, aQuery, aInfo);
|
||||
break;
|
||||
case kResolvingIp6Address:
|
||||
StartOrStopIp6Resolver(aCommand, aName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::StartOrStopBrowser(Command aCommand, Name::Buffer &aServiceName)
|
||||
{
|
||||
// Start or stop a service browser for a given service type
|
||||
// or sub-type.
|
||||
|
||||
static const char kFullSubLabel[] = "._sub.";
|
||||
|
||||
Dnssd::Browser browser;
|
||||
char *ptr;
|
||||
|
||||
browser.Clear();
|
||||
|
||||
IgnoreError(StripDomainName(aServiceName));
|
||||
|
||||
// Check if the service name is a sub-type with name
|
||||
// format: "<sub-label>._sub.<service-labels>.
|
||||
|
||||
ptr = AsNonConst(StringFind(aServiceName, kFullSubLabel, kStringCaseInsensitiveMatch));
|
||||
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
*ptr = kNullChar;
|
||||
ptr += sizeof(kFullSubLabel) - 1;
|
||||
|
||||
browser.mServiceType = ptr;
|
||||
browser.mSubTypeLabel = aServiceName;
|
||||
}
|
||||
else
|
||||
{
|
||||
browser.mServiceType = aServiceName;
|
||||
browser.mSubTypeLabel = nullptr;
|
||||
}
|
||||
|
||||
browser.mInfraIfIndex = Get<BorderRouter::InfraIf>().GetIfIndex();
|
||||
browser.mCallback = HandleBrowseResult;
|
||||
|
||||
switch (aCommand)
|
||||
{
|
||||
case kStart:
|
||||
Get<Dnssd>().StartBrowser(browser);
|
||||
break;
|
||||
|
||||
case kStop:
|
||||
Get<Dnssd>().StopBrowser(browser);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::StartOrStopSrvResolver(Command aCommand,
|
||||
const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo)
|
||||
{
|
||||
// Start or stop an SRV record resolver for a given query.
|
||||
|
||||
Dnssd::SrvResolver resolver;
|
||||
Name::LabelBuffer instanceLabel;
|
||||
Name::Buffer serviceType;
|
||||
|
||||
ReadQueryInstanceName(aQuery, aInfo, instanceLabel, serviceType);
|
||||
|
||||
resolver.Clear();
|
||||
|
||||
resolver.mServiceInstance = instanceLabel;
|
||||
resolver.mServiceType = serviceType;
|
||||
resolver.mInfraIfIndex = Get<BorderRouter::InfraIf>().GetIfIndex();
|
||||
resolver.mCallback = HandleSrvResult;
|
||||
|
||||
switch (aCommand)
|
||||
{
|
||||
case kStart:
|
||||
Get<Dnssd>().StartSrvResolver(resolver);
|
||||
break;
|
||||
|
||||
case kStop:
|
||||
Get<Dnssd>().StopSrvResolver(resolver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::StartOrStopTxtResolver(Command aCommand,
|
||||
const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo)
|
||||
{
|
||||
// Start or stop a TXT record resolver for a given query.
|
||||
|
||||
Dnssd::TxtResolver resolver;
|
||||
Name::LabelBuffer instanceLabel;
|
||||
Name::Buffer serviceType;
|
||||
|
||||
ReadQueryInstanceName(aQuery, aInfo, instanceLabel, serviceType);
|
||||
|
||||
resolver.Clear();
|
||||
|
||||
resolver.mServiceInstance = instanceLabel;
|
||||
resolver.mServiceType = serviceType;
|
||||
resolver.mInfraIfIndex = Get<BorderRouter::InfraIf>().GetIfIndex();
|
||||
resolver.mCallback = HandleTxtResult;
|
||||
|
||||
switch (aCommand)
|
||||
{
|
||||
case kStart:
|
||||
Get<Dnssd>().StartTxtResolver(resolver);
|
||||
break;
|
||||
|
||||
case kStop:
|
||||
Get<Dnssd>().StopTxtResolver(resolver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::StartOrStopIp6Resolver(Command aCommand, Name::Buffer &aHostName)
|
||||
{
|
||||
// Start or stop an IPv6 address resolver for a given host name.
|
||||
|
||||
Dnssd::AddressResolver resolver;
|
||||
|
||||
IgnoreError(StripDomainName(aHostName));
|
||||
|
||||
resolver.mHostName = aHostName;
|
||||
resolver.mInfraIfIndex = Get<BorderRouter::InfraIf>().GetIfIndex();
|
||||
resolver.mCallback = HandleIp6AddressResult;
|
||||
|
||||
switch (aCommand)
|
||||
{
|
||||
case kStart:
|
||||
Get<Dnssd>().StartIp6AddressResolver(resolver);
|
||||
break;
|
||||
|
||||
case kStop:
|
||||
Get<Dnssd>().StopIp6AddressResolver(resolver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
ProxyAction aAction,
|
||||
const Name::Buffer &aName) const
|
||||
{
|
||||
// Check whether `aQuery` is performing `aAction` and
|
||||
// its name matches `aName`.
|
||||
|
||||
bool matches = false;
|
||||
|
||||
VerifyOrExit(aInfo.mAction == aAction);
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kBrowsing:
|
||||
VerifyOrExit(QueryNameMatches(aQuery, aName));
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
case kResolvingTxt:
|
||||
VerifyOrExit(QueryInstanceNameMatches(aQuery, aInfo, aName));
|
||||
break;
|
||||
case kResolvingIp6Address:
|
||||
VerifyOrExit(QueryHostNameMatches(aQuery, aInfo, aName));
|
||||
break;
|
||||
case kNoAction:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
matches = true;
|
||||
|
||||
exit:
|
||||
return matches;
|
||||
}
|
||||
|
||||
bool Server::DiscoveryProxy::HasActive(ProxyAction aAction, const Name::Buffer &aName) const
|
||||
{
|
||||
// Determine whether or not we have an active browser/resolver
|
||||
// corresponding to `aAction` for `aName`.
|
||||
|
||||
bool has = false;
|
||||
|
||||
for (const ProxyQuery &query : Get<Server>().mProxyQueries)
|
||||
{
|
||||
ProxyQueryInfo info;
|
||||
|
||||
info.ReadFrom(query);
|
||||
|
||||
if (QueryMatches(query, info, aAction, aName))
|
||||
{
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return has;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleBrowseResult(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Server>().mDiscoveryProxy.HandleBrowseResult(*aResult);
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleBrowseResult(const Dnssd::BrowseResult &aResult)
|
||||
{
|
||||
Name::Buffer serviceName;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
VerifyOrExit(aResult.mTtl != 0);
|
||||
VerifyOrExit(aResult.mInfraIfIndex == Get<BorderRouter::InfraIf>().GetIfIndex());
|
||||
|
||||
if (aResult.mSubTypeLabel != nullptr)
|
||||
{
|
||||
ConstructFullServiceSubTypeName(aResult.mServiceType, aResult.mSubTypeLabel, serviceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConstructFullName(aResult.mServiceType, serviceName);
|
||||
}
|
||||
|
||||
HandleResult(kBrowsing, serviceName, &Response::AppendPtrRecord, ProxyResult(aResult));
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleSrvResult(otInstance *aInstance, const otPlatDnssdSrvResult *aResult)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Server>().mDiscoveryProxy.HandleSrvResult(*aResult);
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleSrvResult(const Dnssd::SrvResult &aResult)
|
||||
{
|
||||
Name::Buffer instanceName;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
VerifyOrExit(aResult.mTtl != 0);
|
||||
VerifyOrExit(aResult.mInfraIfIndex == Get<BorderRouter::InfraIf>().GetIfIndex());
|
||||
|
||||
ConstructFullInstanceName(aResult.mServiceInstance, aResult.mServiceType, instanceName);
|
||||
HandleResult(kResolvingSrv, instanceName, &Response::AppendSrvRecord, ProxyResult(aResult));
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleTxtResult(otInstance *aInstance, const otPlatDnssdTxtResult *aResult)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Server>().mDiscoveryProxy.HandleTxtResult(*aResult);
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleTxtResult(const Dnssd::TxtResult &aResult)
|
||||
{
|
||||
Name::Buffer instanceName;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
VerifyOrExit(aResult.mTtl != 0);
|
||||
VerifyOrExit(aResult.mInfraIfIndex == Get<BorderRouter::InfraIf>().GetIfIndex());
|
||||
|
||||
ConstructFullInstanceName(aResult.mServiceInstance, aResult.mServiceType, instanceName);
|
||||
HandleResult(kResolvingTxt, instanceName, &Response::AppendTxtRecord, ProxyResult(aResult));
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleIp6AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Server>().mDiscoveryProxy.HandleIp6AddressResult(*aResult);
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleIp6AddressResult(const Dnssd::AddressResult &aResult)
|
||||
{
|
||||
bool hasValidAddress = false;
|
||||
Name::Buffer fullHostName;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
VerifyOrExit(aResult.mInfraIfIndex == Get<BorderRouter::InfraIf>().GetIfIndex());
|
||||
|
||||
for (uint16_t index = 0; index < aResult.mAddressesLength; index++)
|
||||
{
|
||||
const Dnssd::AddressAndTtl &entry = aResult.mAddresses[index];
|
||||
const Ip6::Address &address = AsCoreType(&entry.mAddress);
|
||||
|
||||
if (entry.mTtl == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsProxyAddressValid(address))
|
||||
{
|
||||
hasValidAddress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(hasValidAddress);
|
||||
|
||||
ConstructFullName(aResult.mHostName, fullHostName);
|
||||
HandleResult(kResolvingIp6Address, fullHostName, &Response::AppendHostAddresses, ProxyResult(aResult));
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::DiscoveryProxy::HandleResult(ProxyAction aAction,
|
||||
const Name::Buffer &aName,
|
||||
ResponseAppender aAppender,
|
||||
const ProxyResult &aResult)
|
||||
{
|
||||
// Common method that handles result from DNS-SD/mDNS. It
|
||||
// iterates over all `ProxyQuery` entries and checks if any entry
|
||||
// is waiting for the result of `aAction` for `aName`. Matching
|
||||
// queries are updated using the `aAppender` method pointer,
|
||||
// which appends the corresponding record(s) to the response. We
|
||||
// then determine the next action to be performed for the
|
||||
// `ProxyQuery` or if it can be finalized.
|
||||
|
||||
ProxyQueryList nextActionQueries;
|
||||
ProxyQueryInfo info;
|
||||
ProxyAction nextAction;
|
||||
|
||||
for (ProxyQuery &query : Get<Server>().mProxyQueries)
|
||||
{
|
||||
Response response(GetInstance());
|
||||
bool shouldFinalize;
|
||||
|
||||
info.ReadFrom(query);
|
||||
|
||||
if (!QueryMatches(query, info, aAction, aName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CancelAction(query, info);
|
||||
|
||||
nextAction = kNoAction;
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kBrowsing:
|
||||
nextAction = kResolvingSrv;
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
nextAction = (info.mType == kSrvQuery) ? kResolvingIp6Address : kResolvingTxt;
|
||||
break;
|
||||
case kResolvingTxt:
|
||||
nextAction = (info.mType == kTxtQuery) ? kNoAction : kResolvingIp6Address;
|
||||
break;
|
||||
case kNoAction:
|
||||
case kResolvingIp6Address:
|
||||
break;
|
||||
}
|
||||
|
||||
shouldFinalize = (nextAction == kNoAction);
|
||||
|
||||
if ((Get<Server>().mTestMode & kTestModeEmptyAdditionalSection) &&
|
||||
IsActionForAdditionalSection(nextAction, info.mType))
|
||||
{
|
||||
shouldFinalize = true;
|
||||
}
|
||||
|
||||
Get<Server>().mProxyQueries.Dequeue(query);
|
||||
info.RemoveFrom(query);
|
||||
response.InitFrom(query, info);
|
||||
|
||||
if ((response.*aAppender)(aResult) != kErrorNone)
|
||||
{
|
||||
response.SetResponseCode(Header::kResponseServerFailure);
|
||||
shouldFinalize = true;
|
||||
}
|
||||
|
||||
if (shouldFinalize)
|
||||
{
|
||||
response.Send(info.mMessageInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The `query` is not yet finished and we need to perform
|
||||
// the `nextAction` for it.
|
||||
|
||||
// Reinitialize `response` as a `ProxyQuey` by updating
|
||||
// and appending `info` to it after the newly appended
|
||||
// records from `aResult` and saving the `mHeader`.
|
||||
|
||||
info.mOffsets = response.mOffsets;
|
||||
info.mAction = nextAction;
|
||||
response.mMessage->Write(0, response.mHeader);
|
||||
|
||||
if (response.mMessage->Append(info) != kErrorNone)
|
||||
{
|
||||
response.SetResponseCode(Header::kResponseServerFailure);
|
||||
response.Send(info.mMessageInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Take back ownership of `response.mMessage` as we still
|
||||
// treat it as a `ProxyQuery`.
|
||||
|
||||
response.mMessage.Release();
|
||||
|
||||
// We place the `query` in a separate list and add it back to
|
||||
// the main `mProxyQueries` list after we are done with the
|
||||
// current iteration. This ensures that other entries in the
|
||||
// `mProxyQueries` list are not updated or removed due to the
|
||||
// DNS-SD platform callback being invoked immediately when we
|
||||
// potentially start a browser or resolver to perform the
|
||||
// `nextAction` for `query`.
|
||||
|
||||
nextActionQueries.Enqueue(query);
|
||||
}
|
||||
|
||||
for (ProxyQuery &query : nextActionQueries)
|
||||
{
|
||||
nextActionQueries.Dequeue(query);
|
||||
|
||||
info.ReadFrom(query);
|
||||
|
||||
nextAction = info.mAction;
|
||||
|
||||
info.mAction = kNoAction;
|
||||
info.UpdateIn(query);
|
||||
|
||||
Get<Server>().mProxyQueries.Enqueue(query);
|
||||
Perform(nextAction, query, info);
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::DiscoveryProxy::IsActionForAdditionalSection(ProxyAction aAction, QueryType aQueryType)
|
||||
{
|
||||
bool isForAddnlSection = false;
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kResolvingSrv:
|
||||
VerifyOrExit((aQueryType == kSrvQuery) || (aQueryType == kSrvTxtQuery));
|
||||
break;
|
||||
case kResolvingTxt:
|
||||
VerifyOrExit((aQueryType == kTxtQuery) || (aQueryType == kSrvTxtQuery));
|
||||
break;
|
||||
|
||||
case kResolvingIp6Address:
|
||||
VerifyOrExit(aQueryType == kAaaaQuery);
|
||||
break;
|
||||
|
||||
case kNoAction:
|
||||
case kBrowsing:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
isForAddnlSection = true;
|
||||
|
||||
exit:
|
||||
return isForAddnlSection;
|
||||
}
|
||||
|
||||
Error Server::Response::AppendPtrRecord(const ProxyResult &aResult)
|
||||
{
|
||||
const Dnssd::BrowseResult *browseResult = aResult.mBrowseResult;
|
||||
|
||||
mSection = kAnswerSection;
|
||||
|
||||
return AppendPtrRecord(browseResult->mServiceInstance, browseResult->mTtl);
|
||||
}
|
||||
|
||||
Error Server::Response::AppendSrvRecord(const ProxyResult &aResult)
|
||||
{
|
||||
const Dnssd::SrvResult *srvResult = aResult.mSrvResult;
|
||||
Name::Buffer fullHostName;
|
||||
|
||||
mSection = ((mType == kSrvQuery) || (mType == kSrvTxtQuery)) ? kAnswerSection : kAdditionalDataSection;
|
||||
|
||||
ConstructFullName(srvResult->mHostName, fullHostName);
|
||||
|
||||
return AppendSrvRecord(fullHostName, srvResult->mTtl, srvResult->mPriority, srvResult->mWeight, srvResult->mPort);
|
||||
}
|
||||
|
||||
Error Server::Response::AppendTxtRecord(const ProxyResult &aResult)
|
||||
{
|
||||
const Dnssd::TxtResult *txtResult = aResult.mTxtResult;
|
||||
|
||||
mSection = ((mType == kTxtQuery) || (mType == kSrvTxtQuery)) ? kAnswerSection : kAdditionalDataSection;
|
||||
|
||||
return AppendTxtRecord(txtResult->mTxtData, txtResult->mTxtDataLength, txtResult->mTtl);
|
||||
}
|
||||
|
||||
Error Server::Response::AppendHostAddresses(const ProxyResult &aResult)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const Dnssd::AddressResult *addrResult = aResult.mAddressResult;
|
||||
|
||||
mSection = (mType == kAaaaQuery) ? kAnswerSection : kAdditionalDataSection;
|
||||
|
||||
for (uint16_t index = 0; index < addrResult->mAddressesLength; index++)
|
||||
{
|
||||
const Dnssd::AddressAndTtl &entry = addrResult->mAddresses[index];
|
||||
const Ip6::Address &address = AsCoreType(&entry.mAddress);
|
||||
|
||||
if (entry.mTtl == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsProxyAddressValid(address))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = AppendAaaaRecord(address, entry.mTtl));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Server::IsProxyAddressValid(const Ip6::Address &aAddress)
|
||||
{
|
||||
return !aAddress.IsLinkLocal() && !aAddress.IsMulticast() && !aAddress.IsUnspecified() && !aAddress.IsLoopback();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
|
||||
} // namespace ServiceDiscovery
|
||||
} // namespace Dns
|
||||
} // namespace ot
|
||||
|
||||
@@ -33,8 +33,20 @@
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
|
||||
#if !OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE && !OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
|
||||
#error "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE requires either PLATFORM_DNSSD_ENABLE or MULTICAST_DNS_ENABLE"
|
||||
#endif
|
||||
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
#error "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE requires OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
|
||||
#include <openthread/dnssd_server.h>
|
||||
|
||||
#include "border_router/infra_if.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/callback.hpp"
|
||||
#include "common/message.hpp"
|
||||
@@ -42,6 +54,7 @@
|
||||
#include "common/owned_ptr.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/dns_types.hpp"
|
||||
#include "net/dnssd.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "net/netif.hpp"
|
||||
#include "net/srp_server.hpp"
|
||||
@@ -71,6 +84,10 @@ namespace ServiceDiscovery {
|
||||
class Server : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend class Srp::Server;
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
friend class ot::Dnssd;
|
||||
friend class ot::BorderRouter::InfraIf;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -316,6 +333,17 @@ private:
|
||||
kAdditionalDataSection,
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
enum ProxyAction : uint8_t
|
||||
{
|
||||
kNoAction,
|
||||
kBrowsing,
|
||||
kResolvingSrv,
|
||||
kResolvingTxt,
|
||||
kResolvingIp6Address,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Request
|
||||
{
|
||||
ResponseCode ParseQuestions(uint8_t aTestMode);
|
||||
@@ -336,6 +364,21 @@ private:
|
||||
uint16_t mHostName;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
union ProxyResult
|
||||
{
|
||||
explicit ProxyResult(const Dnssd::BrowseResult &aBrowseResult) { mBrowseResult = &aBrowseResult; }
|
||||
explicit ProxyResult(const Dnssd::SrvResult &aSrvResult) { mSrvResult = &aSrvResult; }
|
||||
explicit ProxyResult(const Dnssd::TxtResult &aTxtResult) { mTxtResult = &aTxtResult; }
|
||||
explicit ProxyResult(const Dnssd::AddressResult &aAddressResult) { mAddressResult = &aAddressResult; }
|
||||
|
||||
const Dnssd::BrowseResult *mBrowseResult;
|
||||
const Dnssd::SrvResult *mSrvResult;
|
||||
const Dnssd::TxtResult *mTxtResult;
|
||||
const Dnssd::AddressResult *mAddressResult;
|
||||
};
|
||||
#endif
|
||||
|
||||
class Response : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
@@ -360,6 +403,7 @@ private:
|
||||
Error AppendHostAddresses(const HostInfo &aHostInfo);
|
||||
Error AppendHostAddresses(const ServiceInstanceInfo &aInstanceInfo);
|
||||
Error AppendHostAddresses(const Ip6::Address *aAddrs, uint16_t aAddrsLength, uint32_t aTtl);
|
||||
Error AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl);
|
||||
void UpdateRecordLength(ResourceRecord &aRecord, uint16_t aOffset);
|
||||
void IncResourceRecordCount(void);
|
||||
void Send(const Ip6::MessageInfo &aMessageInfo);
|
||||
@@ -373,6 +417,14 @@ private:
|
||||
Error AppendTxtRecord(const Srp::Server::Service &aService);
|
||||
Error AppendHostAddresses(const Srp::Server::Host &aHost);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
Error AppendPtrRecord(const ProxyResult &aResult);
|
||||
Error AppendSrvRecord(const ProxyResult &aResult);
|
||||
Error AppendTxtRecord(const ProxyResult &aResult);
|
||||
|
||||
Error AppendHostAddresses(const ProxyResult &aResult);
|
||||
#endif
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
void Log(void) const;
|
||||
static const char *QueryTypeToString(QueryType aType);
|
||||
@@ -395,18 +447,106 @@ private:
|
||||
Ip6::MessageInfo mMessageInfo;
|
||||
TimeMilli mExpireTime;
|
||||
NameOffsets mOffsets;
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
ProxyAction mAction;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
class DiscoveryProxy : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend ot::Dnssd;
|
||||
|
||||
public:
|
||||
explicit DiscoveryProxy(Instance &aInstance);
|
||||
|
||||
bool IsRunning(void) const { return mIsRunning; }
|
||||
void UpdateState(void);
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
void Resolve(ProxyQuery &aQuery, ProxyQueryInfo &aInfo);
|
||||
void CancelAction(ProxyQuery &aQuery, ProxyQueryInfo &aInfo);
|
||||
|
||||
private:
|
||||
enum Command : uint8_t
|
||||
{
|
||||
kStart,
|
||||
kStop,
|
||||
};
|
||||
|
||||
typedef Error (Response::*ResponseAppender)(const ProxyResult &aResult);
|
||||
|
||||
void Perform(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo);
|
||||
void ReadNameFor(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo, Name::Buffer &aName) const;
|
||||
bool HasActive(ProxyAction aAction, const Name::Buffer &aName) const;
|
||||
bool QueryMatches(const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
ProxyAction aAction,
|
||||
const Name::Buffer &aName) const;
|
||||
void UpdateProxy(Command aCommand,
|
||||
ProxyAction aAction,
|
||||
const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
Name::Buffer &aName);
|
||||
void StartOrStopBrowser(Command aCommand, Name::Buffer &aServiceName);
|
||||
void StartOrStopSrvResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
|
||||
void StartOrStopTxtResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
|
||||
void StartOrStopIp6Resolver(Command aCommand, Name::Buffer &aHostName);
|
||||
|
||||
static void HandleBrowseResult(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult);
|
||||
static void HandleSrvResult(otInstance *aInstance, const otPlatDnssdSrvResult *aResult);
|
||||
static void HandleTxtResult(otInstance *aInstance, const otPlatDnssdTxtResult *aResult);
|
||||
static void HandleIp6AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult);
|
||||
|
||||
void HandleBrowseResult(const Dnssd::BrowseResult &aResult);
|
||||
void HandleSrvResult(const Dnssd::SrvResult &aResult);
|
||||
void HandleTxtResult(const Dnssd::TxtResult &aResult);
|
||||
void HandleIp6AddressResult(const Dnssd::AddressResult &aResult);
|
||||
void HandleResult(ProxyAction aAction,
|
||||
const Name::Buffer &aName,
|
||||
ResponseAppender aAppender,
|
||||
const ProxyResult &aResult);
|
||||
|
||||
static bool IsActionForAdditionalSection(ProxyAction aAction, QueryType aQueryType);
|
||||
|
||||
bool mIsRunning;
|
||||
};
|
||||
#endif
|
||||
|
||||
bool IsRunning(void) const { return mSocket.IsBound(); }
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void ProcessQuery(Request &aRequest);
|
||||
|
||||
void ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessageInfo);
|
||||
void RemoveQueryAndPrepareResponse(ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Response &aResponse);
|
||||
void Finalize(ProxyQuery &aQuery, ResponseCode aResponseCode);
|
||||
static void ReadQueryName(const Message &aQuery, Name::Buffer &aName);
|
||||
static bool QueryNameMatches(const Message &aQuery, const char *aName);
|
||||
void ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessageInfo);
|
||||
void RemoveQueryAndPrepareResponse(ProxyQuery &aQuery, ProxyQueryInfo &aInfo, Response &aResponse);
|
||||
void Finalize(ProxyQuery &aQuery, ResponseCode aResponseCode);
|
||||
|
||||
static void ReadQueryName(const Message &aQuery, Name::Buffer &aName);
|
||||
static bool QueryNameMatches(const Message &aQuery, const char *aName);
|
||||
static void ReadQueryInstanceName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName);
|
||||
static void ReadQueryInstanceName(const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
Name::LabelBuffer &aInstanceLabel,
|
||||
Name::Buffer &aServiceType);
|
||||
static bool QueryInstanceNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName);
|
||||
static void ReadQueryHostName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName);
|
||||
static bool QueryHostNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName);
|
||||
static Error StripDomainName(const char *aFullName, Name::Buffer &aLabels);
|
||||
static Error StripDomainName(Name::Buffer &aName);
|
||||
static void ConstructFullName(const char *aLabels, Name::Buffer &aFullName);
|
||||
static void ConstructFullInstanceName(const char *aInstanceLabel,
|
||||
const char *aServiceType,
|
||||
Name::Buffer &aFullName);
|
||||
static void ConstructFullServiceSubTypeName(const char *aServiceType,
|
||||
const char *aSubTypeLabel,
|
||||
Name::Buffer &aFullName);
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
void HandleInfraIfStateChanged(void) { mDiscoveryProxy.UpdateState(); }
|
||||
void HandleDnssdPlatformStateChange(void) { mDiscoveryProxy.UpdateState(); }
|
||||
static bool IsProxyAddressValid(const Ip6::Address &aAddress);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||
static bool ShouldForwardToUpstream(const Request &aRequest);
|
||||
@@ -434,6 +574,10 @@ private:
|
||||
Callback<SubscribeCallback> mQuerySubscribe;
|
||||
Callback<UnsubscribeCallback> mQueryUnsubscribe;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
|
||||
DiscoveryProxy mDiscoveryProxy;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
|
||||
bool mEnableUpstreamQuery;
|
||||
UpstreamQueryTransaction mUpstreamQueryTransactions[kMaxConcurrentUpstreamQueries];
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#define OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 1
|
||||
|
||||
#define OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE 1
|
||||
|
||||
@@ -176,6 +176,7 @@ ot_unit_test(data)
|
||||
ot_unit_test(dataset)
|
||||
ot_unit_test(dns)
|
||||
ot_unit_test(dns_client)
|
||||
ot_unit_test(dnssd_discovery_proxy)
|
||||
ot_unit_test(dso)
|
||||
ot_unit_test(ecdsa)
|
||||
ot_unit_test(flash)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -877,6 +877,66 @@ OT_TOOL_WEAK void otPlatDnssdUnregisterKey(otInstance *aInstance
|
||||
OT_UNUSED_VARIABLE(aCallback);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStartBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStopBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStartSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStopSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStartTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStopTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStartIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStopIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStartIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDnssdStopIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
|
||||
Reference in New Issue
Block a user