mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
net: move BanMan to its own files
This commit is contained in:
parent
d0469b2e93
commit
af3503d903
13 changed files with 276 additions and 237 deletions
|
@ -96,6 +96,7 @@ BITCOIN_CORE_H = \
|
||||||
addrdb.h \
|
addrdb.h \
|
||||||
addrman.h \
|
addrman.h \
|
||||||
attributes.h \
|
attributes.h \
|
||||||
|
banman.h \
|
||||||
base58.h \
|
base58.h \
|
||||||
bech32.h \
|
bech32.h \
|
||||||
bloom.h \
|
bloom.h \
|
||||||
|
@ -225,6 +226,7 @@ libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
libbitcoin_server_a_SOURCES = \
|
libbitcoin_server_a_SOURCES = \
|
||||||
addrdb.cpp \
|
addrdb.cpp \
|
||||||
addrman.cpp \
|
addrman.cpp \
|
||||||
|
banman.cpp \
|
||||||
bloom.cpp \
|
bloom.cpp \
|
||||||
blockencodings.cpp \
|
blockencodings.cpp \
|
||||||
blockfilter.cpp \
|
blockfilter.cpp \
|
||||||
|
|
195
src/banman.cpp
Normal file
195
src/banman.cpp
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
|
|
||||||
|
#include <netaddress.h>
|
||||||
|
#include <ui_interface.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
#include <util/time.h>
|
||||||
|
|
||||||
|
|
||||||
|
BanMan::BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time)
|
||||||
|
: clientInterface(client_interface), m_ban_db(std::move(ban_file)), m_default_ban_time(default_ban_time)
|
||||||
|
{
|
||||||
|
if (clientInterface) clientInterface->InitMessage(_("Loading banlist..."));
|
||||||
|
|
||||||
|
int64_t nStart = GetTimeMillis();
|
||||||
|
setBannedIsDirty = false;
|
||||||
|
banmap_t banmap;
|
||||||
|
if (m_ban_db.Read(banmap)) {
|
||||||
|
SetBanned(banmap); // thread save setter
|
||||||
|
SetBannedSetDirty(false); // no need to write down, just read data
|
||||||
|
SweepBanned(); // sweep out unused entries
|
||||||
|
|
||||||
|
LogPrint(BCLog::NET, "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
|
||||||
|
banmap.size(), GetTimeMillis() - nStart);
|
||||||
|
} else {
|
||||||
|
LogPrintf("Invalid or missing banlist.dat; recreating\n");
|
||||||
|
SetBannedSetDirty(true); // force write
|
||||||
|
DumpBanlist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BanMan::~BanMan()
|
||||||
|
{
|
||||||
|
DumpBanlist();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::DumpBanlist()
|
||||||
|
{
|
||||||
|
SweepBanned(); // clean unused entries (if bantime has expired)
|
||||||
|
|
||||||
|
if (!BannedSetIsDirty()) return;
|
||||||
|
|
||||||
|
int64_t nStart = GetTimeMillis();
|
||||||
|
|
||||||
|
banmap_t banmap;
|
||||||
|
GetBanned(banmap);
|
||||||
|
if (m_ban_db.Write(banmap)) {
|
||||||
|
SetBannedSetDirty(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrint(BCLog::NET, "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
|
||||||
|
banmap.size(), GetTimeMillis() - nStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::ClearBanned()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
setBanned.clear();
|
||||||
|
setBannedIsDirty = true;
|
||||||
|
}
|
||||||
|
DumpBanlist(); //store banlist to disk
|
||||||
|
if (clientInterface) clientInterface->BannedListChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BanMan::IsBanned(CNetAddr netAddr)
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
for (const auto& it : setBanned) {
|
||||||
|
CSubNet subNet = it.first;
|
||||||
|
CBanEntry banEntry = it.second;
|
||||||
|
|
||||||
|
if (subNet.Match(netAddr) && GetTime() < banEntry.nBanUntil) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BanMan::IsBanned(CSubNet subNet)
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
banmap_t::iterator i = setBanned.find(subNet);
|
||||||
|
if (i != setBanned.end()) {
|
||||||
|
CBanEntry banEntry = (*i).second;
|
||||||
|
if (GetTime() < banEntry.nBanUntil) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::Ban(const CNetAddr& netAddr, const BanReason& banReason, int64_t bantimeoffset, bool sinceUnixEpoch)
|
||||||
|
{
|
||||||
|
CSubNet subNet(netAddr);
|
||||||
|
Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::Ban(const CSubNet& subNet, const BanReason& banReason, int64_t bantimeoffset, bool sinceUnixEpoch)
|
||||||
|
{
|
||||||
|
CBanEntry banEntry(GetTime());
|
||||||
|
banEntry.banReason = banReason;
|
||||||
|
if (bantimeoffset <= 0) {
|
||||||
|
bantimeoffset = m_default_ban_time;
|
||||||
|
sinceUnixEpoch = false;
|
||||||
|
}
|
||||||
|
banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime()) + bantimeoffset;
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) {
|
||||||
|
setBanned[subNet] = banEntry;
|
||||||
|
setBannedIsDirty = true;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (clientInterface) clientInterface->BannedListChanged();
|
||||||
|
|
||||||
|
//store banlist to disk immediately if user requested ban
|
||||||
|
if (banReason == BanReasonManuallyAdded) DumpBanlist();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BanMan::Unban(const CNetAddr& netAddr)
|
||||||
|
{
|
||||||
|
CSubNet subNet(netAddr);
|
||||||
|
return Unban(subNet);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BanMan::Unban(const CSubNet& subNet)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
if (setBanned.erase(subNet) == 0) return false;
|
||||||
|
setBannedIsDirty = true;
|
||||||
|
}
|
||||||
|
if (clientInterface) clientInterface->BannedListChanged();
|
||||||
|
DumpBanlist(); //store banlist to disk immediately
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::GetBanned(banmap_t& banMap)
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
// Sweep the banlist so expired bans are not returned
|
||||||
|
SweepBanned();
|
||||||
|
banMap = setBanned; //create a thread safe copy
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::SetBanned(const banmap_t& banMap)
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
setBanned = banMap;
|
||||||
|
setBannedIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::SweepBanned()
|
||||||
|
{
|
||||||
|
int64_t now = GetTime();
|
||||||
|
bool notifyUI = false;
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
banmap_t::iterator it = setBanned.begin();
|
||||||
|
while (it != setBanned.end()) {
|
||||||
|
CSubNet subNet = (*it).first;
|
||||||
|
CBanEntry banEntry = (*it).second;
|
||||||
|
if (now > banEntry.nBanUntil) {
|
||||||
|
setBanned.erase(it++);
|
||||||
|
setBannedIsDirty = true;
|
||||||
|
notifyUI = true;
|
||||||
|
LogPrint(BCLog::NET, "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString());
|
||||||
|
} else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update UI
|
||||||
|
if (notifyUI && clientInterface) {
|
||||||
|
clientInterface->BannedListChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BanMan::BannedSetIsDirty()
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
|
return setBannedIsDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BanMan::SetBannedSetDirty(bool dirty)
|
||||||
|
{
|
||||||
|
LOCK(cs_setBanned); //reuse setBanned lock for the setBannedIsDirty flag
|
||||||
|
setBannedIsDirty = dirty;
|
||||||
|
}
|
69
src/banman.h
Normal file
69
src/banman.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
#ifndef BITCOIN_BANMAN_H
|
||||||
|
#define BITCOIN_BANMAN_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <addrdb.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <sync.h>
|
||||||
|
|
||||||
|
// NOTE: When adjusting this, update rpcnet:setban's help ("24h")
|
||||||
|
static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
|
||||||
|
|
||||||
|
class CClientUIInterface;
|
||||||
|
class CNetAddr;
|
||||||
|
class CSubNet;
|
||||||
|
|
||||||
|
// Denial-of-service detection/prevention
|
||||||
|
// The idea is to detect peers that are behaving
|
||||||
|
// badly and disconnect/ban them, but do it in a
|
||||||
|
// one-coding-mistake-won't-shatter-the-entire-network
|
||||||
|
// way.
|
||||||
|
// IMPORTANT: There should be nothing I can give a
|
||||||
|
// node that it will forward on that will make that
|
||||||
|
// node's peers drop it. If there is, an attacker
|
||||||
|
// can isolate a node and/or try to split the network.
|
||||||
|
// Dropping a node for sending stuff that is invalid
|
||||||
|
// now but might be valid in a later version is also
|
||||||
|
// dangerous, because it can cause a network split
|
||||||
|
// between nodes running old code and nodes running
|
||||||
|
// new code.
|
||||||
|
|
||||||
|
class BanMan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~BanMan();
|
||||||
|
BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time);
|
||||||
|
void Ban(const CNetAddr& netAddr, const BanReason& banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||||
|
void Ban(const CSubNet& subNet, const BanReason& banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||||
|
void ClearBanned(); // needed for unit testing
|
||||||
|
bool IsBanned(CNetAddr netAddr);
|
||||||
|
bool IsBanned(CSubNet subNet);
|
||||||
|
bool Unban(const CNetAddr& netAddr);
|
||||||
|
bool Unban(const CSubNet& subNet);
|
||||||
|
void GetBanned(banmap_t& banMap);
|
||||||
|
void DumpBanlist();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetBanned(const banmap_t& banMap);
|
||||||
|
bool BannedSetIsDirty();
|
||||||
|
//!set the "dirty" flag for the banlist
|
||||||
|
void SetBannedSetDirty(bool dirty = true);
|
||||||
|
//!clean unused entries (if bantime has expired)
|
||||||
|
void SweepBanned();
|
||||||
|
|
||||||
|
banmap_t setBanned;
|
||||||
|
CCriticalSection cs_setBanned;
|
||||||
|
bool setBannedIsDirty;
|
||||||
|
CClientUIInterface* clientInterface = nullptr;
|
||||||
|
CBanDB m_ban_db;
|
||||||
|
int64_t m_default_ban_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::unique_ptr<BanMan> g_banman;
|
||||||
|
#endif
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <addrman.h>
|
#include <addrman.h>
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
|
#include <banman.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <checkpoints.h>
|
#include <checkpoints.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <addrdb.h>
|
#include <addrdb.h>
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
|
#include <banman.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class BanMan;
|
||||||
class CCoinControl;
|
class CCoinControl;
|
||||||
class CFeeRate;
|
class CFeeRate;
|
||||||
class CNodeStats;
|
class CNodeStats;
|
||||||
|
|
190
src/net.cpp
190
src/net.cpp
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <clientversion.h>
|
#include <clientversion.h>
|
||||||
#include <consensus/consensus.h>
|
#include <consensus/consensus.h>
|
||||||
|
@ -457,25 +458,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||||
return pnode;
|
return pnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BanMan::DumpBanlist()
|
|
||||||
{
|
|
||||||
SweepBanned(); // clean unused entries (if bantime has expired)
|
|
||||||
|
|
||||||
if (!BannedSetIsDirty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int64_t nStart = GetTimeMillis();
|
|
||||||
|
|
||||||
banmap_t banmap;
|
|
||||||
GetBanned(banmap);
|
|
||||||
if (m_ban_db.Write(banmap)) {
|
|
||||||
SetBannedSetDirty(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogPrint(BCLog::NET, "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
|
|
||||||
banmap.size(), GetTimeMillis() - nStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNode::CloseSocketDisconnect()
|
void CNode::CloseSocketDisconnect()
|
||||||
{
|
{
|
||||||
fDisconnect = true;
|
fDisconnect = true;
|
||||||
|
@ -487,150 +469,6 @@ void CNode::CloseSocketDisconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BanMan::ClearBanned()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
setBanned.clear();
|
|
||||||
setBannedIsDirty = true;
|
|
||||||
}
|
|
||||||
DumpBanlist(); //store banlist to disk
|
|
||||||
if(clientInterface)
|
|
||||||
clientInterface->BannedListChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BanMan::IsBanned(CNetAddr ip)
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
for (const auto& it : setBanned) {
|
|
||||||
CSubNet subNet = it.first;
|
|
||||||
CBanEntry banEntry = it.second;
|
|
||||||
|
|
||||||
if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BanMan::IsBanned(CSubNet subnet)
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
banmap_t::iterator i = setBanned.find(subnet);
|
|
||||||
if (i != setBanned.end())
|
|
||||||
{
|
|
||||||
CBanEntry banEntry = (*i).second;
|
|
||||||
if (GetTime() < banEntry.nBanUntil) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
|
|
||||||
CSubNet subNet(addr);
|
|
||||||
Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
|
|
||||||
CBanEntry banEntry(GetTime());
|
|
||||||
banEntry.banReason = banReason;
|
|
||||||
if (bantimeoffset <= 0)
|
|
||||||
{
|
|
||||||
bantimeoffset = m_default_ban_time;
|
|
||||||
sinceUnixEpoch = false;
|
|
||||||
}
|
|
||||||
banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
|
|
||||||
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) {
|
|
||||||
setBanned[subNet] = banEntry;
|
|
||||||
setBannedIsDirty = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(clientInterface)
|
|
||||||
clientInterface->BannedListChanged();
|
|
||||||
if(banReason == BanReasonManuallyAdded)
|
|
||||||
DumpBanlist(); //store banlist to disk immediately if user requested ban
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BanMan::Unban(const CNetAddr &addr) {
|
|
||||||
CSubNet subNet(addr);
|
|
||||||
return Unban(subNet);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BanMan::Unban(const CSubNet &subNet) {
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
if (!setBanned.erase(subNet))
|
|
||||||
return false;
|
|
||||||
setBannedIsDirty = true;
|
|
||||||
}
|
|
||||||
if(clientInterface)
|
|
||||||
clientInterface->BannedListChanged();
|
|
||||||
DumpBanlist(); //store banlist to disk immediately
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::GetBanned(banmap_t &banMap)
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
// Sweep the banlist so expired bans are not returned
|
|
||||||
SweepBanned();
|
|
||||||
banMap = setBanned; //create a thread safe copy
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::SetBanned(const banmap_t &banMap)
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
setBanned = banMap;
|
|
||||||
setBannedIsDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::SweepBanned()
|
|
||||||
{
|
|
||||||
int64_t now = GetTime();
|
|
||||||
bool notifyUI = false;
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
banmap_t::iterator it = setBanned.begin();
|
|
||||||
while(it != setBanned.end())
|
|
||||||
{
|
|
||||||
CSubNet subNet = (*it).first;
|
|
||||||
CBanEntry banEntry = (*it).second;
|
|
||||||
if(now > banEntry.nBanUntil)
|
|
||||||
{
|
|
||||||
setBanned.erase(it++);
|
|
||||||
setBannedIsDirty = true;
|
|
||||||
notifyUI = true;
|
|
||||||
LogPrint(BCLog::NET, "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// update UI
|
|
||||||
if(notifyUI && clientInterface) {
|
|
||||||
clientInterface->BannedListChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BanMan::BannedSetIsDirty()
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned);
|
|
||||||
return setBannedIsDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BanMan::SetBannedSetDirty(bool dirty)
|
|
||||||
{
|
|
||||||
LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
|
|
||||||
setBannedIsDirty = dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
|
bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
|
||||||
for (const CSubNet& subnet : vWhitelistedRange) {
|
for (const CSubNet& subnet : vWhitelistedRange) {
|
||||||
if (subnet.Match(addr))
|
if (subnet.Match(addr))
|
||||||
|
@ -2430,32 +2268,6 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BanMan::BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time) : clientInterface(client_interface), m_ban_db(std::move(ban_file)), m_default_ban_time(default_ban_time)
|
|
||||||
{
|
|
||||||
if (clientInterface) clientInterface->InitMessage(_("Loading banlist..."));
|
|
||||||
|
|
||||||
int64_t nStart = GetTimeMillis();
|
|
||||||
setBannedIsDirty = false;
|
|
||||||
banmap_t banmap;
|
|
||||||
if (m_ban_db.Read(banmap)) {
|
|
||||||
SetBanned(banmap); // thread save setter
|
|
||||||
SetBannedSetDirty(false); // no need to write down, just read data
|
|
||||||
SweepBanned(); // sweep out unused entries
|
|
||||||
|
|
||||||
LogPrint(BCLog::NET, "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
|
|
||||||
banmap.size(), GetTimeMillis() - nStart);
|
|
||||||
} else {
|
|
||||||
LogPrintf("Invalid or missing banlist.dat; recreating\n");
|
|
||||||
SetBannedSetDirty(true); // force write
|
|
||||||
DumpBanlist();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BanMan::~BanMan()
|
|
||||||
{
|
|
||||||
DumpBanlist();
|
|
||||||
}
|
|
||||||
|
|
||||||
class CNetCleanup
|
class CNetCleanup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
49
src/net.h
49
src/net.h
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
class CNode;
|
class CNode;
|
||||||
|
class BanMan;
|
||||||
|
|
||||||
/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
|
/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
|
||||||
static const int PING_INTERVAL = 2 * 60;
|
static const int PING_INTERVAL = 2 * 60;
|
||||||
|
@ -85,9 +86,6 @@ static const bool DEFAULT_FORCEDNSSEED = false;
|
||||||
static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
|
static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
|
||||||
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
|
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
|
||||||
|
|
||||||
// NOTE: When adjusting this, update rpcnet:setban's help ("24h")
|
|
||||||
static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
|
|
||||||
|
|
||||||
typedef int64_t NodeId;
|
typedef int64_t NodeId;
|
||||||
|
|
||||||
struct AddedNodeInfo
|
struct AddedNodeInfo
|
||||||
|
@ -115,51 +113,6 @@ struct CSerializedNetMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BanMan
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Denial-of-service detection/prevention
|
|
||||||
// The idea is to detect peers that are behaving
|
|
||||||
// badly and disconnect/ban them, but do it in a
|
|
||||||
// one-coding-mistake-won't-shatter-the-entire-network
|
|
||||||
// way.
|
|
||||||
// IMPORTANT: There should be nothing I can give a
|
|
||||||
// node that it will forward on that will make that
|
|
||||||
// node's peers drop it. If there is, an attacker
|
|
||||||
// can isolate a node and/or try to split the network.
|
|
||||||
// Dropping a node for sending stuff that is invalid
|
|
||||||
// now but might be valid in a later version is also
|
|
||||||
// dangerous, because it can cause a network split
|
|
||||||
// between nodes running old code and nodes running
|
|
||||||
// new code.
|
|
||||||
~BanMan();
|
|
||||||
BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time);
|
|
||||||
void Ban(const CNetAddr& netAddr, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
|
||||||
void Ban(const CSubNet& subNet, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
|
||||||
void ClearBanned(); // needed for unit testing
|
|
||||||
bool IsBanned(CNetAddr ip);
|
|
||||||
bool IsBanned(CSubNet subnet);
|
|
||||||
bool Unban(const CNetAddr &ip);
|
|
||||||
bool Unban(const CSubNet &ip);
|
|
||||||
void GetBanned(banmap_t &banmap);
|
|
||||||
void DumpBanlist();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void SetBanned(const banmap_t &banmap);
|
|
||||||
bool BannedSetIsDirty();
|
|
||||||
//!set the "dirty" flag for the banlist
|
|
||||||
void SetBannedSetDirty(bool dirty=true);
|
|
||||||
//!clean unused entries (if bantime has expired)
|
|
||||||
void SweepBanned();
|
|
||||||
|
|
||||||
banmap_t setBanned;
|
|
||||||
CCriticalSection cs_setBanned;
|
|
||||||
bool setBannedIsDirty;
|
|
||||||
CClientUIInterface* clientInterface = nullptr;
|
|
||||||
CBanDB m_ban_db;
|
|
||||||
int64_t m_default_ban_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
class NetEventsInterface;
|
class NetEventsInterface;
|
||||||
class CConnman
|
class CConnman
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <net_processing.h>
|
#include <net_processing.h>
|
||||||
|
|
||||||
#include <addrman.h>
|
#include <addrman.h>
|
||||||
|
#include <banman.h>
|
||||||
#include <arith_uint256.h>
|
#include <arith_uint256.h>
|
||||||
#include <blockencodings.h>
|
#include <blockencodings.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <clientversion.h>
|
#include <clientversion.h>
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
// Unit tests for denial-of-service detection/prevention code
|
// Unit tests for denial-of-service detection/prevention code
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <keystore.h>
|
#include <keystore.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <test/test_bitcoin.h>
|
#include <test/test_bitcoin.h>
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <consensus/consensus.h>
|
#include <consensus/consensus.h>
|
||||||
#include <consensus/params.h>
|
#include <consensus/params.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE Bitcoin Test Suite
|
#define BOOST_TEST_MODULE Bitcoin Test Suite
|
||||||
|
|
||||||
|
#include <banman.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
Loading…
Add table
Reference in a new issue