aboutsummaryrefslogtreecommitdiff
path: root/src/base/qdnslookup_unix.cpp
diff options
context:
space:
mode:
authorNiels Ole Salscheider <niels_ole@salscheider-online.de>2017-09-03 22:00:29 +0200
committerNiels Ole Salscheider <niels_ole@salscheider-online.de>2017-09-04 19:44:01 +0200
commit2a5ccd3bd191b75b9fa148a8fa7f3d3ddc225add (patch)
treed8cd64a20fbe77a78be7c9533787044157190442 /src/base/qdnslookup_unix.cpp
parent3241e63f07c5fa493788897ddfb87a201205f621 (diff)
downloadqxmpp-2a5ccd3bd191b75b9fa148a8fa7f3d3ddc225add.tar.gz
Drop support for Qt 4
Diffstat (limited to 'src/base/qdnslookup_unix.cpp')
-rw-r--r--src/base/qdnslookup_unix.cpp323
1 files changed, 0 insertions, 323 deletions
diff --git a/src/base/qdnslookup_unix.cpp b/src/base/qdnslookup_unix.cpp
deleted file mode 100644
index f4d1c64c..00000000
--- a/src/base/qdnslookup_unix.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org>
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdnslookup_p.h"
-
-#include <QLibrary>
-#include <QMutex>
-#include <QScopedPointer>
-#include <QUrl>
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/nameser_compat.h>
-#include <resolv.h>
-
-QT_BEGIN_NAMESPACE
-
-static QMutex local_res_mutex;
-typedef int (*dn_expand_proto)(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
-static dn_expand_proto local_dn_expand = 0;
-typedef void (*res_nclose_proto)(res_state);
-static res_nclose_proto local_res_nclose = 0;
-typedef int (*res_ninit_proto)(res_state);
-static res_ninit_proto local_res_ninit = 0;
-typedef int (*res_nquery_proto)(res_state, const char *, int, int, unsigned char *, int);
-static res_nquery_proto local_res_nquery = 0;
-
-// Custom deleter to close resolver state.
-
-struct QDnsLookupStateDeleter
-{
- static inline void cleanup(struct __res_state *pointer)
- {
- local_res_nclose(pointer);
- }
-};
-
-static void resolveLibrary()
-{
- QLibrary lib(QLatin1String("resolv"));
- if (!lib.load())
- return;
-
- local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand"));
- if (!local_dn_expand)
- local_dn_expand = dn_expand_proto(lib.resolve("dn_expand"));
-
- local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose"));
- if (!local_res_nclose)
- local_res_nclose = res_nclose_proto(lib.resolve("res_9_nclose"));
- if (!local_res_nclose)
- local_res_nclose = res_nclose_proto(lib.resolve("res_nclose"));
-
- local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit"));
- if (!local_res_ninit)
- local_res_ninit = res_ninit_proto(lib.resolve("res_9_ninit"));
- if (!local_res_ninit)
- local_res_ninit = res_ninit_proto(lib.resolve("res_ninit"));
-
- local_res_nquery = res_nquery_proto(lib.resolve("__res_nquery"));
- if (!local_res_nquery)
- local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery"));
- if (!local_res_nquery)
- local_res_nquery = res_nquery_proto(lib.resolve("res_nquery"));
-}
-
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
-{
- // Load dn_expand, res_ninit and res_nquery on demand.
- static volatile bool triedResolve = false;
- if (!triedResolve) {
- QMutexLocker locker(&local_res_mutex);
- if (!triedResolve) {
- resolveLibrary();
- triedResolve = true;
- }
- }
-
- // If dn_expand, res_ninit or res_nquery is missing, fail.
- if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) {
- reply->error = QDnsLookup::ResolverError;
- reply->errorString = tr("Resolver functions not found");
- return;
- }
-
- // Initialize state.
- struct __res_state state;
- memset(&state, 0, sizeof(state));
- if (local_res_ninit(&state) < 0) {
- reply->error = QDnsLookup::ResolverError;
- reply->errorString = tr("Resolver initialization failed");
- return;
- }
-#ifdef QDNSLOOKUP_DEBUG
- state.options |= RES_DEBUG;
-#endif
- QScopedPointer<struct __res_state, QDnsLookupStateDeleter> state_ptr(&state);
-
- // Perform DNS query.
- unsigned char response[PACKETSZ];
- memset(response, 0, sizeof(response));
- const int responseLength = local_res_nquery(&state, requestName, C_IN, requestType, response, sizeof(response));
-
- // Check the response header.
- HEADER *header = (HEADER*)response;
- const int answerCount = ntohs(header->ancount);
- switch (header->rcode) {
- case NOERROR:
- break;
- case FORMERR:
- reply->error = QDnsLookup::InvalidRequestError;
- reply->errorString = tr("Server could not process query");
- return;
- case SERVFAIL:
- 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;
- }
-
- // Check the reply is valid.
- if (responseLength < int(sizeof(HEADER))) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid reply received");
- return;
- }
-
- // Skip the query host, type (2 bytes) and class (2 bytes).
- char host[PACKETSZ], answer[PACKETSZ];
- unsigned char *p = response + sizeof(HEADER);
- int status = local_dn_expand(response, response + responseLength, p, host, sizeof(host));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Could not expand domain name");
- return;
- }
- p += status + 4;
-
- // Extract results.
- int answerIndex = 0;
- while ((p < response + responseLength) && (answerIndex < answerCount)) {
- status = local_dn_expand(response, response + responseLength, p, host, sizeof(host));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Could not expand domain name");
- return;
- }
- const QString name = QUrl::fromAce(host);
-
- p += status;
- const quint16 type = (p[0] << 8) | p[1];
- p += 2; // RR type
- p += 2; // RR class
- const quint32 ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- p += 4;
- const quint16 size = (p[0] << 8) | p[1];
- p += 2;
-
- if (type == QDnsLookup::A) {
- if (size != 4) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid IPv4 address record");
- return;
- }
- const quint32 addr = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- QDnsHostAddressRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- 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;
- }
- QDnsHostAddressRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- record.d->value = QHostAddress(p);
- reply->hostAddressRecords.append(record);
- } else if (type == QDnsLookup::CNAME) {
- status = local_dn_expand(response, response + responseLength, p, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid canonical name record");
- return;
- }
- QDnsDomainNameRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- record.d->value = QUrl::fromAce(answer);
- reply->canonicalNameRecords.append(record);
- } else if (type == QDnsLookup::NS) {
- status = local_dn_expand(response, response + responseLength, p, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid name server record");
- return;
- }
- QDnsDomainNameRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- record.d->value = QUrl::fromAce(answer);
- reply->nameServerRecords.append(record);
- } else if (type == QDnsLookup::PTR) {
- status = local_dn_expand(response, response + responseLength, p, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid pointer record");
- return;
- }
- QDnsDomainNameRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- record.d->value = QUrl::fromAce(answer);
- reply->pointerRecords.append(record);
- } else if (type == QDnsLookup::MX) {
- const quint16 preference = (p[0] << 8) | p[1];
- status = local_dn_expand(response, response + responseLength, p + 2, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid mail exchange record");
- return;
- }
- QDnsMailExchangeRecord record;
- record.d->exchange = QUrl::fromAce(answer);
- record.d->name = name;
- record.d->preference = preference;
- record.d->timeToLive = ttl;
- reply->mailExchangeRecords.append(record);
- } else if (type == QDnsLookup::SRV) {
- const quint16 priority = (p[0] << 8) | p[1];
- const quint16 weight = (p[2] << 8) | p[3];
- const quint16 port = (p[4] << 8) | p[5];
- status = local_dn_expand(response, response + responseLength, p + 6, answer, sizeof(answer));
- if (status < 0) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid service record");
- return;
- }
- QDnsServiceRecord record;
- record.d->name = name;
- record.d->target = QUrl::fromAce(answer);
- record.d->port = port;
- record.d->priority = priority;
- record.d->timeToLive = ttl;
- record.d->weight = weight;
- reply->serviceRecords.append(record);
- } else if (type == QDnsLookup::TXT) {
- unsigned char *txt = p;
- QDnsTextRecord record;
- record.d->name = name;
- record.d->timeToLive = ttl;
- while (txt < p + size) {
- const unsigned char length = *txt;
- txt++;
- if (txt + length > p + size) {
- reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid text record");
- return;
- }
- record.d->values << QByteArray((char*)txt, length);
- txt += length;
- }
- reply->textRecords.append(record);
- }
- p += size;
- answerIndex++;
- }
-}
-
-QT_END_NAMESPACE