banman.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-present The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 #ifndef BITCOIN_BANMAN_H 6 #define BITCOIN_BANMAN_H 7 8 #include <addrdb.h> 9 #include <common/bloom.h> 10 #include <net_types.h> 11 #include <sync.h> 12 #include <util/fs.h> 13 14 #include <chrono> 15 #include <cstdint> 16 #include <memory> 17 18 // NOTE: When adjusting this, update rpcnet:setban's help ("24h") 19 static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban 20 21 /// How often to dump banned addresses/subnets to disk. 22 static constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15}; 23 24 class CClientUIInterface; 25 class CNetAddr; 26 class CSubNet; 27 28 // Banman manages two related but distinct concepts: 29 // 30 // 1. Banning. This is configured manually by the user, through the setban RPC. 31 // If an address or subnet is banned, we never accept incoming connections from 32 // it and never create outgoing connections to it. We won't gossip its address 33 // to other peers in addr messages. Banned addresses and subnets are stored to 34 // disk on shutdown and reloaded on startup. Banning can be used to 35 // prevent connections with spy nodes or other griefers. 36 // 37 // 2. Discouragement. If a peer misbehaves (see Misbehaving() in 38 // net_processing.cpp), we'll mark that address as discouraged. We still allow 39 // incoming connections from them, but they're preferred for eviction when 40 // we receive new incoming connections. We never make outgoing connections to 41 // them, and do not gossip their address to other peers. This is implemented as 42 // a bloom filter. We can (probabilistically) test for membership, but can't 43 // list all discouraged addresses or unmark them as discouraged. Discouragement 44 // can prevent our limited connection slots being used up by incompatible 45 // or broken peers. 46 // 47 // Neither banning nor discouragement are protections against denial-of-service 48 // attacks, since if an attacker has a way to waste our resources and we 49 // disconnect from them and ban that address, it's trivial for them to 50 // reconnect from another IP address. 51 // 52 // Attempting to automatically disconnect or ban any class of peer carries the 53 // risk of splitting the network. For example, if we banned/disconnected for a 54 // transaction that fails a policy check and a future version changes the 55 // policy check so the transaction is accepted, then that transaction could 56 // cause the network to split between old nodes and new nodes. 57 // 58 // NOTE: previously a misbehaving peer would get banned instead of discouraged. 59 // This meant a peer could unboundedly grow our in-memory map of banned ips. When 60 // receiving an ADDR message we would also compare every address received to every 61 // item in the map. See https://bitcoincore.org/en/2024/07/03/disclose-unbounded-banlist. 62 63 class BanMan 64 { 65 public: 66 ~BanMan(); 67 BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time); 68 void Ban(const CNetAddr& net_addr, int64_t ban_time_offset = 0, bool since_unix_epoch = false) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 69 void Ban(const CSubNet& sub_net, int64_t ban_time_offset = 0, bool since_unix_epoch = false) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 70 void Discourage(const CNetAddr& net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 71 void ClearBanned() EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 72 73 //! Return whether net_addr is banned 74 bool IsBanned(const CNetAddr& net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 75 76 //! Return whether sub_net is exactly banned 77 bool IsBanned(const CSubNet& sub_net) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 78 79 //! Return whether net_addr is discouraged. 80 bool IsDiscouraged(const CNetAddr& net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 81 82 bool Unban(const CNetAddr& net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 83 bool Unban(const CSubNet& sub_net) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 84 void GetBanned(banmap_t& banmap) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 85 void DumpBanlist() EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 86 87 private: 88 void LoadBanlist() EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex); 89 //!clean unused entries (if bantime has expired) 90 void SweepBanned() EXCLUSIVE_LOCKS_REQUIRED(m_banned_mutex); 91 92 Mutex m_banned_mutex; 93 banmap_t m_banned GUARDED_BY(m_banned_mutex); 94 bool m_is_dirty GUARDED_BY(m_banned_mutex){false}; 95 CClientUIInterface* m_client_interface = nullptr; 96 CBanDB m_ban_db; 97 const int64_t m_default_ban_time; 98 CRollingBloomFilter m_discouraged GUARDED_BY(m_banned_mutex) {50000, 0.000001}; 99 }; 100 101 #endif // BITCOIN_BANMAN_H