banman.h raw

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