summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-04-18 11:05:26 -0700
committerThiago Macieira <thiago.macieira@intel.com>2024-04-22 21:36:29 -0700
commitf19e9f2521ff7784223ec34fc6794583f4faa2a5 (patch)
treeb0459b05f45446d0bb23f2c84db5b60f8bfab0c6
parentd139642aefde2d00683cf29f3875ccfae6c66779 (diff)
QDnsLookup/Unix: handle more error conditions from res_nsend()
It does set ECONNREFUSED explicitly. So let's reuse ServerRefusedError for it too (it was so far only used when we got a REFUSED DNS answer), which allows tst_QDnsLookup to handle this as an ignorable failure. For almost everything else, it sets ETIMEDOUT to indicate "no answer", which isn't useful. So let's inspect the reply to see if it has something. Pick-to: 6.7 Change-Id: I455fe22ef4ad4b2f9b01fffd17c771ffa4a998be Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 0217293348..5696a3ca70 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -183,14 +183,22 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
auto attemptToSend = [&]() {
std::memset(buffer.data(), 0, HFIXEDSZ); // the header is enough
int responseLength = res_nsend(&state, qbuffer.data(), queryLength, buffer.data(), buffer.size());
- if (responseLength < 0) {
- // network error of some sort
- if (errno == ETIMEDOUT)
- reply->makeTimeoutError();
- else
- reply->makeResolverSystemError();
- }
- return responseLength;
+ if (responseLength >= 0)
+ return responseLength; // success
+
+ // libresolv uses ETIMEDOUT for resolver errors ("no answer")
+ if (errno == ECONNREFUSED)
+ reply->setError(QDnsLookup::ServerRefusedError, qt_error_string());
+ else if (errno != ETIMEDOUT)
+ reply->makeResolverSystemError(); // some other error
+
+ auto query = reinterpret_cast<HEADER *>(qbuffer.data());
+ auto header = reinterpret_cast<HEADER *>(buffer.data());
+ if (query->id == header->id && header->qr)
+ reply->makeDnsRcodeError(header->rcode);
+ else
+ reply->makeTimeoutError(); // must really be a timeout
+ return -1;
};
// strictly use UDP, we'll deal with truncated replies ourselves