aboutsummaryrefslogtreecommitdiff
path: root/src/banman.cpp
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2018-12-11 21:07:36 +0000
committerGregory Maxwell <greg@xiph.org>2019-01-22 21:10:48 +0000
commit0297be61acdf1cdd5f56c8371d1718d08229d9b3 (patch)
treeadd640a4a3c30cb470c7259b2c1018ee94b9a892 /src/banman.cpp
parent9bad1e0b22c1065c5ab73d74ac96747ecf33dcdf (diff)
Allow connections from misbehavior banned peers.
This allows incoming connections from peers which are only banned due to an automatic misbehavior ban if doing so won't fill inbound. These peers are preferred for eviction when inbound fills, but may still be kept if they fall into the protected classes. This eviction preference lasts the entire life of the connection even if the ban expires. If they misbehave again they'll still get disconnected. The main purpose of banning on misbehavior is to prevent our connections from being wasted on unhelpful peers such as ones running incompatible consensus rules. For inbound peers this can be better accomplished with eviction preferences. A secondary purpose was to reduce resource waste from repeated abuse but virtually any attacker can get a nearly unlimited supply of addresses, so disconnection is about the best we can do.
Diffstat (limited to 'src/banman.cpp')
-rw-r--r--src/banman.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/banman.cpp b/src/banman.cpp
index 9933c829c5..47d64a8f31 100644
--- a/src/banman.cpp
+++ b/src/banman.cpp
@@ -67,14 +67,36 @@ void BanMan::ClearBanned()
if (m_client_interface) m_client_interface->BannedListChanged();
}
+int BanMan::IsBannedLevel(CNetAddr net_addr)
+{
+ // Returns the most severe level of banning that applies to this address.
+ // 0 - Not banned
+ // 1 - Automatic misbehavior ban
+ // 2 - Any other ban
+ int level = 0;
+ auto current_time = GetTime();
+ LOCK(m_cs_banned);
+ for (const auto& it : m_banned) {
+ CSubNet sub_net = it.first;
+ CBanEntry ban_entry = it.second;
+
+ if (current_time < ban_entry.nBanUntil && sub_net.Match(net_addr)) {
+ if (ban_entry.banReason != BanReasonNodeMisbehaving) return 2;
+ level = 1;
+ }
+ }
+ return level;
+}
+
bool BanMan::IsBanned(CNetAddr net_addr)
{
+ auto current_time = GetTime();
LOCK(m_cs_banned);
for (const auto& it : m_banned) {
CSubNet sub_net = it.first;
CBanEntry ban_entry = it.second;
- if (sub_net.Match(net_addr) && GetTime() < ban_entry.nBanUntil) {
+ if (current_time < ban_entry.nBanUntil && sub_net.Match(net_addr)) {
return true;
}
}
@@ -83,11 +105,12 @@ bool BanMan::IsBanned(CNetAddr net_addr)
bool BanMan::IsBanned(CSubNet sub_net)
{
+ auto current_time = GetTime();
LOCK(m_cs_banned);
banmap_t::iterator i = m_banned.find(sub_net);
if (i != m_banned.end()) {
CBanEntry ban_entry = (*i).second;
- if (GetTime() < ban_entry.nBanUntil) {
+ if (current_time < ban_entry.nBanUntil) {
return true;
}
}