|
|
@ -1,6 +1,6 @@ |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Bittorrent Client using Qt and libtorrent. |
|
|
|
* Bittorrent Client using Qt and libtorrent. |
|
|
|
* Copyright (C) 2019 Vladimir Golovnev <glassez@yandex.ru> |
|
|
|
* Copyright (C) 2019-2022 Vladimir Golovnev <glassez@yandex.ru> |
|
|
|
* |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or |
|
|
|
* This program is free software; you can redistribute it and/or |
|
|
|
* modify it under the terms of the GNU General Public License |
|
|
|
* modify it under the terms of the GNU General Public License |
|
|
@ -28,13 +28,12 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "portforwarderimpl.h" |
|
|
|
#include "portforwarderimpl.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <libtorrent/session.hpp> |
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
|
|
#include "base/algorithm.h" |
|
|
|
#include "base/bittorrent/sessionimpl.h" |
|
|
|
#include "base/logger.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent) |
|
|
|
PortForwarderImpl::PortForwarderImpl(BitTorrent::SessionImpl *provider, QObject *parent) |
|
|
|
: Net::PortForwarder {parent} |
|
|
|
: Net::PortForwarder(parent) |
|
|
|
, m_storeActive {u"Network/PortForwardingEnabled"_qs, true} |
|
|
|
, m_storeActive {u"Network/PortForwardingEnabled"_qs, true} |
|
|
|
, m_provider {provider} |
|
|
|
, m_provider {provider} |
|
|
|
{ |
|
|
|
{ |
|
|
@ -66,38 +65,13 @@ void PortForwarderImpl::setEnabled(const bool enabled) |
|
|
|
|
|
|
|
|
|
|
|
void PortForwarderImpl::setPorts(const QString &profile, QSet<quint16> ports) |
|
|
|
void PortForwarderImpl::setPorts(const QString &profile, QSet<quint16> ports) |
|
|
|
{ |
|
|
|
{ |
|
|
|
PortMapping &portMapping = m_portProfiles[profile]; |
|
|
|
const QSet<quint16> oldForwardedPorts = std::accumulate(m_portProfiles.cbegin(), m_portProfiles.cend(), QSet<quint16>()); |
|
|
|
Algorithm::removeIf(portMapping, [this, &ports](const quint16 port, const std::vector<lt::port_mapping_t> &handles) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// keep existing forwardings
|
|
|
|
|
|
|
|
const bool isAlreadyMapped = ports.remove(port); |
|
|
|
|
|
|
|
if (isAlreadyMapped) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove outdated forwardings
|
|
|
|
|
|
|
|
for (const lt::port_mapping_t &handle : handles) |
|
|
|
|
|
|
|
m_provider->delete_port_mapping(handle); |
|
|
|
|
|
|
|
m_forwardedPorts.remove(port); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// add new forwardings
|
|
|
|
|
|
|
|
for (const quint16 port : ports) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// port already forwarded/taken by other profile, don't do anything
|
|
|
|
|
|
|
|
if (m_forwardedPorts.contains(port)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isEnabled()) |
|
|
|
m_portProfiles[profile] = ports; |
|
|
|
portMapping.insert(port, m_provider->add_port_mapping(lt::session::tcp, port, port)); |
|
|
|
const QSet<quint16> newForwardedPorts = std::accumulate(m_portProfiles.cbegin(), m_portProfiles.cend(), QSet<quint16>()); |
|
|
|
else |
|
|
|
|
|
|
|
portMapping.insert(port, {}); |
|
|
|
|
|
|
|
m_forwardedPorts.insert(port); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (portMapping.isEmpty()) |
|
|
|
m_provider->removeMappedPorts(oldForwardedPorts - newForwardedPorts); |
|
|
|
m_portProfiles.remove(profile); |
|
|
|
m_provider->addMappedPorts(newForwardedPorts - oldForwardedPorts); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void PortForwarderImpl::removePorts(const QString &profile) |
|
|
|
void PortForwarderImpl::removePorts(const QString &profile) |
|
|
@ -107,40 +81,12 @@ void PortForwarderImpl::removePorts(const QString &profile) |
|
|
|
|
|
|
|
|
|
|
|
void PortForwarderImpl::start() |
|
|
|
void PortForwarderImpl::start() |
|
|
|
{ |
|
|
|
{ |
|
|
|
lt::settings_pack settingsPack; |
|
|
|
m_provider->enablePortMapping(); |
|
|
|
settingsPack.set_bool(lt::settings_pack::enable_upnp, true); |
|
|
|
for (const QSet<quint16> &ports : asConst(m_portProfiles)) |
|
|
|
settingsPack.set_bool(lt::settings_pack::enable_natpmp, true); |
|
|
|
m_provider->addMappedPorts(ports); |
|
|
|
m_provider->apply_settings(std::move(settingsPack)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto profileIter = m_portProfiles.begin(); profileIter != m_portProfiles.end(); ++profileIter) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
PortMapping &portMapping = profileIter.value(); |
|
|
|
|
|
|
|
for (auto iter = portMapping.begin(); iter != portMapping.end(); ++iter) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Q_ASSERT(iter.value().empty()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const quint16 port = iter.key(); |
|
|
|
|
|
|
|
iter.value() = m_provider->add_port_mapping(lt::session::tcp, port, port); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LogMsg(tr("UPnP/NAT-PMP support: ON"), Log::INFO); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void PortForwarderImpl::stop() |
|
|
|
void PortForwarderImpl::stop() |
|
|
|
{ |
|
|
|
{ |
|
|
|
lt::settings_pack settingsPack; |
|
|
|
m_provider->disablePortMapping(); |
|
|
|
settingsPack.set_bool(lt::settings_pack::enable_upnp, false); |
|
|
|
|
|
|
|
settingsPack.set_bool(lt::settings_pack::enable_natpmp, false); |
|
|
|
|
|
|
|
m_provider->apply_settings(std::move(settingsPack)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// don't clear m_portProfiles so a later `start()` call can restore the port forwardings
|
|
|
|
|
|
|
|
for (auto profileIter = m_portProfiles.begin(); profileIter != m_portProfiles.end(); ++profileIter) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
PortMapping &portMapping = profileIter.value(); |
|
|
|
|
|
|
|
for (auto iter = portMapping.begin(); iter != portMapping.end(); ++iter) |
|
|
|
|
|
|
|
iter.value().clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LogMsg(tr("UPnP/NAT-PMP support: OFF"), Log::INFO); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|