diff options
Diffstat (limited to 'src/network/kernel/qdnslookup_unix.cpp')
-rw-r--r-- | src/network/kernel/qdnslookup_unix.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index 02172933485..5696a3ca701 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 |