diff --git a/include/openthread/dns_client.h b/include/openthread/dns_client.h index 11c3ec517..b24317d0d 100644 --- a/include/openthread/dns_client.h +++ b/include/openthread/dns_client.h @@ -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; /** diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 3f2595018..35438f424 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -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 diff --git a/src/core/config/dns_client.h b/src/core/config/dns_client.h index e7c4d0868..817d7ab25 100644 --- a/src/core/config/dns_client.h +++ b/src/core/config/dns_client.h @@ -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 * diff --git a/src/core/net/dns_client.cpp b/src/core/net/dns_client.cpp index 6e5e8d11b..28e3d0e46 100644 --- a/src/core/net/dns_client.cpp +++ b/src/core/net/dns_client.cpp @@ -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(); + 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(); + 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) { diff --git a/src/core/net/dns_client.hpp b/src/core/net/dns_client.hpp index e44a8f9af..b0a9b7c29 100644 --- a/src/core/net/dns_client.hpp +++ b/src/core/net/dns_client.hpp @@ -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(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(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(aFlag); } +#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE + void SetNat64Mode(Nat64Mode aMode) { mNat64Mode = static_cast(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, - public otDnsAddressResponse + class Response : public otDnsAddressResponse, #if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE - , public otDnsBrowseResponse, - public otDnsServiceResponse + public otDnsServiceResponse, #endif - + public Clearable { 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[]; diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index f7063eca4..cc2bb1e7c 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -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`) diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index e0efdba2d..95f776136 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -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. diff --git a/tests/unit/test_ip_address.cpp b/tests/unit/test_ip_address.cpp index b680a0feb..c7da5159a 100644 --- a/tests/unit/test_ip_address.cpp +++ b/tests/unit/test_ip_address.cpp @@ -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"); } }