summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/kernel/qdnslookup.cpp4
-rw-r--r--src/network/kernel/qdnslookup_android.cpp3
-rw-r--r--src/network/kernel/qdnslookup_p.h6
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp39
-rw-r--r--src/network/kernel/qdnslookup_win.cpp22
-rw-r--r--src/network/kernel/qdnslookup_winrt.cpp7
6 files changed, 72 insertions, 9 deletions
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index e776a8eb76..97a402901e 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -482,7 +482,7 @@ void QDnsLookup::lookup()
Q_D(QDnsLookup);
d->isFinished = false;
d->reply = QDnsLookupReply();
- d->runnable = new QDnsLookupRunnable(d->type, QUrl::toAce(d->name));
+ d->runnable = new QDnsLookupRunnable(d->type, QUrl::toAce(d->name), d->nameserver);
connect(d->runnable, SIGNAL(finished(QDnsLookupReply)),
this, SLOT(_q_lookupFinished(QDnsLookupReply)),
Qt::BlockingQueuedConnection);
@@ -990,7 +990,7 @@ void QDnsLookupRunnable::run()
}
// Perform request.
- query(requestType, requestName, &reply);
+ query(requestType, requestName, nameserver, &reply);
// Sort results.
if (!theDnsLookupSeedStorage()->hasLocalData()) {
diff --git a/src/network/kernel/qdnslookup_android.cpp b/src/network/kernel/qdnslookup_android.cpp
index dff81dba0c..1ace5727c2 100644
--- a/src/network/kernel/qdnslookup_android.cpp
+++ b/src/network/kernel/qdnslookup_android.cpp
@@ -43,10 +43,11 @@
QT_BEGIN_NAMESPACE
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
Q_UNUSED(requestType);
Q_UNUSED(requestName);
+ Q_UNUSED(nameserver);
Q_UNUSED(reply);
qWarning() << Q_FUNC_INFO << "Not yet supported on Android";
reply->error = QDnsLookup::ResolverError;
diff --git a/src/network/kernel/qdnslookup_p.h b/src/network/kernel/qdnslookup_p.h
index 4bd3bd7603..7c0b0e862a 100644
--- a/src/network/kernel/qdnslookup_p.h
+++ b/src/network/kernel/qdnslookup_p.h
@@ -112,9 +112,10 @@ class QDnsLookupRunnable : public QObject, public QRunnable
Q_OBJECT
public:
- QDnsLookupRunnable(QDnsLookup::Type type, const QByteArray &name)
+ QDnsLookupRunnable(QDnsLookup::Type type, const QByteArray &name, const QHostAddress &nameserver)
: requestType(type)
, requestName(name)
+ , nameserver(nameserver)
{ }
void run();
@@ -122,9 +123,10 @@ signals:
void finished(const QDnsLookupReply &reply);
private:
- static void query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply);
+ static void query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply);
QDnsLookup::Type requestType;
QByteArray requestName;
+ QHostAddress nameserver;
};
class QDnsLookupThreadPool : public QThreadPool
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 9fb488cee6..26834dff57 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -115,7 +115,7 @@ static void resolveLibrary()
local_res_nquery = res_nquery_proto(lib.resolve("res_nquery"));
}
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
// Load dn_expand, res_ninit and res_nquery on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false);
@@ -142,6 +142,43 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
reply->errorString = tr("Resolver initialization failed");
return;
}
+
+ //Check if a nameserver was set. If so, use it
+ if (!nameserver.isNull()) {
+ if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) {
+ state.nsaddr_list[0].sin_addr.s_addr = htonl(nameserver.toIPv4Address());
+ state.nscount = 1;
+ } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
+#if defined(Q_OS_LINUX)
+ struct sockaddr_in6 *ns;
+ ns = state._u._ext.nsaddrs[0];
+ // nsaddrs will be NULL if no nameserver is set in /etc/resolv.conf
+ if (!ns) {
+ // Memory allocated here will be free'd in res_close() as we
+ // have done res_init() above.
+ ns = (struct sockaddr_in6*) calloc(1, sizeof(struct sockaddr_in6));
+ Q_CHECK_PTR(ns);
+ state._u._ext.nsaddrs[0] = ns;
+ }
+ // Set nsmap[] to indicate that nsaddrs[0] is an IPv6 address
+ // See: https://sourceware.org/ml/libc-hacker/2002-05/msg00035.html
+ state._u._ext.nsmap[0] = MAXNS + 1;
+ state._u._ext.nscount6 = 1;
+ ns->sin6_family = AF_INET6;
+ ns->sin6_port = htons(53);
+
+ Q_IPV6ADDR ipv6Address = nameserver.toIPv6Address();
+ for (int i=0; i<16; i++) {
+ ns->sin6_addr.s6_addr[i] = ipv6Address[i];
+ }
+#else
+ qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
+ return;
+#endif
+ }
+ }
#ifdef QDNSLOOKUP_DEBUG
state.options |= RES_DEBUG;
#endif
diff --git a/src/network/kernel/qdnslookup_win.cpp b/src/network/kernel/qdnslookup_win.cpp
index bf80a23297..6f58e64440 100644
--- a/src/network/kernel/qdnslookup_win.cpp
+++ b/src/network/kernel/qdnslookup_win.cpp
@@ -48,15 +48,33 @@
#include <qt_windows.h>
#include <windns.h>
+#include <memory.h>
QT_BEGIN_NAMESPACE
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
// Perform DNS query.
PDNS_RECORD dns_records = 0;
const QString requestNameUtf16 = QString::fromUtf8(requestName.data(), requestName.size());
- const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, NULL, &dns_records, NULL);
+ IP4_ARRAY srvList;
+ memset(&srvList, 0, sizeof(IP4_ARRAY));
+ if (!nameserver.isNull()) {
+ if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) {
+ // The below code is referenced from: http://support.microsoft.com/kb/831226
+ srvList.AddrCount = 1;
+ srvList.AddrArray[0] = htonl(nameserver.toIPv4Address());
+ } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
+ // For supoprting IPv6 nameserver addresses, we'll need to switch
+ // from DnsQuey() to DnsQueryEx() as it supports passing an IPv6
+ // address in the nameserver list
+ qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
+ return;
+ }
+ }
+ const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, &srvList, &dns_records, NULL);
switch (status) {
case ERROR_SUCCESS:
break;
diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp
index a5d16e4b63..6ac944934a 100644
--- a/src/network/kernel/qdnslookup_winrt.cpp
+++ b/src/network/kernel/qdnslookup_winrt.cpp
@@ -42,6 +42,7 @@
#include "qdnslookup_p.h"
#include <qurl.h>
+#include <qdebug.h>
#include <wrl.h>
#include <windows.foundation.h>
@@ -59,8 +60,12 @@ using namespace ABI::Windows::Networking::Sockets;
QT_BEGIN_NAMESPACE
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
+ // TODO: Add nameserver support for winRT
+ if (!nameserver.isNull())
+ qWarning() << "Ignoring nameserver as its currently not supported on WinRT";
+
// TODO: is there any way to do "proper" dns lookup?
if (requestType != QDnsLookup::A && requestType != QDnsLookup::AAAA
&& requestType != QDnsLookup::ANY) {