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

refactor(core): move Tox_Options handling to separate file

This commit is contained in:
sudden6 2018-06-26 08:48:52 +02:00
parent c7ca261679
commit 20ca6c84c8
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
4 changed files with 145 additions and 111 deletions

View File

@ -257,6 +257,8 @@ set(${PROJECT_NAME}_SOURCES
src/core/toxid.h
src/core/toxlogger.cpp
src/core/toxlogger.h
src/core/toxoptions.cpp
src/core/toxoptions.h
src/core/toxpk.cpp
src/core/toxpk.h
src/core/toxstring.cpp

View File

@ -22,8 +22,9 @@
#include "corefile.h"
#include "src/core/coreav.h"
#include "src/core/icoresettings.h"
#include "src/core/toxstring.h"
#include "src/core/toxlogger.h"
#include "src/core/toxoptions.h"
#include "src/core/toxstring.h"
#include "src/model/groupinvite.h"
#include "src/nexus.h"
#include "src/persistence/profile.h"
@ -41,8 +42,6 @@
const QString Core::TOX_EXT = ".tox";
QThread* Core::coreThread{nullptr};
static const int MAX_PROXY_ADDRESS_LENGTH = 255;
#define MAX_GROUP_MESSAGE_LEN 1024
Core::Core(QThread* CoreThread, Profile& profile, const ICoreSettings* const settings)
@ -114,117 +113,13 @@ CoreAV* Core::getAv()
return av;
}
namespace {
/**
* @brief The ToxOptionsWrapper class wraps the Tox_Options struct and the matching
* proxy address data. This is needed to ensure both have equal lifetime and
* are correctly deleted.
*/
class ToxOptionsWrapper
{
public:
ToxOptionsWrapper(Tox_Options *options, const QByteArray& proxyAddrData)
: options(options)
, proxyAddrData(proxyAddrData)
{}
~ToxOptionsWrapper() {
tox_options_free(options);
}
ToxOptionsWrapper (ToxOptionsWrapper && from) {
options = from.options;
proxyAddrData.swap(from.proxyAddrData);
from.options = nullptr;
from.proxyAddrData.clear();
}
operator Tox_Options* () {
return options;
}
const char* getProxyAddrData() const {
return proxyAddrData.constData();
}
private:
Tox_Options *options = nullptr;
QByteArray proxyAddrData;
};
/**
* @brief Initializes Tox_Options instance
* @param savedata Previously saved Tox data
* @return ToxOptionsWrapper instance initialized to create Tox instance
*/
ToxOptionsWrapper initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
{
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be
// disabled in options.
const bool enableIPv6 = s->getEnableIPv6();
const bool forceTCP = s->getForceTCP();
// LAN requiring UDP is a toxcore limitation, ideally wouldn't be related
const bool enableLanDiscovery = s->getEnableLanDiscovery() && !forceTCP;
ICoreSettings::ProxyType proxyType = s->getProxyType();
quint16 proxyPort = s->getProxyPort();
QString proxyAddr = s->getProxyAddr();
if (!enableLanDiscovery) {
qWarning() << "Core starting without LAN discovery. Peers can only be found through DHT.";
}
if (enableIPv6) {
qDebug() << "Core starting with IPv6 enabled";
} else if(enableLanDiscovery) {
qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly.";
}
ToxOptionsWrapper toxOptions = ToxOptionsWrapper(tox_options_new(nullptr), proxyAddr.toUtf8());
// register log first, to get messages as early as possible
tox_options_set_log_callback(toxOptions, ToxLogger::onLogMessage);
tox_options_set_ipv6_enabled(toxOptions, enableIPv6);
tox_options_set_udp_enabled(toxOptions, !forceTCP);
tox_options_set_local_discovery_enabled(toxOptions, enableLanDiscovery);
tox_options_set_start_port(toxOptions, 0);
tox_options_set_end_port(toxOptions, 0);
// No proxy by default
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_NONE);
tox_options_set_proxy_host(toxOptions, nullptr);
tox_options_set_proxy_port(toxOptions, 0);
tox_options_set_savedata_type(toxOptions, !savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE);
tox_options_set_savedata_data(toxOptions, reinterpret_cast<const uint8_t*>(savedata.data()), savedata.size());
if (proxyType != ICoreSettings::ProxyType::ptNone) {
if (proxyAddr.length() > MAX_PROXY_ADDRESS_LENGTH) {
qWarning() << "proxy address" << proxyAddr << "is too long";
} else if (!proxyAddr.isEmpty() && proxyPort > 0) {
qDebug() << "using proxy" << proxyAddr << ":" << proxyPort;
// protection against changings in TOX_PROXY_TYPE enum
if (proxyType == ICoreSettings::ProxyType::ptSOCKS5) {
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_SOCKS5);
} else if (proxyType == ICoreSettings::ProxyType::ptHTTP) {
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_HTTP);
}
tox_options_set_proxy_host(toxOptions, toxOptions.getProxyAddrData());
tox_options_set_proxy_port(toxOptions, proxyPort);
}
}
return toxOptions;
}
} // namespace
/**
* @brief Creates Tox instance from previously saved data
* @param savedata Previously saved Tox data - null, if new profile was created
*/
void Core::makeTox(QByteArray savedata)
{
ToxOptionsWrapper toxOptions = initToxOptions(savedata, s);
auto toxOptions = ToxOptions::makeToxOptions(savedata, s);
if (toxOptions == nullptr) {
qCritical() << "could not allocate Tox Options data structure";
emit failedToStart();
@ -232,7 +127,7 @@ void Core::makeTox(QByteArray savedata)
}
TOX_ERR_NEW tox_err;
tox = tox_new(toxOptions, &tox_err);
tox = tox_new(*toxOptions, &tox_err);
switch (tox_err) {
case TOX_ERR_NEW_OK:
@ -245,8 +140,8 @@ void Core::makeTox(QByteArray savedata)
case TOX_ERR_NEW_PORT_ALLOC:
if (s->getEnableIPv6()) {
tox_options_set_ipv6_enabled(toxOptions, false);
tox = tox_new(toxOptions, &tox_err);
tox_options_set_ipv6_enabled(*toxOptions, false);
tox = tox_new(*toxOptions, &tox_err);
if (tox_err == TOX_ERR_NEW_OK) {
qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery "
"may not work properly.";

109
src/core/toxoptions.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "toxoptions.h"
#include "src/core/icoresettings.h"
#include "src/core/toxlogger.h"
#include <QByteArray>
#include <QDebug>
// TODO(sudden6): replace this constant with the function from toxcore 0.2.3
static const int MAX_PROXY_ADDRESS_LENGTH = 255;
/**
* @brief The ToxOptions class wraps the Tox_Options struct and the matching
* proxy address data. This is needed to ensure both have equal lifetime and
* are correctly deleted.
*/
ToxOptions::ToxOptions(Tox_Options *options, const QByteArray &proxyAddrData)
: options(options)
, proxyAddrData(proxyAddrData)
{}
ToxOptions::~ToxOptions() {
tox_options_free(options);
}
ToxOptions::ToxOptions(ToxOptions &&from) {
options = from.options;
proxyAddrData.swap(from.proxyAddrData);
from.options = nullptr;
from.proxyAddrData.clear();
}
const char *ToxOptions::getProxyAddrData() const {
return proxyAddrData.constData();
}
ToxOptions::operator Tox_Options *() {
return options;
}
/**
* @brief Initializes a ToxOptions instance
* @param savedata Previously saved Tox data
* @return ToxOptions instance initialized to create Tox instance
*/
std::unique_ptr<ToxOptions> ToxOptions::makeToxOptions(const QByteArray& savedata, const ICoreSettings* s)
{
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be
// disabled in options.
const bool enableIPv6 = s->getEnableIPv6();
const bool forceTCP = s->getForceTCP();
// LAN requiring UDP is a toxcore limitation, ideally wouldn't be related
const bool enableLanDiscovery = s->getEnableLanDiscovery() && !forceTCP;
ICoreSettings::ProxyType proxyType = s->getProxyType();
quint16 proxyPort = s->getProxyPort();
QString proxyAddr = s->getProxyAddr();
if (!enableLanDiscovery) {
qWarning() << "Core starting without LAN discovery. Peers can only be found through DHT.";
}
if (enableIPv6) {
qDebug() << "Core starting with IPv6 enabled";
} else if(enableLanDiscovery) {
qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly.";
}
Tox_Options* tox_opts = tox_options_new(nullptr);
if(!tox_opts) {
return {};
}
auto toxOptions = std::unique_ptr<ToxOptions>(new ToxOptions(tox_opts, proxyAddr.toUtf8()));
// register log first, to get messages as early as possible
tox_options_set_log_callback(*toxOptions, ToxLogger::onLogMessage);
tox_options_set_ipv6_enabled(*toxOptions, enableIPv6);
tox_options_set_udp_enabled(*toxOptions, !forceTCP);
tox_options_set_local_discovery_enabled(*toxOptions, enableLanDiscovery);
tox_options_set_start_port(*toxOptions, 0);
tox_options_set_end_port(*toxOptions, 0);
// No proxy by default
tox_options_set_proxy_type(*toxOptions, TOX_PROXY_TYPE_NONE);
tox_options_set_proxy_host(*toxOptions, nullptr);
tox_options_set_proxy_port(*toxOptions, 0);
tox_options_set_savedata_type(*toxOptions, !savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE);
tox_options_set_savedata_data(*toxOptions, reinterpret_cast<const uint8_t*>(savedata.data()), savedata.size());
if (proxyType != ICoreSettings::ProxyType::ptNone) {
if (proxyAddr.length() > MAX_PROXY_ADDRESS_LENGTH) {
qWarning() << "proxy address" << proxyAddr << "is too long";
} else if (!proxyAddr.isEmpty() && proxyPort > 0) {
qDebug() << "using proxy" << proxyAddr << ":" << proxyPort;
// protection against changings in TOX_PROXY_TYPE enum
if (proxyType == ICoreSettings::ProxyType::ptSOCKS5) {
tox_options_set_proxy_type(*toxOptions, TOX_PROXY_TYPE_SOCKS5);
} else if (proxyType == ICoreSettings::ProxyType::ptHTTP) {
tox_options_set_proxy_type(*toxOptions, TOX_PROXY_TYPE_HTTP);
}
tox_options_set_proxy_host(*toxOptions, toxOptions->getProxyAddrData());
tox_options_set_proxy_port(*toxOptions, proxyPort);
}
}
return toxOptions;
}

28
src/core/toxoptions.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef TOXOPTIONS_H
#define TOXOPTIONS_H
#include <QByteArray>
#include <memory>
class ICoreSettings;
struct Tox_Options;
class ToxOptions
{
public:
~ToxOptions();
ToxOptions (ToxOptions && from);
operator Tox_Options* ();
const char* getProxyAddrData() const;
static std::unique_ptr<ToxOptions> makeToxOptions(const QByteArray &savedata, const ICoreSettings *s);
private:
ToxOptions(Tox_Options *options, const QByteArray& proxyAddrData);
private:
Tox_Options *options = nullptr;
QByteArray proxyAddrData;
};
#endif // TOXOPTIONS_H