QDnsLookup: add initial support for DNS-over-TLS (DoT)

This is just an empty shell for now. The implementation will come in the
next commit.

[ChangeLog][QtNetwork][QDnsLookup] The class now supports DNS-over-TLS
and some other DNSSEC experimental features, on some platforms. Use
QDnsLookup::isProtocolSupported to know if the protocol is supported on
a given platform.

Change-Id: I455fe22ef4ad4b2f9b01fffd17c7e034dee75533
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
Thiago Macieira 2024-04-19 20:45:00 -07:00
parent fd6cfd2283
commit 9724b039ca
9 changed files with 337 additions and 27 deletions

View File

@ -149,6 +149,11 @@
\title RFC 7252
*/
/*!
\externalpage https://datatracker.ietf.org/doc/html/rfc7858
\title RFC 7858
*/
/*!
\externalpage https://datatracker.ietf.org/doc/html/rfc8018#section-5.1
\title RFC 8018, section 5.1

View File

@ -58,6 +58,9 @@ QList<QNetworkCookie> QNetworkCookie::parseCookies(const QByteArray &cookieStrin
#if QT_NETWORK_REMOVED_SINCE(6, 8)
#if QT_CONFIG(dnslookup)
# include "qdnslookup.h" // inlined API
#endif
#include "qnetworkrequest.h" // inlined API
// #include "qotherheader.h"

View File

@ -159,6 +159,21 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
\note If you simply want to find the IP address(es) associated with a host
name, or the host name associated with an IP address you should use
QHostInfo instead.
\section1 DNS-over-TLS
QDnsLookup supports DNS-over-TLS (DoT, as specified by \l{RFC 7858}) on
some platforms. That currently includes all Unix platforms where regular
queries are supported, if \l QSslSocket support is present in Qt. To query
if support is present at runtime, use isProtocolSupported().
When using DNS-over-TLS, QDnsLookup only implements the "Opportunistic
Privacy Profile" method of authentication, as described in \l{RFC 7858}
section 4.1. In this mode, QDnsLookup (through \l QSslSocket) only
validates that the server presents a certificate that is valid for the
server being connected to. Clients may use setSslConfiguration() to impose
additional restrictions and sslConfiguration() to obtain information after
the query is complete.
*/
/*!
@ -216,6 +231,62 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
\value TXT text records.
*/
/*!
\enum QDnsLookup::Protocol
Indicates the type of DNS server that is being queried.
\value Standard
Regular, unencrypted DNS, using UDP and falling back to TCP as necessary
(default port: 53)
\value DnsOverTls
Encrypted DNS over TLS (DoT, as specified by \l{RFC 7858}), over TCP
(default port: 853)
\sa isProtocolSupported(), nameserverProtocol, setNameserver()
*/
/*!
\since 6.8
Returns true if DNS queries using \a protocol are supported with QDnsLookup.
\sa nameserverProtocol
*/
bool QDnsLookup::isProtocolSupported(Protocol protocol)
{
#if QT_CONFIG(libresolv) || defined(Q_OS_WIN)
switch (protocol) {
case QDnsLookup::Standard:
return true;
case QDnsLookup::DnsOverTls:
return false;
}
#else
Q_UNUSED(protocol)
#endif
return false;
}
/*!
\since 6.8
Returns the standard (default) port number for the protocol \a protocol.
\sa isProtocolSupported()
*/
quint16 QDnsLookup::defaultPortForProtocol(Protocol protocol) noexcept
{
switch (protocol) {
case QDnsLookup::Standard:
return DnsPort;
case QDnsLookup::DnsOverTls:
return DnsOverTlsPort;
}
return 0; // will probably fail somewhere
}
/*!
\fn void QDnsLookup::finished()
@ -270,7 +341,7 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent)
*/
QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent)
: QDnsLookup(type, name, nameserver, DnsPort, parent)
: QDnsLookup(type, name, nameserver, 0, parent)
{
}
@ -285,8 +356,9 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &names
//! [nameserver-port]
\note Setting the port number to any value other than the default (53) can
cause the name resolution to fail, depending on the operating system
limitations and firewalls. Notably, the Windows API used by QDnsLookup is
unable to handle alternate port numbers.
limitations and firewalls, if the nameserverProtocol() to be used
QDnsLookup::Standard. Notably, the Windows API used by QDnsLookup is unable
to handle alternate port numbers.
//! [nameserver-port]
*/
QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, quint16 port, QObject *parent)
@ -299,6 +371,30 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &names
d->nameserver = nameserver;
}
/*!
\since 6.8
Constructs a QDnsLookup object to issue a query for \a name of record type
\a type, using the DNS server \a nameserver running on port \a port, and
sets \a parent as the parent object.
The query will be sent using \a protocol, if supported. Use
isProtocolSupported() to check if it is supported.
\include qdnslookup.cpp nameserver-port
*/
QDnsLookup::QDnsLookup(Type type, const QString &name, Protocol protocol,
const QHostAddress &nameserver, quint16 port, QObject *parent)
: QObject(*new QDnsLookupPrivate, parent)
{
Q_D(QDnsLookup);
d->name = name;
d->type = type;
d->nameserver = nameserver;
d->port = port;
d->protocol = protocol;
}
/*!
Destroys the QDnsLookup object.
@ -416,6 +512,10 @@ QBindable<QHostAddress> QDnsLookup::bindableNameserver()
\property QDnsLookup::nameserverPort
\since 6.6
\brief the port number of nameserver to use for DNS lookup.
The value of 0 indicates that QDnsLookup should use the default port for
the nameserverProtocol().
\include qdnslookup.cpp nameserver-port
*/
@ -437,18 +537,44 @@ QBindable<quint16> QDnsLookup::bindableNameserverPort()
}
/*!
\property QDnsLookup::nameserverProtocol
\since 6.8
\brief the protocol to use when sending the DNS query
\sa isProtocolSupported()
*/
QDnsLookup::Protocol QDnsLookup::nameserverProtocol() const
{
return d_func()->protocol;
}
void QDnsLookup::setNameserverProtocol(Protocol protocol)
{
d_func()->protocol = protocol;
}
QBindable<QDnsLookup::Protocol> QDnsLookup::bindableNameserverProtocol()
{
return &d_func()->protocol;
}
/*!
\fn void QDnsLookup::setNameserver(const QHostAddress &nameserver, quint16 port)
\since 6.6
Sets the nameserver to \a nameserver and the port to \a port.
\include qdnslookup.cpp nameserver-port
\sa QDnsLookup::nameserver, QDnsLookup::nameserverPort
*/
void QDnsLookup::setNameserver(const QHostAddress &nameserver, quint16 port)
void QDnsLookup::setNameserver(Protocol protocol, const QHostAddress &nameserver, quint16 port)
{
Qt::beginPropertyUpdateGroup();
setNameserver(nameserver);
setNameserverPort(port);
setNameserverProtocol(protocol);
Qt::endPropertyUpdateGroup();
}
@ -523,6 +649,29 @@ QList<QDnsTextRecord> QDnsLookup::textRecords() const
return d_func()->reply.textRecords;
}
#if QT_CONFIG(ssl)
/*!
\since 6.8
Sets the \a sslConfiguration to use for outgoing DNS-over-TLS connections.
\sa sslConfiguration(), QSslSocket::setSslConfiguration()
*/
void QDnsLookup::setSslConfiguration(const QSslConfiguration &sslConfiguration)
{
Q_UNUSED(sslConfiguration)
}
/*!
Returns the current SSL configuration.
\sa setSslConfiguration()
*/
QSslConfiguration QDnsLookup::sslConfiguration() const
{
return {};
}
#endif
/*!
Aborts the DNS lookup operation.
@ -564,6 +713,9 @@ void QDnsLookup::lookup()
if (d->runnable == sender()) {
#ifdef QDNSLOOKUP_DEBUG
qDebug("DNS reply for %s: %i (%s)", qPrintable(d->name), reply.error, qPrintable(reply.errorString));
#endif
#if QT_CONFIG(ssl)
d->sslConfiguration = std::move(reply.sslConfiguration);
#endif
d->reply = reply;
d->runnable = nullptr;
@ -1070,8 +1222,14 @@ inline QDnsLookupRunnable::QDnsLookupRunnable(const QDnsLookupPrivate *d)
: requestName(encodeLabel(d->name)),
nameserver(d->nameserver),
requestType(d->type),
port(d->port)
port(d->port),
protocol(d->protocol)
{
if (port == 0)
port = QDnsLookup::defaultPortForProtocol(protocol);
#if QT_CONFIG(ssl)
sslConfiguration = d->sslConfiguration;
#endif
}
void QDnsLookupRunnable::run()
@ -1120,9 +1278,16 @@ inline QDebug operator<<(QDebug &d, QDnsLookupRunnable *r)
if (r->requestName.size() > MaxDomainNameLength)
d << "... (truncated)";
d << " type " << r->requestType;
if (!r->nameserver.isNull())
if (!r->nameserver.isNull()) {
d << " to nameserver " << qUtf16Printable(r->nameserver.toString())
<< " port " << (r->port ? r->port : DnsPort);
<< " port " << (r->port ? r->port : QDnsLookup::defaultPortForProtocol(r->protocol));
switch (r->protocol) {
case QDnsLookup::Standard:
break;
case QDnsLookup::DnsOverTls:
d << " (TLS)";
}
}
return d;
}

View File

@ -22,6 +22,7 @@ class QDnsHostAddressRecordPrivate;
class QDnsMailExchangeRecordPrivate;
class QDnsServiceRecordPrivate;
class QDnsTextRecordPrivate;
class QSslConfiguration;
class Q_NETWORK_EXPORT QDnsDomainNameRecord
{
@ -148,6 +149,8 @@ class Q_NETWORK_EXPORT QDnsLookup : public QObject
BINDABLE bindableNameserver)
Q_PROPERTY(quint16 nameserverPort READ nameserverPort WRITE setNameserverPort
NOTIFY nameserverPortChanged BINDABLE bindableNameserverPort)
Q_PROPERTY(Protocol nameserverProtocol READ nameserverProtocol WRITE setNameserverProtocol
NOTIFY nameserverProtocolChanged BINDABLE bindableNameserverProtocol)
public:
enum Error
@ -178,11 +181,19 @@ public:
};
Q_ENUM(Type)
enum Protocol : quint8 {
Standard = 0,
DnsOverTls,
};
Q_ENUM(Protocol)
explicit QDnsLookup(QObject *parent = nullptr);
QDnsLookup(Type type, const QString &name, QObject *parent = nullptr);
QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = nullptr);
QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, quint16 port,
QObject *parent = nullptr);
QDnsLookup(Type type, const QString &name, Protocol protocol, const QHostAddress &nameserver,
quint16 port = 0, QObject *parent = nullptr);
~QDnsLookup();
Error error() const;
@ -203,6 +214,11 @@ public:
quint16 nameserverPort() const;
void setNameserverPort(quint16 port);
QBindable<quint16> bindableNameserverPort();
Protocol nameserverProtocol() const;
void setNameserverProtocol(Protocol protocol);
QBindable<Protocol> bindableNameserverProtocol();
void setNameserver(Protocol protocol, const QHostAddress &nameserver, quint16 port = 0);
QT_NETWORK_INLINE_SINCE(6, 8)
void setNameserver(const QHostAddress &nameserver, quint16 port);
QList<QDnsDomainNameRecord> canonicalNameRecords() const;
@ -214,6 +230,14 @@ public:
QList<QDnsTextRecord> textRecords() const;
#if QT_CONFIG(ssl)
void setSslConfiguration(const QSslConfiguration &sslConfiguration);
QSslConfiguration sslConfiguration() const;
#endif
static bool isProtocolSupported(Protocol protocol);
static quint16 defaultPortForProtocol(Protocol protocol) noexcept Q_DECL_CONST_FUNCTION;
public Q_SLOTS:
void abort();
void lookup();
@ -224,11 +248,19 @@ Q_SIGNALS:
void typeChanged(Type type);
void nameserverChanged(const QHostAddress &nameserver);
void nameserverPortChanged(quint16 port);
void nameserverProtocolChanged(Protocol protocol);
private:
Q_DECLARE_PRIVATE(QDnsLookup)
};
#if QT_NETWORK_INLINE_IMPL_SINCE(6, 8)
void QDnsLookup::setNameserver(const QHostAddress &nameserver, quint16 port)
{
setNameserver(Standard, nameserver, port);
}
#endif
QT_END_NAMESPACE
#endif // QDNSLOOKUP_H

View File

@ -27,6 +27,10 @@
#include "private/qobject_p.h"
#include "private/qurl_p.h"
#if QT_CONFIG(ssl)
# include "qsslconfiguration.h"
#endif
QT_REQUIRE_CONFIG(dnslookup);
QT_BEGIN_NAMESPACE
@ -35,6 +39,7 @@ QT_BEGIN_NAMESPACE
constexpr qsizetype MaxDomainNameLength = 255;
constexpr quint16 DnsPort = 53;
constexpr quint16 DnsOverTlsPort = 853;
class QDnsLookupRunnable;
QDebug operator<<(QDebug &, QDnsLookupRunnable *);
@ -53,6 +58,10 @@ public:
QList<QDnsServiceRecord> serviceRecords;
QList<QDnsTextRecord> textRecords;
#if QT_CONFIG(ssl)
std::optional<QSslConfiguration> sslConfiguration;
#endif
// helper methods
void setError(QDnsLookup::Error err, QString &&msg)
{
@ -129,7 +138,8 @@ class QDnsLookupPrivate : public QObjectPrivate
public:
QDnsLookupPrivate()
: type(QDnsLookup::A)
, port(DnsPort)
, port(0)
, protocol(QDnsLookup::Standard)
{ }
void nameChanged()
@ -162,11 +172,22 @@ public:
Q_OBJECT_BINDABLE_PROPERTY(QDnsLookupPrivate, quint16,
port, &QDnsLookupPrivate::nameserverPortChanged);
void nameserverProtocolChanged()
{
emit q_func()->nameserverProtocolChanged(protocol);
}
Q_OBJECT_BINDABLE_PROPERTY(QDnsLookupPrivate, QDnsLookup::Protocol,
protocol, &QDnsLookupPrivate::nameserverProtocolChanged);
QDnsLookupReply reply;
QDnsLookupRunnable *runnable = nullptr;
bool isFinished = false;
#if QT_CONFIG(ssl)
std::optional<QSslConfiguration> sslConfiguration;
#endif
Q_DECLARE_PUBLIC(QDnsLookup)
};
@ -198,6 +219,11 @@ private:
QHostAddress nameserver;
QDnsLookup::Type requestType;
quint16 port;
QDnsLookup::Protocol protocol;
#if QT_CONFIG(ssl)
std::optional<QSslConfiguration> sslConfiguration;
#endif
friend QDebug operator<<(QDebug &, QDnsLookupRunnable *);
};

View File

@ -155,6 +155,10 @@ prepareQueryBuffer(res_state state, QueryBuffer &buffer, const char *label, ns_r
void QDnsLookupRunnable::query(QDnsLookupReply *reply)
{
if (protocol != QDnsLookup::Standard)
return reply->setError(QDnsLookup::ResolverError,
QDnsLookup::tr("DNS over TLS not implemented"));
// Initialize state.
std::remove_pointer_t<res_state> state = {};
if (res_ninit(&state) < 0) {

View File

@ -73,7 +73,7 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
request.QueryType = requestType;
request.QueryOptions = DNS_QUERY_STANDARD | DNS_QUERY_TREAT_AS_FQDN;
if (!nameserver.isNull()) {
if (protocol == QDnsLookup::Standard && !nameserver.isNull()) {
memset(dnsAddresses, 0, sizeof(dnsAddresses));
request.pDnsServerList = new (dnsAddresses) DNS_ADDR_ARRAY;
auto addr = new (request.pDnsServerList->AddrArray) DNS_ADDR[1];
@ -87,7 +87,16 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
DNS_QUERY_RESULT results = {};
results.Version = 1;
const DNS_STATUS status = DnsQueryEx(&request, &results, nullptr);
DNS_STATUS status = ERROR_INVALID_PARAMETER;
switch (protocol) {
case QDnsLookup::Standard:
status = DnsQueryEx(&request, &results, nullptr);
break;
case QDnsLookup::DnsOverTls:
return reply->setError(QDnsLookup::ResolverError,
QDnsLookup::tr("DNS over TLS not implemented"));
}
if (status >= DNS_ERROR_RCODE_FORMAT_ERROR && status <= DNS_ERROR_RCODE_LAST)
return reply->makeDnsRcodeError(status - DNS_ERROR_RCODE_FORMAT_ERROR + 1);
else if (status == ERROR_TIMEOUT)

View File

@ -37,8 +37,11 @@ class tst_QDnsLookup: public QObject
QStringList domainNameListAlternatives(const QString &input);
std::unique_ptr<QDnsLookup> lookupCommon(QDnsLookup::Type type, const QString &domain,
const QHostAddress &server = {}, quint16 port = 53);
const QHostAddress &server = {}, quint16 port = 0,
QDnsLookup::Protocol protocol = QDnsLookup::Standard);
QStringList formatReply(const QDnsLookup *lookup) const;
void setNameserver_helper(QDnsLookup::Protocol protocol);
public slots:
void initTestCase();
@ -57,6 +60,8 @@ private slots:
void setNameserverLoopback();
void setNameserver_data();
void setNameserver();
void dnsOverTls_data();
void dnsOverTls();
void bindingsAndProperties();
void automatedBindings();
};
@ -74,9 +79,11 @@ static const char preparedDnsQuery[] =
"\x00\x00\x06\x00\x01" // <root domain> IN SOA
;
static QList<QHostAddress> systemNameservers()
static QList<QHostAddress> systemNameservers(QDnsLookup::Protocol protocol)
{
QList<QHostAddress> result;
if (protocol != QDnsLookup::Standard)
return result;
#ifdef Q_OS_WIN
ULONG infosize = 0;
@ -113,7 +120,7 @@ static QList<QHostAddress> systemNameservers()
return result;
}
static QList<QHostAddress> globalPublicNameservers()
static QList<QHostAddress> globalPublicNameservers(QDnsLookup::Protocol proto)
{
const char *const candidates[] = {
// Google's dns.google
@ -129,6 +136,8 @@ static QList<QHostAddress> globalPublicNameservers()
};
QList<QHostAddress> result;
if (proto != QDnsLookup::Standard)
return result;
QRandomGenerator &rng = *QRandomGenerator::system();
for (auto name : candidates) {
// check the candidates for reachability
@ -221,9 +230,10 @@ QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input)
std::unique_ptr<QDnsLookup>
tst_QDnsLookup::lookupCommon(QDnsLookup::Type type, const QString &domain,
const QHostAddress &server, quint16 port)
const QHostAddress &server, quint16 port,
QDnsLookup::Protocol protocol)
{
auto lookup = std::make_unique<QDnsLookup>(type, domainName(domain), server, port);
auto lookup = std::make_unique<QDnsLookup>(type, domainName(domain), protocol, server, port);
QObject::connect(lookup.get(), &QDnsLookup::finished,
&QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
lookup->lookup();
@ -591,24 +601,34 @@ void tst_QDnsLookup::setNameserverLoopback()
QCOMPARE(lookup.error(), QDnsLookup::NotFoundError);
}
void tst_QDnsLookup::setNameserver_data()
template <QDnsLookup::Protocol Protocol>
static void setNameserver_data_helper(const QByteArray &protoName)
{
static QList<QHostAddress> servers = systemNameservers() + globalPublicNameservers();
if (!QDnsLookup::isProtocolSupported(Protocol))
QSKIP(protoName + " not supported");
static QList<QHostAddress> servers = systemNameservers(Protocol)
+ globalPublicNameservers(Protocol);
QTest::addColumn<QHostAddress>("server");
if (servers.isEmpty()) {
QSKIP("No reachable DNS servers were found");
QSKIP("No reachable " + protoName + " servers were found");
} else {
for (const QHostAddress &h : std::as_const(servers))
QTest::addRow("%s", qUtf8Printable(h.toString())) << h;
}
}
void tst_QDnsLookup::setNameserver()
void tst_QDnsLookup::setNameserver_data()
{
setNameserver_data_helper<QDnsLookup::Standard>("DNS");
}
void tst_QDnsLookup::setNameserver_helper(QDnsLookup::Protocol protocol)
{
QFETCH(QHostAddress, server);
std::unique_ptr<QDnsLookup> lookup =
lookupCommon(QDnsLookup::Type::A, "a-single", server);
lookupCommon(QDnsLookup::Type::A, "a-single", server, 0, protocol);
if (!lookup)
return;
QCOMPARE(lookup->error(), QDnsLookup::NoError);
@ -616,6 +636,21 @@ void tst_QDnsLookup::setNameserver()
QCOMPARE(result, "A 192.0.2.1");
}
void tst_QDnsLookup::setNameserver()
{
setNameserver_helper(QDnsLookup::Standard);
}
void tst_QDnsLookup::dnsOverTls_data()
{
setNameserver_data_helper<QDnsLookup::DnsOverTls>("DNS-over-TLS");
}
void tst_QDnsLookup::dnsOverTls()
{
setNameserver_helper(QDnsLookup::DnsOverTls);
}
void tst_QDnsLookup::bindingsAndProperties()
{
QDnsLookup lookup;

View File

@ -11,6 +11,11 @@
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QDnsLookup>
#if QT_CONFIG(ssl)
# include <QtNetwork/QSslCipher>
# include <QtNetwork/QSslConfiguration>
#endif
#include <stdlib.h>
#include <stdio.h>
@ -32,6 +37,12 @@ static QDnsLookup::Type typeFromString(QString str)
return QDnsLookup::Type(value);
}
template <typename Enum> [[maybe_unused]] static const char *enumToKey(Enum e)
{
QMetaEnum me = QMetaEnum::fromType<Enum>();
return me.valueToKey(int(e));
}
static int showHelp(const char *argv0, int exitcode)
{
// like dig
@ -43,7 +54,7 @@ static auto parseServerAddress(QString server)
{
struct R {
QHostAddress address;
int port = -1;
int port;
} r;
// let's use QUrl to help us
@ -52,7 +63,7 @@ static auto parseServerAddress(QString server)
if (!url.isValid() || !url.userInfo().isNull())
return r; // failed
r.port = url.port();
r.port = url.port(0);
r.address.setAddress(url.host());
if (r.address.isNull()) {
// try to resolve a hostname
@ -121,8 +132,21 @@ static void printResults(const QDnsLookup &lookup, QElapsedTimer::Duration durat
printAnswers(lookup);
printf("\n;; Query time: %lld ms\n", qint64(duration_cast<milliseconds>(duration).count()));
if (QHostAddress server = lookup.nameserver(); !server.isNull())
printf(";; SERVER: %s#%d\n", qPrintable(server.toString()), lookup.nameserverPort());
if (QHostAddress server = lookup.nameserver(); !server.isNull()) {
quint16 port = lookup.nameserverPort();
if (port == 0)
port = QDnsLookup::defaultPortForProtocol(lookup.nameserverProtocol());
printf(";; SERVER: %s#%d", qPrintable(server.toString()), port);
#if QT_CONFIG(ssl)
if (lookup.nameserverProtocol() != QDnsLookup::Standard) {
if (QSslConfiguration conf = lookup.sslConfiguration(); !conf.isNull()) {
printf(" (%s %s)", enumToKey(conf.sessionProtocol()),
qPrintable(conf.sessionCipher().name()));
}
}
#endif
puts("");
}
}
int main(int argc, char *argv[])
@ -130,6 +154,7 @@ int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
QDnsLookup::Type type = {};
QDnsLookup::Protocol protocol = QDnsLookup::Standard;
QString domain, server;
const QStringList args = QCoreApplication::arguments().sliced(1);
for (const QString &arg : args) {
@ -139,6 +164,14 @@ int main(int argc, char *argv[])
}
if (arg == u"-h")
return showHelp(argv[0], EXIT_SUCCESS);
if (arg == "+tls") {
protocol = QDnsLookup::DnsOverTls;
continue;
} else if (arg == "+notls") {
protocol = QDnsLookup::Standard;
continue;
}
if (domain.isNull()) {
domain = arg;
continue;
@ -170,9 +203,7 @@ int main(int argc, char *argv[])
argv[0], qPrintable(server));
return EXIT_FAILURE;
}
lookup.setNameserver(addr.address);
if (addr.port > 0)
lookup.setNameserverPort(addr.port);
lookup.setNameserver(protocol, addr.address, addr.port);
}
// execute the lookup