From 73454d93b787443b257d21e4696e6a253e8fa1cd Mon Sep 17 00:00:00 2001 From: iphydf Date: Wed, 1 Jan 2025 23:36:27 +0000 Subject: [PATCH] refactor: Use Qt's DNS lookup instead of toxcore's. This is in preparation for sending DNS lookups to tor-resolve. Also prefer IPv6 if enabled. Fixes #164. --- src/core/core.cpp | 58 +++++++++++++++++++++----------- src/core/core.h | 2 ++ src/core/toxoptions.cpp | 4 +++ src/net/updatecheck.cpp | 7 ++-- util/CMakeLists.txt | 2 ++ util/include/util/laterdeleter.h | 15 +++++++++ util/src/laterdeleter.cpp | 17 ++++++++++ 7 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 util/include/util/laterdeleter.h create mode 100644 util/src/laterdeleter.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 7d8a39d5ba..28aee3dbfa 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -17,16 +17,20 @@ #include "src/model/ibootstraplistgenerator.h" #include "src/model/status.h" #include "src/persistence/profile.h" +#include "util/laterdeleter.h" #include "util/strongtype.h" #include "util/toxcoreerrorparser.h" #include #include +#include +#include #include #include #include #include +#include #include #include @@ -362,6 +366,29 @@ bool Core::checkConnection() return toxConnected; } +void Core::bootstrapTo(const DhtServer& dhtServer, const QHostAddress& address) +{ + ASSERT_CORE_THREAD; + + const auto& ip = address.toString().toUtf8(); + + ToxPk pk{dhtServer.publicKey}; + qDebug() << "Connecting to bootstrap node" << pk.toString() << "at" << ip; + const uint8_t* pkPtr = pk.getData(); + + Tox_Err_Bootstrap error; + if (dhtServer.statusUdp) { + tox_bootstrap(tox.get(), ip.constData(), dhtServer.udpPort, pkPtr, &error); + PARSE_ERR(error); + } + if (dhtServer.statusTcp) { + const auto ports = dhtServer.tcpPorts.size(); + const auto tcpPort = dhtServer.tcpPorts[rand() % ports]; + tox_add_tcp_relay(tox.get(), ip.constData(), tcpPort, pkPtr, &error); + PARSE_ERR(error); + } +} + /** * @brief Connects us to the Tox network */ @@ -369,7 +396,6 @@ void Core::bootstrapDht() { ASSERT_CORE_THREAD; - const auto shuffledBootstrapNodes = shuffleBootstrapNodes(bootstrapListGenerator.getBootstrapNodes()); if (shuffledBootstrapNodes.empty()) { @@ -381,31 +407,23 @@ void Core::bootstrapDht() auto numNewNodes = 2; for (int i = 0; i < numNewNodes && i < shuffledBootstrapNodes.size(); ++i) { const auto& dhtServer = shuffledBootstrapNodes.at(i); - QByteArray address; - if (!dhtServer.ipv4.isEmpty()) { - address = dhtServer.ipv4.toLatin1(); - } else if (!dhtServer.ipv6.isEmpty() && settings.getEnableIPv6()) { - address = dhtServer.ipv6.toLatin1(); + QString address; + if (!dhtServer.ipv6.isEmpty() && settings.getEnableIPv6()) { + address = dhtServer.ipv6; + } else if (!dhtServer.ipv4.isEmpty()) { + address = dhtServer.ipv4; } else { ++numNewNodes; continue; } - ToxPk pk{dhtServer.publicKey}; - qDebug() << "Connecting to bootstrap node" << pk.toString(); - const uint8_t* pkPtr = pk.getData(); - - Tox_Err_Bootstrap error; - if (dhtServer.statusUdp) { - tox_bootstrap(tox.get(), address.constData(), dhtServer.udpPort, pkPtr, &error); - PARSE_ERR(error); - } - if (dhtServer.statusTcp) { - const auto ports = dhtServer.tcpPorts.size(); - const auto tcpPort = dhtServer.tcpPorts[rand() % ports]; - tox_add_tcp_relay(tox.get(), address.constData(), tcpPort, pkPtr, &error); - PARSE_ERR(error); + QHostInfo hostInfo = QHostInfo::fromName(address); + if (hostInfo.error() != QHostInfo::NoError) { + qWarning() << "Failed to resolve" << address << "address:" << hostInfo.errorString(); + return; } + + bootstrapTo(dhtServer, hostInfo.addresses().first()); } } diff --git a/src/core/core.h b/src/core/core.h index 860009ad7d..51c5c6c07b 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -28,6 +28,7 @@ #include #include +class QHostAddress; class CoreAV; class CoreFile; class IAudioControl; @@ -220,6 +221,7 @@ public slots: void makeTox(QByteArray savedata, ICoreSettings* s); void loadFriends(); void loadConferences(); + void bootstrapTo(const DhtServer& dhtServer, const QHostAddress& address); void bootstrapDht(); void checkLastOnline(uint32_t friendId); diff --git a/src/core/toxoptions.cpp b/src/core/toxoptions.cpp index ef43503b5a..307fd20569 100644 --- a/src/core/toxoptions.cpp +++ b/src/core/toxoptions.cpp @@ -24,6 +24,10 @@ ToxOptions::ToxOptions(Tox_Options* options_, const QByteArray& proxyAddrData_) : options(options_) , proxyAddrData(proxyAddrData_) { + assert(options != nullptr); +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 21) + tox_options_set_experimental_disable_dns(options_, true); +#endif } ToxOptions::~ToxOptions() diff --git a/src/net/updatecheck.cpp b/src/net/updatecheck.cpp index cc6da83f5f..f432a338af 100644 --- a/src/net/updatecheck.cpp +++ b/src/net/updatecheck.cpp @@ -6,6 +6,7 @@ #include "src/persistence/settings.h" #include "src/version.h" +#include "util/laterdeleter.h" #include #include @@ -131,11 +132,12 @@ void UpdateCheck::handleResponse(QNetworkReply* reply) return; } + const LaterDeleter replyDeleter(reply); + #ifdef UPDATE_CHECK_ENABLED if (reply->error() != QNetworkReply::NoError) { qWarning() << "Failed to check for update:" << reply->error(); emit updateCheckFailed(); - reply->deleteLater(); return; } const QByteArray result = reply->readAll(); @@ -146,7 +148,6 @@ void UpdateCheck::handleResponse(QNetworkReply* reply) if (latestVersion.isEmpty()) { qWarning() << "No tag name found in response:"; emit updateCheckFailed(); - reply->deleteLater(); return; } @@ -161,7 +162,5 @@ void UpdateCheck::handleResponse(QNetworkReply* reply) qInfo() << "qTox is up to date"; emit upToDate(); } - - reply->deleteLater(); #endif } diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index dc0bb34003..d8620a18e8 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -8,6 +8,8 @@ add_library( util_library STATIC include/util/algorithm.h src/algorithm.cpp + include/util/laterdeleter.h + src/laterdeleter.cpp include/util/interface.h include/util/ranges.h src/ranges.cpp diff --git a/util/include/util/laterdeleter.h b/util/include/util/laterdeleter.h new file mode 100644 index 0000000000..ea2aede326 --- /dev/null +++ b/util/include/util/laterdeleter.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2025 The TokTok team. + */ + +#pragma once + +class QObject; + +struct LaterDeleter +{ + QObject* ptr; + + explicit LaterDeleter(QObject* ptr_); + ~LaterDeleter(); +}; diff --git a/util/src/laterdeleter.cpp b/util/src/laterdeleter.cpp new file mode 100644 index 0000000000..937174f938 --- /dev/null +++ b/util/src/laterdeleter.cpp @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2025 The TokTok team. + */ + +#include "util/laterdeleter.h" + +#include + +LaterDeleter::LaterDeleter(QObject* ptr_) + : ptr(ptr_) +{ +} + +LaterDeleter::~LaterDeleter() +{ + ptr->deleteLater(); +}