[dns-client] add support for NAT64 during address resolution (#6414)

This commit adds support for NAT64 address translation (from IPv4 to
IPv6) during address resolution in `Dns::Client`. This feature is
enabled using `OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE` config
option. When enabled, the caller can specify in the address query
configuration whether to allow or disallow NAT64 address translation
for a specific query. The default behavior can also be set using the
default DNS client config.

When the NAT64 is allowed, if the response from server does not
provide an IPv6 address for the host name, we first check if the
server has provided IPv4 address information in the response, and if
not, start a new query for the IPv4 address. Once the IPv4 address(es)
of the host name are resolved, they are translated to IPv6 address(es)
and reported to the user in the query callback function.
This commit is contained in:
Abtin Keshavarzian
2021-04-14 00:45:18 -07:00
committed by GitHub
parent 3e833c120f
commit 7d008f6c76
8 changed files with 316 additions and 51 deletions
+15
View File
@@ -66,6 +66,20 @@ typedef enum
OT_DNS_FLAG_NO_RECURSION = 2, ///< Indicates DNS name server can not resolve the query recursively.
} otDnsRecursionFlag;
/**
* This enumeration type represents the NAT64 mode in an `otDnsQueryConfig`.
*
* The NAT64 mode indicates whether to allow or disallow NAT64 address translation during DNS client address resolution.
* This mode is only used when `OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE` is enabled.
*
*/
typedef enum
{
OT_DNS_NAT64_UNSPECIFIED = 0, ///< NAT64 mode is not specified. Use default NAT64 mode.
OT_DNS_NAT64_ALLOW = 1, ///< Allow NAT64 address translation during DNS client address resolution.
OT_DNS_NAT64_DISALLOW = 2, ///< Do not allow NAT64 address translation during DNS client address resolution.
} otDnsNat64Mode;
/**
* This structure represents a DNS query configuration.
*
@@ -79,6 +93,7 @@ typedef struct otDnsQueryConfig
uint32_t mResponseTimeout; ///< Wait time (in msec) to rx response. Zero indicates unspecified value.
uint8_t mMaxTxAttempts; ///< Maximum tx attempts before reporting failure. Zero for unspecified value.
otDnsRecursionFlag mRecursionFlag; ///< Indicates whether the server can resolve the query recursively or not.
otDnsNat64Mode mNat64Mode; ///< Allow/Disallow NAT64 address translation during address resolution.
} otDnsQueryConfig;
/**
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (98)
#define OPENTHREAD_API_VERSION (99)
/**
* @addtogroup api-instance
+22
View File
@@ -45,6 +45,28 @@
#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
*
* Define to 1 to enable support for NAT64 address translation (from IPv4 to IPv6) during address resolution by DNS
* client.
*
*/
#ifndef OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
#define OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE 1
#endif
/**
* @def OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_NAT64_ALLOWED
*
* Specifies the default NAT64 mode, i.e., whether to allow or disallow NAT64 address translation during DNS client
* address resolution. This mode is only available when `OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE` is enabled.
*
*/
#ifndef OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_NAT64_ALLOWED
#define OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_NAT64_ALLOWED 1
#endif
/**
* @def OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
*
+210 -39
View File
@@ -60,6 +60,9 @@ Client::QueryConfig::QueryConfig(InitMode aMode)
SetResponseTimeout(kDefaultResponseTimeout);
SetMaxTxAttempts(kDefaultMaxTxAttempts);
SetRecursionFlag(kDefaultRecursionDesired ? kFlagRecursionDesired : kFlagNoRecursion);
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
SetNat64Mode(kDefaultNat64Allowed ? kNat64Allow : kNat64Disallow);
#endif
}
void Client::QueryConfig::SetFrom(const QueryConfig &aConfig, const QueryConfig &aDefaultConfig)
@@ -94,6 +97,13 @@ void Client::QueryConfig::SetFrom(const QueryConfig &aConfig, const QueryConfig
{
SetRecursionFlag(aDefaultConfig.GetRecursionFlag());
}
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
if (GetNat64Mode() == kNat64Unspecified)
{
SetNat64Mode(aDefaultConfig.GetNat64Mode());
}
#endif
}
//---------------------------------------------------------------------------------------------------------------------
@@ -122,37 +132,57 @@ Error Client::Response::GetName(char *aNameBuffer, uint16_t aNameBufferSize) con
return Name::ReadName(*mQuery, offset, aNameBuffer, aNameBufferSize);
}
Error Client::Response::CheckForHostNameAlias(Section aSection, Name &aHostName) const
{
// If the response includes a CNAME record mapping the query host
// name to a canonical name, we update `aHostName` to the new alias
// name. Otherwise `aHostName` remains as before.
Error error;
uint16_t offset;
uint16_t numRecords;
CnameRecord cnameRecord;
VerifyOrExit(mMessage != nullptr, error = kErrorNotFound);
SelectSection(aSection, offset, numRecords);
error = ResourceRecord::FindRecord(*mMessage, offset, numRecords, /* aIndex */ 0, aHostName, cnameRecord);
switch (error)
{
case kErrorNone:
// A CNAME record was found. `offset` now points to after the
// last read byte within the `mMessage` into the `cnameRecord`
// (which is the start of the new canonical name).
aHostName.SetFromMessage(*mMessage, offset);
error = Name::ParseName(*mMessage, offset);
break;
case kErrorNotFound:
error = kErrorNone;
break;
default:
break;
}
exit:
return error;
}
Error Client::Response::FindHostAddress(Section aSection,
const Name & aHostName,
uint16_t aIndex,
Ip6::Address &aAddress,
uint32_t & aTtl) const
{
Error error;
uint16_t offset;
uint16_t numRecords;
Name name = aHostName;
CnameRecord cnameRecord;
AaaaRecord aaaaRecord;
Error error;
uint16_t offset;
uint16_t numRecords;
Name name = aHostName;
AaaaRecord aaaaRecord;
VerifyOrExit(mMessage != nullptr, error = kErrorNotFound);
// If the response includes a CNAME record mapping the query host
// name to a canonical name, we then search for AAAA records
// matching the canonical name.
SelectSection(aSection, offset, numRecords);
error = ResourceRecord::FindRecord(*mMessage, offset, numRecords, /* aIndex */ 0, aHostName, cnameRecord);
if (error == kErrorNone)
{
name.SetFromMessage(*mMessage, offset);
SuccessOrExit(error = Name::ParseName(*mMessage, offset));
}
else
{
VerifyOrExit(error == kErrorNotFound);
}
SuccessOrExit(error = CheckForHostNameAlias(aSection, name));
SelectSection(aSection, offset, numRecords);
SuccessOrExit(error = ResourceRecord::FindRecord(*mMessage, offset, numRecords, aIndex, name, aaaaRecord));
@@ -163,6 +193,26 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error Client::Response::FindARecord(Section aSection, const Name &aHostName, uint16_t aIndex, ARecord &aARecord) const
{
Error error;
uint16_t offset;
uint16_t numRecords;
Name name = aHostName;
SuccessOrExit(error = CheckForHostNameAlias(aSection, name));
SelectSection(aSection, offset, numRecords);
error = ResourceRecord::FindRecord(*mMessage, offset, numRecords, aIndex, name, aARecord);
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
Error Client::Response::FindServiceInfo(Section aSection, const Name &aName, ServiceInfo &aServiceInfo) const
@@ -257,9 +307,60 @@ exit:
Error Client::AddressResponse::GetAddress(uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const
{
return FindHostAddress(kAnswerSection, Name(*mQuery, kNameOffsetInQuery), aIndex, aAddress, aTtl);
Error error = kErrorNone;
Name name(*mQuery, kNameOffsetInQuery);
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
// If the response is for an IPv4 address query or if it is an
// IPv6 address query response with no IPv6 address but with
// an IPv4 in its additional section, we read the IPv4 address
// and translate it to an IPv6 address.
QueryInfo info;
info.ReadFrom(*mQuery);
if ((info.mQueryType == kIp4AddressQuery) || mIp6QueryResponseRequiresNat64)
{
Section section;
ARecord aRecord;
Ip6::Prefix nat64Prefix;
SuccessOrExit(error = GetNat64Prefix(nat64Prefix));
section = (info.mQueryType == kIp4AddressQuery) ? kAnswerSection : kAdditionalDataSection;
SuccessOrExit(error = FindARecord(section, name, aIndex, aRecord));
aAddress.SynthesizeFromIp4Address(nat64Prefix, aRecord.GetAddress());
aTtl = aRecord.GetTtl();
ExitNow();
}
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
ExitNow(error = FindHostAddress(kAnswerSection, name, aIndex, aAddress, aTtl));
exit:
return error;
}
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error Client::AddressResponse::GetNat64Prefix(Ip6::Prefix &aPrefix) const
{
// Use well-known prefix "64:ff9b::/96" (temporary solution).
static const uint8_t kWellknownPrefix[] = {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
aPrefix.Clear();
aPrefix.Set(kWellknownPrefix, 96);
return kErrorNone;
}
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
//---------------------------------------------------------------------------------------------------------------------
@@ -410,25 +511,34 @@ Error Client::ServiceResponse::GetHostAddress(const char * aHostName,
//---------------------------------------------------------------------------------------------------------------------
// Client
const uint16_t Client::kAddressQueryRecordTypes[] = {ResourceRecord::kTypeAaaa};
const uint16_t Client::kIp6AddressQueryRecordTypes[] = {ResourceRecord::kTypeAaaa};
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
const uint16_t Client::kIp4AddressQueryRecordTypes[] = {ResourceRecord::kTypeA};
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
const uint16_t Client::kBrowseQueryRecordTypes[] = {ResourceRecord::kTypePtr};
const uint16_t Client::kServiceQueryRecordTypes[] = {ResourceRecord::kTypeSrv, ResourceRecord::kTypeTxt};
#endif
const uint8_t Client::kQuestionCount[] = {
/* (0) kAddressQuery -> */ OT_ARRAY_LENGTH(kAddressQueryRecordTypes), // AAAA records
/* kIp6AddressQuery -> */ OT_ARRAY_LENGTH(kIp6AddressQueryRecordTypes), // AAAA records
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
/* kIp4AddressQuery -> */ OT_ARRAY_LENGTH(kIp4AddressQueryRecordTypes), // A records
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
/* (1) kBrowseQuery -> */ OT_ARRAY_LENGTH(kBrowseQueryRecordTypes), // PTR records
/* (2) kServiceQuery -> */ OT_ARRAY_LENGTH(kServiceQueryRecordTypes), // SRV and TXT records
/* kBrowseQuery -> */ OT_ARRAY_LENGTH(kBrowseQueryRecordTypes), // PTR records
/* kServiceQuery -> */ OT_ARRAY_LENGTH(kServiceQueryRecordTypes), // SRV and TXT records
#endif
};
const uint16_t *Client::kQuestionRecordTypes[] = {
/* (0) kAddressQuery -> */ kAddressQueryRecordTypes,
/* kIp6AddressQuery -> */ kIp6AddressQueryRecordTypes,
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
/* kIp4AddressQuery -> */ kIp4AddressQueryRecordTypes,
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
/* (1) kBrowseQuery -> */ kBrowseQueryRecordTypes,
/* (2) kServiceQuery -> */ kServiceQueryRecordTypes,
/* kBrowseQuery -> */ kBrowseQueryRecordTypes,
/* kServiceQuery -> */ kServiceQueryRecordTypes,
#endif
};
@@ -438,8 +548,14 @@ Client::Client(Instance &aInstance)
, mTimer(aInstance, Client::HandleTimer)
, mDefaultConfig(QueryConfig::kInitFromDefaults)
{
static_assert(kAddressQuery == 0, "kAddressQuery value is not correct");
static_assert(kIp6AddressQuery == 0, "kIp6AddressQuery value is not correct");
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
static_assert(kIp4AddressQuery == 1, "kIp4AddressQuery value is not correct");
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
static_assert(kBrowseQuery == 2, "kBrowseQuery value is not correct");
static_assert(kServiceQuery == 3, "kServiceQuery value is not correct");
#endif
#elif OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
static_assert(kBrowseQuery == 1, "kBrowseQuery value is not correct");
static_assert(kServiceQuery == 2, "kServiceQuery value is not correct");
#endif
@@ -488,7 +604,7 @@ Error Client::ResolveAddress(const char * aHostName,
QueryInfo info;
info.Clear();
info.mQueryType = kAddressQuery;
info.mQueryType = kIp6AddressQuery;
info.mCallback.mAddressCallback = aCallback;
return StartQuery(info, aConfig, nullptr, aHostName, aContext);
@@ -694,7 +810,8 @@ void Client::FinalizeQuery(Query &aQuery, Error aError)
Response response;
QueryInfo info;
response.mQuery = &aQuery;
response.mInstance = &Get<Instance>();
response.mQuery = &aQuery;
info.ReadFrom(aQuery);
FinalizeQuery(response, info.mQueryType, aError);
@@ -709,7 +826,10 @@ void Client::FinalizeQuery(Response &aResponse, QueryType aType, Error aError)
switch (aType)
{
case kAddressQuery:
case kIp6AddressQuery:
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
case kIp4AddressQuery:
#endif
if (callback.mAddressCallback != nullptr)
{
callback.mAddressCallback(aError, &aResponse, context);
@@ -777,7 +897,8 @@ void Client::ProcessResponse(const Message &aMessage)
QueryType type;
Error responseError;
response.mMessage = &aMessage;
response.mInstance = &Get<Instance>();
response.mMessage = &aMessage;
// We intentionally parse the response in a separate method
// `ParseResponse()` to free all the stack allocated variables
@@ -798,6 +919,7 @@ Error Client::ParseResponse(Response &aResponse, QueryType &aType, Error &aRespo
uint16_t offset = message.GetOffset();
Header header;
QueryInfo info;
Name queryName;
SuccessOrExit(error = message.Read(offset, header));
offset += sizeof(Header);
@@ -812,14 +934,15 @@ Error Client::ParseResponse(Response &aResponse, QueryType &aType, Error &aRespo
info.ReadFrom(*aResponse.mQuery);
aType = info.mQueryType;
queryName.SetFromMessage(*aResponse.mQuery, kNameOffsetInQuery);
// Check the Question Section
VerifyOrExit(header.GetQuestionCount() == kQuestionCount[aType], error = kErrorParse);
for (uint8_t num = 0; num < kQuestionCount[aType]; num++)
{
// The name is encoded after `Info` struct in `query`.
SuccessOrExit(error = Name::CompareName(message, offset, *aResponse.mQuery, kNameOffsetInQuery));
SuccessOrExit(error = Name::CompareName(message, offset, queryName));
offset += sizeof(Question);
}
@@ -838,6 +961,54 @@ Error Client::ParseResponse(Response &aResponse, QueryType &aType, Error &aRespo
aResponseError = Header::ResponseCodeToError(header.GetResponseCode());
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
if (aType == kIp6AddressQuery)
{
Ip6::Address ip6ddress;
uint32_t ttl;
ARecord aRecord;
// If the response does not contain an answer for the IPv6 address
// resolution query and if NAT64 is allowed for this query, we can
// perform IPv4 to IPv6 address translation.
VerifyOrExit(aResponse.FindHostAddress(Response::kAnswerSection, queryName, /* aIndex */ 0, ip6ddress, ttl) !=
kErrorNone);
VerifyOrExit(info.mConfig.GetNat64Mode() == QueryConfig::kNat64Allow);
// First, we check if the response already contains an A record
// (IPv4 address) for the query name.
if (aResponse.FindARecord(Response::kAdditionalDataSection, queryName, /* aIndex */ 0, aRecord) == kErrorNone)
{
aResponse.mIp6QueryResponseRequiresNat64 = true;
aResponseError = kErrorNone;
ExitNow();
}
// Otherwise, we send a new query for IPv4 address resolution
// for the same host name. We reuse the existing `query`
// instance and keep all the info but clear `mTransmissionCount`
// and `mMessageId` (so that a new random message ID is
// selected). The new `info` will be saved in the query in
// `SendQuery()`. Note that the current query is still in the
// `mQueries` list when `SendQuery()` selects a new random
// message ID, so the existing message ID for this query will
// not be reused. Since the query is not yet resolved, we
// return `kErrorPending`.
info.mQueryType = kIp4AddressQuery;
info.mMessageId = 0;
info.mTransmissionCount = 0;
SendQuery(*aResponse.mQuery, info, /* aUpdateTimer */ true);
error = kErrorPending;
}
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
exit:
if (error != kErrorNone)
{
+64 -7
View File
@@ -108,6 +108,19 @@ public:
kFlagNoRecursion = OT_DNS_FLAG_NO_RECURSION, ///< Server can not resolve the query recursively.
};
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
/**
* This enumeration type represents the NAT64 mode.
*
*/
enum Nat64Mode
{
kNat64Unspecified = OT_DNS_NAT64_UNSPECIFIED, ///< NAT64 mode is not specified. Use default NAT64 mode.
kNat64Allow = OT_DNS_NAT64_ALLOW, ///< Allow NAT64 address translation
kNat64Disallow = OT_DNS_NAT64_DISALLOW, ///< Disallow NAT64 address translation.
};
#endif
/**
* This is the default constructor for `QueryConfig` object.
*
@@ -149,6 +162,16 @@ public:
*/
RecursionFlag GetRecursionFlag(void) const { return static_cast<RecursionFlag>(mRecursionFlag); }
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
/**
* This method gets the NAT64 mode.
*
* @returns The NAT64 mode.
*
*/
Nat64Mode GetNat64Mode(void) const { return static_cast<Nat64Mode>(mNat64Mode); }
#endif
private:
enum : uint32_t
{
@@ -170,6 +193,13 @@ public:
kDefaultRecursionDesired = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_RECURSION_DESIRED_FLAG,
};
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
enum : bool
{
kDefaultNat64Allowed = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_NAT64_ALLOWED,
};
#endif
enum InitMode : uint8_t
{
kInitFromDefaults,
@@ -184,6 +214,9 @@ public:
void SetResponseTimeout(uint32_t aResponseTimeout) { mResponseTimeout = aResponseTimeout; }
void SetMaxTxAttempts(uint8_t aMaxTxAttempts) { mMaxTxAttempts = aMaxTxAttempts; }
void SetRecursionFlag(RecursionFlag aFlag) { mRecursionFlag = static_cast<otDnsRecursionFlag>(aFlag); }
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
void SetNat64Mode(Nat64Mode aMode) { mNat64Mode = static_cast<otDnsNat64Mode>(aMode); }
#endif
void SetFrom(const QueryConfig &aConfig, const QueryConfig &aDefaultConfig);
};
@@ -200,14 +233,12 @@ public:
* This class represents a DNS query response.
*
*/
class Response : public Clearable<Response>,
public otDnsAddressResponse
class Response : public otDnsAddressResponse,
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
,
public otDnsBrowseResponse,
public otDnsServiceResponse
public otDnsServiceResponse,
#endif
public Clearable<Response>
{
friend class Client;
@@ -222,22 +253,34 @@ public:
Error GetName(char *aNameBuffer, uint16_t aNameBufferSize) const;
void SelectSection(Section aSection, uint16_t &aOffset, uint16_t &aNumRecord) const;
Error CheckForHostNameAlias(Section aSection, Name &aHostName) const;
Error FindHostAddress(Section aSection,
const Name & aHostName,
uint16_t aIndex,
Ip6::Address &aAddress,
uint32_t & aTtl) const;
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error FindARecord(Section aSection, const Name &aHostName, uint16_t aIndex, ARecord &aARecord) const;
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
Error FindServiceInfo(Section aSection, const Name &aName, ServiceInfo &aServiceInfo) const;
#endif
Instance * mInstance; // The OpenThread instance.
Query * mQuery; // The associated query.
const Message *mMessage; // The response message.
uint16_t mAnswerOffset; // Answer section offset in `mMessage`.
uint16_t mAnswerRecordCount; // Number of records in answer section.
uint16_t mAdditionalOffset; // Additional data section offset in `mMessage`.
uint16_t mAdditionalRecordCount; // Number of records in additional data section.
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
// This flag is only used in an IPv6 address query response.
// It indicates that the response does not contain any IPv6
// addresses but server provided at least one IPv4 address
// in the additional data section for NAT64 address synthesis.
bool mIp6QueryResponseRequiresNat64;
#endif
};
/**
@@ -292,6 +335,11 @@ public:
*
*/
Error GetAddress(uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;
private:
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error GetNat64Prefix(Ip6::Prefix &aPrefix) const;
#endif
};
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
@@ -612,7 +660,10 @@ public:
private:
enum QueryType : uint8_t
{
kAddressQuery, // Address resolution.
kIp6AddressQuery, // IPv6 Address resolution.
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
kIp4AddressQuery, // IPv4 Address resolution
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
kBrowseQuery, // Browse (service instance enumeration).
kServiceQuery, // Service instance resolution.
@@ -668,11 +719,17 @@ private:
Error ParseResponse(Response &aResponse, QueryType &aType, Error &aResponseError);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error CheckAddressResponse(Response &aResponse, Error aResponseError) const;
#endif
static const uint8_t kQuestionCount[];
static const uint16_t *kQuestionRecordTypes[];
static const uint16_t kAddressQueryRecordTypes[];
static const uint16_t kIp6AddressQueryRecordTypes[];
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
static const uint16_t kIp4AddressQueryRecordTypes[];
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
static const uint16_t kBrowseQueryRecordTypes[];
static const uint16_t kServiceQueryRecordTypes[];
+1 -1
View File
@@ -453,7 +453,7 @@ bool Address::MatchesFilter(TypeFilter aFilter) const
return matches;
}
void Address::SetFromTranslatedIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address)
void Address::SynthesizeFromIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address)
{
// The prefix length must be 32, 40, 48, 56, 64, 96. IPv4 bytes are added
// after the prefix, skipping over the bits 64 to 71 (byte at `kSkipIndex`)
+1 -1
View File
@@ -892,7 +892,7 @@ public:
* @param[in] aIp4Address The IPv4 address to translate to IPv6.
*
*/
void SetFromTranslatedIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address);
void SynthesizeFromIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address);
/**
* This method converts an IPv6 address string to binary.
+2 -2
View File
@@ -399,13 +399,13 @@ void TestIp4Ip6Translation(void)
SuccessOrQuit(expectedAddress.FromString(testCase.mIp6Address), "Ip6::FromString() failed");
address.SetFromTranslatedIp4Address(prefix, ip4Address);
address.SynthesizeFromIp4Address(prefix, ip4Address);
printf("Prefix: %-26s IPv4Addr: %-12s Ipv6Address: %-36s Expected: %s (%s)\n", prefix.ToString().AsCString(),
ip4Address.ToString().AsCString(), address.ToString().AsCString(), testCase.mIp6Address,
expectedAddress.ToString().AsCString());
VerifyOrQuit(address == expectedAddress, "Ip6::SetFromTranslatedIp4Address() failed");
VerifyOrQuit(address == expectedAddress, "Ip6::SynthesizeFromIp4Address() failed");
}
}