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