1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

fix(core): Use node's TCP ports when connecting to TCP relay

Allows connecting to TCP relays that aren't acting as bootstrap nodes, and
connecting to TCP relays that have different or additional TCP ports compared
to UDP ports.
This commit is contained in:
Anthony Bilinski 2022-02-15 14:22:45 -08:00
parent 3d36cf47e8
commit e7e30ada8c
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
4 changed files with 40 additions and 11 deletions

View File

@ -846,7 +846,9 @@ void Core::bootstrapDht()
PARSE_ERR(error);
}
if (dhtServer.statusTcp) {
tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.udpPort, pkPtr, &error);
const auto ports = dhtServer.tcpPorts.size();
const auto tcpPort = rand() % ports;
tox_add_tcp_relay(tox.get(), address.constData(), tcpPort, pkPtr, &error);
PARSE_ERR(error);
}

View File

@ -33,7 +33,8 @@ bool DhtServer::operator==(const DhtServer& other) const
&& ipv6 == other.ipv6
&& maintainer == other.maintainer
&& userId == other.userId
&& udpPort == other.udpPort);
&& udpPort == other.udpPort
&& tcpPorts == other.tcpPorts);
}
/**

View File

@ -20,6 +20,7 @@
#pragma once
#include <QString>
#include <vector>
struct DhtServer
{
@ -30,6 +31,7 @@ struct DhtServer
QString maintainer;
QString userId;
quint16 udpPort;
std::vector<uint16_t> tcpPorts;
bool operator==(const DhtServer& other) const;
bool operator!=(const DhtServer& other) const;

View File

@ -29,6 +29,9 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QRegularExpression>
#include <QJsonArray>
#include <cstdint>
namespace NodeFields {
const QLatin1String status_udp{"status_udp"};
@ -38,9 +41,8 @@ const QLatin1String ipv6{"ipv6"};
const QLatin1String public_key{"public_key"};
const QLatin1String udp_port{"port"};
const QLatin1String maintainer{"maintainer"};
// TODO(sudden6): make use of this field once we differentiate between TCP nodes, and bootstrap nodes
const QLatin1String tcp_ports{"tcp_ports"};
const QStringList neededFields{status_udp, status_tcp, ipv4, ipv6, public_key, udp_port, maintainer};
const QStringList neededFields{status_udp, status_tcp, ipv4, ipv6, public_key, udp_port, tcp_ports, maintainer};
} // namespace NodeFields
namespace {
@ -63,13 +65,22 @@ void jsonNodeToDhtServer(const QJsonObject& node, QList<DhtServer>& outList)
return;
}
// only use nodes that provide at least UDP connection
if (!node[NodeFields::status_udp].toBool(false)) {
return;
}
const QString public_key = node[NodeFields::public_key].toString({});
const auto udp_port = node[NodeFields::udp_port].toInt(-1);
const auto status_udp = node[NodeFields::status_udp].toBool(false);
const auto status_tcp = node[NodeFields::status_tcp].toBool(false);
const QString maintainer = node[NodeFields::maintainer].toString({});
std::vector<uint16_t> tcp_ports;
const auto jsonTcpPorts = node[NodeFields::tcp_ports].toArray();
for (int i = 0; i < jsonTcpPorts.count(); ++i) {
const auto port = jsonTcpPorts.at(i).toInt();
if (port < 1 || port > std::numeric_limits<uint16_t>::max()) {
qDebug () << "Invalid TCP port in nodes list:" << port;
return;
}
tcp_ports.emplace_back(static_cast<uint16_t>(port));
}
// nodes.tox.chat doesn't use empty strings for empty addresses
QString ipv6_address = node[NodeFields::ipv6].toString({});
@ -86,7 +97,13 @@ void jsonNodeToDhtServer(const QJsonObject& node, QList<DhtServer>& outList)
qWarning() << "Both ipv4 and ipv4 addresses are empty for" << public_key;
}
const QString maintainer = node[NodeFields::maintainer].toString({});
if (status_udp && udp_port == -1) {
qWarning() << "UDP enabled but no UDP port for" << public_key;
}
if (status_tcp && tcp_ports.empty()) {
qWarning() << "TCP enabled but no TCP ports for:" << public_key;
}
if (udp_port < 1 || udp_port > std::numeric_limits<uint16_t>::max()) {
qDebug() << "Invalid port in nodes list:" << udp_port;
@ -101,7 +118,8 @@ void jsonNodeToDhtServer(const QJsonObject& node, QList<DhtServer>& outList)
DhtServer server;
server.statusUdp = true;
server.statusTcp = node[NodeFields::status_udp].toBool(false);
server.statusTcp = status_tcp;
server.tcpPorts = tcp_ports;
server.userId = public_key;
server.udpPort = udp_port_u16;
server.maintainer = maintainer;
@ -167,6 +185,12 @@ QByteArray serialize(QList<DhtServer> nodes)
nodeJson.insert(NodeFields::public_key, node.userId);
nodeJson.insert(NodeFields::udp_port, node.udpPort);
nodeJson.insert(NodeFields::maintainer, node.maintainer);
QJsonArray tcp_ports;
for (size_t i = 0; i < node.tcpPorts.size(); ++i) {
tcp_ports.push_back(node.tcpPorts.at(i));
}
nodeJson.insert(NodeFields::tcp_ports, tcp_ports);
jsonNodes.append(nodeJson);
}
QJsonObject rootObj;