From 662a7e91c874abad8d1fd6a71157645f99d35d66 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Tue, 31 Aug 2021 13:14:35 +0200 Subject: [PATCH] P2PServer: always ban IPs that send bad blocks --- src/p2p_server.cpp | 31 ++++++++++++++++++++++++++----- src/p2p_server.h | 3 ++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index ee407b8..0d45805 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -409,6 +409,19 @@ void P2PServer::remove_peer_from_list(P2PClient* client) } } +void P2PServer::remove_peer_from_list(const raw_ip& ip) +{ + MutexLock lock(m_peerListLock); + + for (auto it = m_peerList.begin(); it != m_peerList.end(); ++it) { + const Peer& p = *it; + if (p.m_addr == ip) { + m_peerList.erase(it); + return; + } + } +} + void P2PServer::broadcast(const PoolBlock& block) { Broadcast* data = new Broadcast{}; @@ -1429,10 +1442,11 @@ bool P2PServer::P2PClient::handle_incoming_block_async(PoolBlock* block) P2PClient* client; P2PServer* server; uint32_t client_reset_counter; + raw_ip client_ip; std::vector missing_blocks; }; - Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), {} }; + Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), m_addr, {} }; work->req.data = work; const int err = uv_queue_work(&server->m_loop, &work->req, @@ -1440,7 +1454,7 @@ bool P2PServer::P2PClient::handle_incoming_block_async(PoolBlock* block) { bkg_jobs_tracker.start("P2PServer::handle_incoming_block_async"); Work* work = reinterpret_cast(req->data); - work->client->handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->missing_blocks); + work->client->handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->client_ip, work->missing_blocks); }, [](uv_work_t* req, int /*status*/) { @@ -1459,15 +1473,22 @@ bool P2PServer::P2PClient::handle_incoming_block_async(PoolBlock* block) return true; } -void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, std::vector& missing_blocks) +void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, const raw_ip& addr, std::vector& missing_blocks) { if (!pool->side_chain().add_external_block(block, missing_blocks)) { // Client sent bad data, disconnect and ban it if (reset_counter == m_resetCounter.load()) { - ban(DEFAULT_BAN_TIME); - static_cast(m_owner)->remove_peer_from_list(this); close(); + LOGWARN(3, "peer " << static_cast(m_addrString) << " banned for " << DEFAULT_BAN_TIME << " seconds"); } + else { + const log::hex_buf addr_hex(addr.data, sizeof(addr.data)); + LOGWARN(3, "IP " << addr_hex << " banned for " << DEFAULT_BAN_TIME << " seconds"); + } + + P2PServer* server = pool->p2p_server(); + server->ban(addr, DEFAULT_BAN_TIME); + server->remove_peer_from_list(addr); } } diff --git a/src/p2p_server.h b/src/p2p_server.h index d31e169..15350ee 100644 --- a/src/p2p_server.h +++ b/src/p2p_server.h @@ -95,7 +95,7 @@ public: bool on_peer_list_response(const uint8_t* buf) const; bool handle_incoming_block_async(PoolBlock* block); - void handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, std::vector& missing_blocks); + void handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, const raw_ip& addr, std::vector& missing_blocks); void post_handle_incoming_block(const uint32_t reset_counter, std::vector& missing_blocks); uint64_t m_peerId; @@ -139,6 +139,7 @@ private: void load_saved_peer_list(); void update_peer_in_list(bool is_v6, const raw_ip& ip, int port); void remove_peer_from_list(P2PClient* client); + void remove_peer_from_list(const raw_ip& ip); uv_mutex_t m_rngLock; std::random_device m_rd;