summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qdnslookup_unix.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-05-12 15:38:52 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-05-23 21:23:42 -0700
commit029e0bf55203846fa2335e1594689c6160c30113 (patch)
treec3853e8d1fde2a34e52fa8f991e6ce9f52445e0d /src/network/kernel/qdnslookup_unix.cpp
parentc5c7712910f5de454ee0d9a30b9a848d023bb543 (diff)
QDnsLookup: add a number of functions to simply setting error conditions
This also updates a few messages and transfers the translation context from QDnsLookupRunnable to QDnsLookup. Change-Id: I3e3bfef633af4130a03afffd175e86715e4a25e3 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/kernel/qdnslookup_unix.cpp')
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp152
1 files changed, 46 insertions, 106 deletions
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index d2435064ad..af2ef73a22 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -28,14 +28,14 @@ using namespace Qt::StringLiterals;
#if QT_CONFIG(res_setservers)
// https://www.ibm.com/docs/en/i/7.3?topic=ssw_ibm_i_73/apis/ressetservers.html
// https://docs.oracle.com/cd/E86824_01/html/E54774/res-setservers-3resolv.html
-static const char *applyNameServer(res_state state, const QHostAddress &nameserver, quint16 port)
+static bool applyNameServer(res_state state, const QHostAddress &nameserver, quint16 port)
{
- if (nameserver.isNull())
- return nullptr;
- union res_sockaddr_union u;
- setSockaddr(reinterpret_cast<sockaddr *>(&u.sin), nameserver, port);
- res_setservers(state, &u, 1);
- return nullptr;
+ if (!nameserver.isNull()) {
+ union res_sockaddr_union u;
+ setSockaddr(reinterpret_cast<sockaddr *>(&u.sin), nameserver, port);
+ res_setservers(state, &u, 1);
+ }
+ return true;
}
#else
template <typename T> void setNsMap(T &ext, std::enable_if_t<sizeof(T::nsmap) != 0, uint16_t> v)
@@ -83,20 +83,17 @@ template <typename State> bool setIpv6NameServer(State *, const void *, quint16)
return false;
}
-static const char *applyNameServer(res_state state, const QHostAddress &nameserver, quint16 port)
+static bool applyNameServer(res_state state, const QHostAddress &nameserver, quint16 port)
{
if (nameserver.isNull())
- return nullptr;
+ return true;
state->nscount = 1;
state->nsaddr_list[0].sin_family = AF_UNSPEC;
- if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
- if (!setIpv6NameServer(state, &nameserver, port))
- return QDnsLookupPrivate::msgNoIpV6NameServerAdresses;
- } else {
- setSockaddr(&state->nsaddr_list[0], nameserver, port);
- }
- return nullptr;
+ if (nameserver.protocol() == QAbstractSocket::IPv6Protocol)
+ return setIpv6NameServer(state, &nameserver, port);
+ setSockaddr(&state->nsaddr_list[0], nameserver, port);
+ return true;
}
#endif // !QT_CONFIG(res_setservers)
@@ -105,18 +102,17 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
// Initialize state.
std::remove_pointer_t<res_state> state = {};
if (res_ninit(&state) < 0) {
- reply->error = QDnsLookup::ResolverError;
- reply->errorString = tr("Resolver initialization failed");
- return;
+ int error = errno;
+ qErrnoWarning(error, "QDnsLookup: Resolver initialization failed");
+ return reply->makeResolverSystemError(error);
}
auto guard = qScopeGuard([&] { res_nclose(&state); });
//Check if a nameserver was set. If so, use it
- if (const char *msg = applyNameServer(&state, nameserver, DnsPort)) {
- qWarning("%s", msg);
- reply->error = QDnsLookup::ResolverError;
- reply->errorString = tr(msg);
- return;
+ if (!applyNameServer(&state, nameserver, DnsPort)) {
+ qWarning("QDnsLookup: %s", "IPv6 nameservers are currently not supported on this OS");
+ return reply->setError(QDnsLookup::ResolverError,
+ QDnsLookup::tr("IPv6 nameservers are currently not supported on this OS"));
}
#ifdef QDNSLOOKUP_DEBUG
state.options |= RES_DEBUG;
@@ -132,9 +128,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
responseLength = res_nquery(&state, requestName, C_IN, requestType, buffer.data(), buffer.size());
if (Q_UNLIKELY(responseLength > buffer.size())) {
// Ok, we give up.
- reply->error = QDnsLookup::ResolverError;
- reply->errorString.clear(); // We cannot be more specific, alas.
- return;
+ return reply->setError(QDnsLookup::ResolverError,
+ QDnsLookup::tr("Reply was too large"));
}
}
@@ -143,38 +138,12 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
// responseLength in case of error, we still can extract the
// exact error code from the response.
HEADER *header = (HEADER*)response;
- switch (header->rcode) {
- case NOERROR:
- break;
- case FORMERR:
- reply->error = QDnsLookup::InvalidRequestError;
- reply->errorString = tr("Server could not process query");
- return;
- case SERVFAIL:
- case NOTIMP:
- reply->error = QDnsLookup::ServerFailureError;
- reply->errorString = tr("Server failure");
- return;
- case NXDOMAIN:
- reply->error = QDnsLookup::NotFoundError;
- reply->errorString = tr("Non existent domain");
- return;
- case REFUSED:
- reply->error = QDnsLookup::ServerRefusedError;
- reply->errorString = tr("Server refused to answer");
- return;
- default:
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid reply received");
- return;
- }
+ if (header->rcode)
+ return reply->makeDnsRcodeError(header->rcode);
// Check the reply is valid.
- if (responseLength < int(sizeof(HEADER))) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid reply received");
- return;
- }
+ if (responseLength < int(sizeof(HEADER)))
+ return reply->makeInvalidReplyError();
char host[PACKETSZ], answer[PACKETSZ];
qptrdiff offset = sizeof(HEADER);
@@ -184,8 +153,7 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
// Skip the query host, type (2 bytes) and class (2 bytes).
status = dn_expand(response, response + responseLength, response + offset, host, sizeof(host));
if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Could not expand domain name");
+ reply->makeInvalidReplyError(QDnsLookup::tr("Could not expand domain name"));
return;
}
if (offset + status + 4 >= responseLength)
@@ -193,11 +161,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
else
offset += status + 4;
}
- if (ntohs(header->qdcount) > 1) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid reply received");
- return;
- }
+ if (ntohs(header->qdcount) > 1)
+ return reply->makeInvalidReplyError();
// Extract results.
const int answerCount = ntohs(header->ancount);
@@ -205,8 +170,7 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
while ((offset < responseLength) && (answerIndex < answerCount)) {
status = dn_expand(response, response + responseLength, response + offset, host, sizeof(host));
if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Could not expand domain name");
+ reply->makeInvalidReplyError(QDnsLookup::tr("Could not expand domain name"));
return;
}
const QString name = QUrl::fromAce(host);
@@ -227,11 +191,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
continue;
if (type == QDnsLookup::A) {
- if (size != 4) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid IPv4 address record");
- return;
- }
+ if (size != 4)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid IPv4 address record"));
const quint32 addr = qFromBigEndian<quint32>(response + offset);
QDnsHostAddressRecord record;
record.d->name = name;
@@ -239,11 +200,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
record.d->value = QHostAddress(addr);
reply->hostAddressRecords.append(record);
} else if (type == QDnsLookup::AAAA) {
- if (size != 16) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid IPv6 address record");
- return;
- }
+ if (size != 16)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid IPv6 address record"));
QDnsHostAddressRecord record;
record.d->name = name;
record.d->timeToLive = ttl;
@@ -251,11 +209,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
reply->hostAddressRecords.append(record);
} else if (type == QDnsLookup::CNAME) {
status = dn_expand(response, response + responseLength, response + offset, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid canonical name record");
- return;
- }
+ if (status < 0)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid canonical name record"));
QDnsDomainNameRecord record;
record.d->name = name;
record.d->timeToLive = ttl;
@@ -263,11 +218,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
reply->canonicalNameRecords.append(record);
} else if (type == QDnsLookup::NS) {
status = dn_expand(response, response + responseLength, response + offset, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid name server record");
- return;
- }
+ if (status < 0)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid name server record"));
QDnsDomainNameRecord record;
record.d->name = name;
record.d->timeToLive = ttl;
@@ -275,11 +227,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
reply->nameServerRecords.append(record);
} else if (type == QDnsLookup::PTR) {
status = dn_expand(response, response + responseLength, response + offset, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid pointer record");
- return;
- }
+ if (status < 0)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid pointer record"));
QDnsDomainNameRecord record;
record.d->name = name;
record.d->timeToLive = ttl;
@@ -288,11 +237,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
} else if (type == QDnsLookup::MX) {
const quint16 preference = qFromBigEndian<quint16>(response + offset);
status = dn_expand(response, response + responseLength, response + offset + 2, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid mail exchange record");
- return;
- }
+ if (status < 0)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid mail exchange record"));
QDnsMailExchangeRecord record;
record.d->exchange = QUrl::fromAce(answer);
record.d->name = name;
@@ -304,11 +250,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
const quint16 weight = qFromBigEndian<quint16>(response + offset + 2);
const quint16 port = qFromBigEndian<quint16>(response + offset + 4);
status = dn_expand(response, response + responseLength, response + offset + 6, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid service record");
- return;
- }
+ if (status < 0)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid service record"));
QDnsServiceRecord record;
record.d->name = name;
record.d->target = QUrl::fromAce(answer);
@@ -325,11 +268,8 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
while (txt < offset + size) {
const unsigned char length = response[txt];
txt++;
- if (txt + length > offset + size) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid text record");
- return;
- }
+ if (txt + length > offset + size)
+ return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid text record"));
record.d->values << QByteArrayView(response + txt, length).toByteArray();
txt += length;
}