Skip to content
/ qTox Public
forked from TokTok/qTox

Commit

Permalink
refactor: Use Qt's DNS lookup instead of toxcore's.
Browse files Browse the repository at this point in the history
This is in preparation for sending DNS lookups to tor-resolve.

Also prefer IPv6 if enabled.

Fixes TokTok#164.
  • Loading branch information
iphydf committed Jan 2, 2025
1 parent 3014906 commit bb7df89
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 20 deletions.
84 changes: 64 additions & 20 deletions src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDnsLookup>
#include <QRegularExpression>
#include <QString>
#include <QStringBuilder>
#include <QTimer>

#include <QtNetwork/qhostaddress.h>
#include <tox/tox.h>

#include <algorithm>
Expand Down Expand Up @@ -362,14 +366,36 @@ 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
*/
void Core::bootstrapDht()
{
ASSERT_CORE_THREAD;


const auto shuffledBootstrapNodes =
shuffleBootstrapNodes(bootstrapListGenerator.getBootstrapNodes());
if (shuffledBootstrapNodes.empty()) {
Expand All @@ -381,31 +407,49 @@ 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;
QDnsLookup::Type type;
if (!dhtServer.ipv6.isEmpty() && settings.getEnableIPv6()) {
address = dhtServer.ipv6;
type = QDnsLookup::AAAA;
} else if (!dhtServer.ipv4.isEmpty()) {
address = dhtServer.ipv4;
type = QDnsLookup::A;
} 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);
const auto hostAddress = address == QStringLiteral("localhost")
? QHostAddress(QHostAddress::LocalHost)
: QHostAddress(address);
if (!hostAddress.isNull()) {
bootstrapTo(dhtServer, hostAddress);
continue;
}

auto* dns = new QDnsLookup(this);
connect(dns, &QDnsLookup::finished, this, [this, dhtServer, dns]() {
const LaterDeleter deleter(dns);
if (dns->error() != QDnsLookup::NoError) {
qWarning() << "DNS lookup failed for" << dns->name() << "with error"
<< dns->errorString();
return;
}

const auto records = dns->hostAddressRecords();
if (records.isEmpty()) {
qWarning() << "No address records found for" << dns->name();
return;
}

bootstrapTo(dhtServer, records.first().value());
});

qDebug() << "Resolving" << address << "with type" << type;
dns->setType(type);
dns->setName(address);
dns->lookup();
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <functional>
#include <memory>

class QHostAddress;
class CoreAV;
class CoreFile;
class IAudioControl;
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/core/toxoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions util/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions util/include/util/laterdeleter.h
Original file line number Diff line number Diff line change
@@ -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();
};
17 changes: 17 additions & 0 deletions util/src/laterdeleter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2025 The TokTok team.
*/

#include "util/laterdeleter.h"

#include <QObject>

LaterDeleter::LaterDeleter(QObject* ptr_)
: ptr(ptr_)
{
}

LaterDeleter::~LaterDeleter()
{
ptr->deleteLater();
}

0 comments on commit bb7df89

Please sign in to comment.