[dns-client] enhance logic for following up with IPv4 address query (#10781)

This commit updates the `ReplaceWithIp4Query()` method, which
determines whether an unsuccessful IPv6 address query should be
followed up with an IPv4 query.

The logic is changed as follows:

- If the response code to the IPv6 query indicates success but the
  answer section is empty (meaning the name exists but has no IPv6
  address), or the response code indicates an error other than
  `NameError`, the query is replaced with an IPv4 address resolution
  query for the same name.
- If the server responds with `NameError` (RCode=3), indicating that
  the name doesn't exist, an IPv4 query is not attempted.

This replaces the previous behavior where a follow-up query was
attempted for any error response code.
This commit is contained in:
Abtin Keshavarzian
2024-10-11 10:32:53 -07:00
committed by GitHub
parent af2e10a7bf
commit d163dee2af
3 changed files with 35 additions and 8 deletions
+33 -7
View File
@@ -1309,17 +1309,18 @@ void Client::ProcessResponse(const Message &aResponseMessage)
SuccessOrExit(ParseResponse(aResponseMessage, query, responseError));
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
if (ReplaceWithIp4Query(*query, aResponseMessage) == kErrorNone)
{
ExitNow();
}
#endif
if (responseError != kErrorNone)
{
// Received an error from server, check if we can replace
// the query.
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
if (ReplaceWithIp4Query(*query) == kErrorNone)
{
ExitNow();
}
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
if (ReplaceWithSeparateSrvTxtQueries(*query) == kErrorNone)
{
@@ -1556,16 +1557,41 @@ void Client::HandleTimer(void)
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error Client::ReplaceWithIp4Query(Query &aQuery)
Error Client::ReplaceWithIp4Query(Query &aQuery, const Message &aResponseMessage)
{
Error error = kErrorFailed;
QueryInfo info;
Header header;
info.ReadFrom(aQuery);
VerifyOrExit(info.mQueryType == kIp6AddressQuery);
VerifyOrExit(info.mConfig.GetNat64Mode() == QueryConfig::kNat64Allow);
// Check the response to the IPv6 query from the server. If the
// response code is success but the answer section is empty
// (indicating the name exists but has no IPv6 address), or the
// response code indicates an error other than `NameError`, we
// replace the query with an IPv4 address resolution query for
// the same name. If the server responded with `NameError`
// (RCode=3), it indicates that the name doesn't exist, so there
// is no need to try an IPv4 query.
SuccessOrExit(aResponseMessage.Read(aResponseMessage.GetOffset(), header));
switch (header.GetResponseCode())
{
case Header::kResponseSuccess:
VerifyOrExit(header.GetAnswerCount() == 0);
OT_FALL_THROUGH;
default:
break;
case Header::kResponseNameError:
ExitNow();
}
// We send a new query for IPv4 address resolution
// for the same host name. We reuse the existing `aQuery`
// instance and keep all the info but clear `mTransmissionCount`
+1 -1
View File
@@ -805,7 +805,7 @@ private:
void HandleTimer(void);
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Error ReplaceWithIp4Query(Query &aQuery);
Error ReplaceWithIp4Query(Query &aQuery, const Message &aResponseMessage);
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
Error Resolve(const char *aInstanceLabel,
@@ -1696,6 +1696,7 @@ void TestProxyTimeout(void)
config.Clear();
config.mResponseTimeout = 120 * 1000; // 2 minutes (in msec)
config.mNat64Mode = OT_DNS_NAT64_DISALLOW;
dnsClient->SetDefaultConfig(config);
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");