diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2024-04-19 20:45:00 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-05-08 21:13:43 -0700 |
commit | 9724b039cac2cc309575ce5a030841939eeb1acd (patch) | |
tree | 235d2a2d574214742b2d3c1b18662c5050443df7 /tests | |
parent | fd6cfd22831c6ff7078bb97e62439375cfc849f6 (diff) |
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>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp | 55 | ||||
-rw-r--r-- | tests/manual/qdnslookup/main.cpp | 45 |
2 files changed, 83 insertions, 17 deletions
diff --git a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp index f71e94862c..2723caa3b8 100644 --- a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp +++ b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp @@ -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; diff --git a/tests/manual/qdnslookup/main.cpp b/tests/manual/qdnslookup/main.cpp index a07eac6d45..129c79bb44 100644 --- a/tests/manual/qdnslookup/main.cpp +++ b/tests/manual/qdnslookup/main.cpp @@ -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 |