/ src / banman.h
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