diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index 57ac430ea15..6cdd4e3adfd 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
(qbuffer.data()); + auto header = reinterpret_cast
(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