diff --git a/src/base/bittorrent/peerinfo.cpp b/src/base/bittorrent/peerinfo.cpp index 9fb6db21a4c..8b07f50f4f2 100644 --- a/src/base/bittorrent/peerinfo.cpp +++ b/src/base/bittorrent/peerinfo.cpp @@ -30,8 +30,10 @@ #include +#include "base/algorithm.h" #include "base/bittorrent/ltqbitarray.h" #include "base/net/geoipmanager.h" +#include "base/settingvalue.h" #include "base/unicodestrings.h" #include "base/utils/bytearray.h" #include "peeraddress.h" @@ -117,6 +119,19 @@ bool PeerInfo::isSeed() const return static_cast(m_nativeInfo.flags & lt::peer_info::seed); } +bool PeerInfo::isShadowBanned() const +{ + if (!CachedSettingValue(u"BitTorrent/Session/ShadowBan"_s, false)) + { + return false; + } + QString peer_ip = address().ip.toString(); + QStringList shadowbannedIPs = + CachedSettingValue(u"State/ShadowBannedIPs"_s, QStringList(), Algorithm::sorted).get(); + + return shadowbannedIPs.contains(peer_ip); +} + bool PeerInfo::optimisticUnchoke() const { return static_cast(m_nativeInfo.flags & lt::peer_info::optimistic_unchoke); diff --git a/src/base/bittorrent/peerinfo.h b/src/base/bittorrent/peerinfo.h index 86f3c0c7adb..a76f1593b87 100644 --- a/src/base/bittorrent/peerinfo.h +++ b/src/base/bittorrent/peerinfo.h @@ -62,6 +62,8 @@ namespace BitTorrent bool isOnParole() const; bool isSeed() const; + bool isShadowBanned() const; + bool optimisticUnchoke() const; bool isSnubbed() const; bool isUploadOnly() const; diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 82a4c8899f5..7d628f6345c 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -459,6 +459,7 @@ namespace BitTorrent virtual void setMaxRatioAction(MaxRatioAction act) = 0; virtual void banIP(const QString &ip) = 0; + virtual void shadowbanIP(const QString &ip) = 0; virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0; virtual bool addTorrent(const QString &source, const AddTorrentParams ¶ms = {}) = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index dfed6ccbdeb..51255491872 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -2485,6 +2485,23 @@ void SessionImpl::banIP(const QString &ip) m_bannedIPs = bannedIPs; } +void SessionImpl::shadowbanIP(const QString &ip) +{ + if (m_shadowBannedIPs.get().contains(ip)) + return; + + lt::error_code ec; + lt::make_address(ip.toLatin1().constData(), ec); // Only check IP valid. + Q_ASSERT(!ec); + if (ec) + return; + + QStringList shadowBannedIPs = m_shadowBannedIPs; + shadowBannedIPs.append(ip); + shadowBannedIPs.sort(); + m_shadowBannedIPs = shadowBannedIPs; +} + // Delete a torrent from the session, given its hash // and from the disk, if the corresponding deleteOption is chosen bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption) diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index e0e0880ed53..a4d22bbdd30 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -417,6 +417,7 @@ namespace BitTorrent void setMaxRatioAction(MaxRatioAction act) override; void banIP(const QString &ip) override; + void shadowbanIP(const QString &ip) override; bool isKnownTorrent(const InfoHash &infoHash) const override; bool addTorrent(const QString &source, const AddTorrentParams ¶ms = {}) override; diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index e484b213ed1..9aaf09d2bc6 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -76,6 +76,7 @@ namespace const QString KEY_PEER_PORT = u"port"_s; const QString KEY_PEER_PROGRESS = u"progress"_s; const QString KEY_PEER_RELEVANCE = u"relevance"_s; + const QString KEY_PEER_SHADOWBANNED = u"shadowbanned"_s; const QString KEY_PEER_TOT_DOWN = u"downloaded"_s; const QString KEY_PEER_TOT_UP = u"uploaded"_s; const QString KEY_PEER_UP_SPEED = u"up_speed"_s; @@ -754,7 +755,8 @@ void SyncController::torrentPeersAction() {KEY_PEER_CONNECTION_TYPE, pi.connectionType()}, {KEY_PEER_FLAGS, pi.flags()}, {KEY_PEER_FLAGS_DESCRIPTION, pi.flagsDescription()}, - {KEY_PEER_RELEVANCE, pi.relevance()} + {KEY_PEER_RELEVANCE, pi.relevance()}, + {KEY_PEER_SHADOWBANNED, pi.isShadowBanned()} }; if (torrent->hasMetadata()) diff --git a/src/webui/api/transfercontroller.cpp b/src/webui/api/transfercontroller.cpp index 11580427056..3be1f0d6104 100644 --- a/src/webui/api/transfercontroller.cpp +++ b/src/webui/api/transfercontroller.cpp @@ -143,3 +143,16 @@ void TransferController::banPeersAction() BitTorrent::Session::instance()->banIP(addr.ip.toString()); } } + +void TransferController::shadowbanPeersAction() +{ + requireParams({u"peers"_s}); + + const QStringList peers = params()[u"peers"_s].split(u'|'); + for (const QString &peer : peers) + { + const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed()); + if (!addr.ip.isNull()) + BitTorrent::Session::instance()->shadowbanIP(addr.ip.toString()); + } +} diff --git a/src/webui/api/transfercontroller.h b/src/webui/api/transfercontroller.h index fe7a0169531..f2d15123fbe 100644 --- a/src/webui/api/transfercontroller.h +++ b/src/webui/api/transfercontroller.h @@ -48,4 +48,5 @@ private slots: void setUploadLimitAction(); void setDownloadLimitAction(); void banPeersAction(); + void shadowbanPeersAction(); };