[dnssd] add api for accessing queries in the dnssd server (#6611)

This commit allows the platform implementations to access the name and
the type of the queries, thus reducing the memory overhead of extra
bookkeeping.
This commit is contained in:
Jiacheng Guo
2021-05-20 19:37:10 -07:00
committed by GitHub
parent ac75e9ea3b
commit 0833468767
5 changed files with 155 additions and 37 deletions
+41
View File
@@ -37,6 +37,7 @@
#include <stdint.h>
#include <openthread/dns.h>
#include <openthread/error.h>
#include <openthread/ip6.h>
@@ -99,6 +100,12 @@ typedef void (*otDnssdQuerySubscribeCallback)(void *aContext, const char *aFullN
*/
typedef void (*otDnssdQueryUnsubscribeCallback)(void *aContext, const char *aFullName);
/**
* This opaque type represents a DNS-SD query.
*
*/
typedef void otDnssdQuery;
/**
* This structure represents information of a discovered service instance for a DNS-SD query.
*
@@ -128,6 +135,18 @@ typedef struct otDnssdHostInfo
uint32_t mTtl; ///< Service TTL (in seconds).
} otDnssdHostInfo;
/**
* This enumeration specifies a DNS-SD query type.
*
*/
typedef enum
{
OT_DNSSD_QUERY_TYPE_NONE = 0, ///< Service type unspecified.
OT_DNSSD_QUERY_TYPE_BROWSE = 1, ///< Service type browse service.
OT_DNSSD_QUERY_TYPE_RESOLVE = 2, ///< Service type resolve service instance.
OT_DNSSD_QUERY_TYPE_RESOLVE_HOST = 3, ///< Service type resolve hostname.
} otDnssdQueryType;
/**
* This function sets DNS-SD server query callbacks.
*
@@ -178,6 +197,28 @@ void otDnssdQueryHandleDiscoveredServiceInstance(otInstance * aIn
*/
void otDnssdQueryHandleDiscoveredHost(otInstance *aInstance, const char *aHostFullName, otDnssdHostInfo *aHostInfo);
/**
* This function aquires the next query in the DNS-SD server.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aQuery The query pointer. Pass NULL to get the first query.
*
* @returns A pointer to the query or NULL if no more queries.
*
*/
const otDnssdQuery *otDnssdGetNextQuery(otInstance *aInstance, const otDnssdQuery *aQuery);
/**
* This function aquires the DNS-SD query type and name for a specific query.
*
* @param[in] aQuery The query pointer acquired from `otDnssdGetNextQuery`.
* @param[out] aNameOutput The name output buffer, which should be `OT_DNS_MAX_NAME_SIZE` bytes long.
*
* @returns The DNS-SD query type.
*
*/
otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
/**
* @}
*
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (116)
#define OPENTHREAD_API_VERSION (117)
/**
* @addtogroup api-instance
+18
View File
@@ -73,4 +73,22 @@ void otDnssdQueryHandleDiscoveredHost(otInstance *aInstance, const char *aHostFu
instance.Get<Dns::ServiceDiscovery::Server>().HandleDiscoveredHost(aHostFullName, *aHostInfo);
}
const otDnssdQuery *otDnssdGetNextQuery(otInstance *aInstance, const otDnssdQuery *aQuery)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Dns::ServiceDiscovery::Server>().GetNextQuery(aQuery);
}
otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE])
{
otDnssdQueryType type = OT_DNSSD_QUERY_TYPE_NONE;
OT_ASSERT(aQuery != nullptr);
OT_ASSERT(aNameOutput != nullptr);
type = static_cast<otDnssdQueryType>(Dns::ServiceDiscovery::Server::GetQueryTypeAndName(aQuery, *aNameOutput));
return type;
}
#endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
+37 -7
View File
@@ -445,6 +445,7 @@ Error Server::AppendInstanceName(Message &aMessage, const char *aName, NameCompr
exit:
return error;
}
Error Server::AppendTxtRecord(Message & aMessage,
const char * aInstanceName,
const void * aTxtData,
@@ -763,7 +764,7 @@ Error Server::ResolveByQueryCallbacks(Header & aResponseHeader,
VerifyOrExit(mQuerySubscribe != nullptr, error = kErrorFailed);
queryType = GetQueryType(aResponseHeader, aResponseMessage, name);
queryType = GetQueryTypeAndName(aResponseHeader, aResponseMessage, name);
VerifyOrExit(queryType != kDnsQueryNone, error = kErrorNotImplemented);
query = NewQuery(aResponseHeader, aResponseMessage, aCompressInfo, aMessageInfo);
@@ -810,7 +811,7 @@ bool Server::CanAnswerQuery(const QueryTransaction & aQuery,
DnsQueryType sdType;
bool canAnswer = false;
sdType = GetQueryType(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
sdType = GetQueryTypeAndName(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
switch (sdType)
{
@@ -832,7 +833,7 @@ bool Server::CanAnswerQuery(const Server::QueryTransaction &aQuery, const char *
char name[Name::kMaxNameSize];
DnsQueryType sdType;
sdType = GetQueryType(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
sdType = GetQueryTypeAndName(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
return (sdType == kDnsQueryResolveHost) && (strcmp(name, aHostFullName) == 0);
}
@@ -961,9 +962,38 @@ void Server::HandleDiscoveredHost(const char *aHostFullName, const otDnssdHostIn
}
}
Server::DnsQueryType Server::GetQueryType(const Header & aHeader,
const Message &aMessage,
char (&aName)[Name::kMaxNameSize])
const otDnssdQuery *Server::GetNextQuery(const otDnssdQuery *aQuery) const
{
const QueryTransaction *now = &mQueryTransactions[0];
const QueryTransaction *found = nullptr;
const QueryTransaction *query = static_cast<const QueryTransaction *>(aQuery);
if (aQuery != nullptr)
{
now = query + 1;
}
for (; now < &mQueryTransactions[OT_ARRAY_LENGTH(mQueryTransactions)]; now++)
{
if (now->IsValid())
{
found = now;
break;
}
}
return static_cast<const otDnssdQuery *>(found);
}
Server::DnsQueryType Server::GetQueryTypeAndName(const otDnssdQuery *aQuery, char (&aName)[Name::kMaxNameSize])
{
const QueryTransaction *query = static_cast<const QueryTransaction *>(aQuery);
OT_ASSERT(query->IsValid());
return GetQueryTypeAndName(query->GetResponseHeader(), query->GetResponseMessage(), aName);
}
Server::DnsQueryType Server::GetQueryTypeAndName(const Header & aHeader,
const Message &aMessage,
char (&aName)[Name::kMaxNameSize])
{
DnsQueryType sdType = kDnsQueryNone;
@@ -1098,7 +1128,7 @@ void Server::FinalizeQuery(QueryTransaction &aQuery, Header::Response aResponseC
OT_ASSERT(mQueryUnsubscribe != nullptr);
sdType = GetQueryType(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
sdType = GetQueryTypeAndName(aQuery.GetResponseHeader(), aQuery.GetResponseMessage(), name);
OT_ASSERT(sdType != kDnsQueryNone);
OT_UNUSED_VARIABLE(sdType);
+58 -29
View File
@@ -59,6 +59,18 @@ namespace ServiceDiscovery {
class Server : public InstanceLocator, private NonCopyable
{
public:
/**
* This enumeration specifies a dns-sd query type.
*
*/
enum DnsQueryType : uint8_t
{
kDnsQueryNone = OT_DNSSD_QUERY_TYPE_NONE, ///< Service type unspecified.
kDnsQueryBrowse = OT_DNSSD_QUERY_TYPE_BROWSE, ///< Service type browse service.
kDnsQueryResolve = OT_DNSSD_QUERY_TYPE_RESOLVE, ///< Service type resolve service instance.
kDnsQueryResolveHost = OT_DNSSD_QUERY_TYPE_RESOLVE_HOST, ///< Service type resolve hostname.
};
/**
* This constructor initializes the object.
*
@@ -98,7 +110,7 @@ public:
* This method notifies a discovered service instance.
*
* @param[in] aServiceFullName The null-terminated full service name.
* @param[in] aInstanceInfo A pointer to the discovered service instance information.
* @param[in] aInstanceInfo A reference to the discovered service instance information.
*
*/
void HandleDiscoveredServiceInstance(const char *aServiceFullName, const otDnssdServiceInstanceInfo &aInstanceInfo);
@@ -107,27 +119,36 @@ public:
* This method notifies a discovered host.
*
* @param[in] aHostFullName The null-terminated full host name.
* @param[in] aHostInfo A pointer to the discovered host information.
* @param[in] aHostInfo A reference to the discovered host information.
*
*/
void HandleDiscoveredHost(const char *aHostFullName, const otDnssdHostInfo &aHostInfo);
private:
enum
{
kPort = OPENTHREAD_CONFIG_DNSSD_SERVER_PORT,
kProtocolLabelLength = 4,
kMaxConcurrentQueries = 32,
};
/**
* This function aquires the next query in the server.
*
* @param[in] aQuery The query pointer. Pass nullptr to get the first query.
*
* @returns A pointer to the query or nullptr if no more queries.
*
*/
const otDnssdQuery *GetNextQuery(const otDnssdQuery *aQuery) const;
/**
* This function aquires the dns-sd query type and name for a specific query.
*
* @param[in] aQuery The query pointer.
* @param[out] aNameOutput The name output buffer.
*
* @returns The dns-sd query type.
*
*/
static DnsQueryType GetQueryTypeAndName(const otDnssdQuery *aQuery, char (&aName)[Name::kMaxNameSize]);
private:
class NameCompressInfo : public Clearable<NameCompressInfo>
{
public:
enum : uint16_t
{
kUnknownOffset = 0, // Unknown offset value (used when offset is not yet set).
};
explicit NameCompressInfo(void) = default;
explicit NameCompressInfo(const char *aDomainName)
@@ -139,6 +160,11 @@ private:
{
}
enum : uint16_t
{
kUnknownOffset = 0, // Unknown offset value (used when offset is not yet set).
};
uint16_t GetDomainNameOffset(void) const { return mDomainNameOffset; }
void SetDomainNameOffset(uint16_t aOffset) { mDomainNameOffset = aOffset; }
@@ -201,6 +227,13 @@ private:
uint16_t mHostNameOffset; // Offset of host name serialization into the response message.
};
enum
{
kPort = OPENTHREAD_CONFIG_DNSSD_SERVER_PORT,
kProtocolLabelLength = 4,
kMaxConcurrentQueries = 32,
};
// This structure represents the splitting information of a full name.
struct NameComponentsOffsetInfo
{
@@ -232,11 +265,10 @@ private:
// instance.
};
enum : uint32_t
{
kQueryTimeout = OPENTHREAD_CONFIG_DNSSD_QUERY_TIMEOUT,
};
/**
* This class contains the compress information for a dns packet.
*
*/
class QueryTransaction
{
public:
@@ -251,15 +283,14 @@ private:
const Ip6::MessageInfo &aMessageInfo);
bool IsValid(void) const { return mResponseMessage != nullptr; }
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
Header & GetResponseHeader(void) { return mResponseHeader; }
const Header & GetResponseHeader(void) const { return mResponseHeader; }
Message & GetResponseMessage(void) { return *mResponseMessage; }
Header & GetResponseHeader(void) { return mResponseHeader; }
const Message & GetResponseMessage(void) const { return *mResponseMessage; }
Message & GetResponseMessage(void) { return *mResponseMessage; }
TimeMilli GetStartTime(void) const { return mStartTime; }
NameCompressInfo & GetNameCompressInfo(void) { return mCompressInfo; };
void Finalize(Header::Response aResponseMessage, Ip6::Udp::Socket &aSocket);
private:
Header mResponseHeader;
Message * mResponseMessage;
NameCompressInfo mCompressInfo;
@@ -267,12 +298,9 @@ private:
TimeMilli mStartTime;
};
enum DnsQueryType
enum : uint32_t
{
kDnsQueryNone,
kDnsQueryBrowse,
kDnsQueryResolve,
kDnsQueryResolveHost,
kQueryTimeout = OPENTHREAD_CONFIG_DNSSD_QUERY_TIMEOUT,
};
bool IsRunning(void) const { return mSocket.IsBound(); }
@@ -323,7 +351,6 @@ private:
Message & aMessage,
const Ip6::MessageInfo &aMessageInfo,
Ip6::Udp::Socket & aSocket);
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Header::Response ResolveBySrp(Header & aResponseHeader,
Message & aResponseMessage,
@@ -356,7 +383,9 @@ private:
static bool CanAnswerQuery(const Server::QueryTransaction &aQuery, const char *aHostFullName);
void AnswerQuery(QueryTransaction &aQuery, const char *aHostFullName, const otDnssdHostInfo &aHostInfo);
void FinalizeQuery(QueryTransaction &aQuery, Header::Response aResponseCode);
static DnsQueryType GetQueryType(const Header &aHeader, const Message &aMessage, char (&aName)[Name::kMaxNameSize]);
static DnsQueryType GetQueryTypeAndName(const Header & aHeader,
const Message &aMessage,
char (&aName)[Name::kMaxNameSize]);
static bool HasQuestion(const Header &aHeader, const Message &aMessage, const char *aName, uint16_t aQuestionType);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);