diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2020-12-08 17:55:24 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2020-12-10 22:00:01 +0000 |
commit | d729730d380fa25f0b122dd4ef6f331a35748a4b (patch) | |
tree | 6e7725c03947b47272261de132abb166e11749b8 /src/cryptonote_protocol/cryptonote_protocol_handler.inl | |
parent | Merge pull request #7109 (diff) | |
download | monero-d729730d380fa25f0b122dd4ef6f331a35748a4b.tar.xz |
protocol: drop origin IP if a block fails to verify in sync mode
It would otherwise be possible for a peer to send bad blocks,
then disconnect and reconnect again, escaping bans
Diffstat (limited to '')
-rw-r--r-- | src/cryptonote_protocol/cryptonote_protocol_handler.inl | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index c62a0cd31..cb743316a 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1257,7 +1257,7 @@ namespace cryptonote const boost::posix_time::time_duration dt = now - request_time; const float rate = size * 1e6 / (dt.total_microseconds() + 1); MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1024) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB"); - m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size); + m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, context.m_remote_address, rate, blocks_size); const crypto::hash last_block_hash = cryptonote::get_block_hash(b); context.m_last_known_hash = last_block_hash; @@ -1358,7 +1358,8 @@ namespace cryptonote uint64_t start_height; std::vector<cryptonote::block_complete_entry> blocks; boost::uuids::uuid span_connection_id; - if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id)) + epee::net_utils::network_address span_origin; + if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id, span_origin)) { MDEBUG(context << " no next span found, going back to download"); break; @@ -1456,6 +1457,7 @@ namespace cryptonote if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks)) { LOG_ERROR_CCONTEXT("Failure in prepare_handle_incoming_blocks"); + drop_connections(span_origin); return 1; } if (!pblocks.empty() && pblocks.size() != blocks.size()) @@ -1495,6 +1497,7 @@ namespace cryptonote { if(tvc[i].m_verifivation_failed) { + drop_connections(span_origin); if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ cryptonote::transaction tx; crypto::hash txid; @@ -1536,6 +1539,7 @@ namespace cryptonote if(bvc.m_verifivation_failed) { + drop_connections(span_origin); if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, true); @@ -1555,6 +1559,7 @@ namespace cryptonote } if(bvc.m_marked_as_orphaned) { + drop_connections(span_origin); if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); drop_connection(context, true, true); @@ -2173,7 +2178,7 @@ skip: const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8); bool sync_pruned_blocks = m_sync_pruned_blocks && first_block_height >= bp_fork_height && m_core.get_blockchain_pruning_seed(); - span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects); + span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_remote_address, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects); MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second); if (span.second > 0) { @@ -2309,7 +2314,8 @@ skip: uint64_t start_height; std::vector<cryptonote::block_complete_entry> blocks; boost::uuids::uuid span_connection_id; - if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, true)) + epee::net_utils::network_address span_origin; + if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, span_origin, true)) { LOG_DEBUG_CC(context, "No other thread is adding blocks, resuming"); MLOG_PEER_STATE("will try to add blocks next"); @@ -2734,6 +2740,29 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> + void t_cryptonote_protocol_handler<t_core>::drop_connections(const epee::net_utils::network_address address) + { + MWARNING("dropping connections to " << address.str()); + + m_p2p->add_host_fail(address, 5); + + std::vector<boost::uuids::uuid> drop; + m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags) { + if (address.is_same_host(cntxt.m_remote_address)) + drop.push_back(cntxt.m_connection_id); + return true; + }); + for (const boost::uuids::uuid &id: drop) + { + m_block_queue.flush_spans(id, true); + m_p2p->for_connection(id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ + drop_connection(context, true, false); + return true; + }); + } + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context) { uint64_t target = 0; |