diff options
Diffstat (limited to 'src/cryptonote_protocol/cryptonote_protocol_handler.inl')
-rw-r--r-- | src/cryptonote_protocol/cryptonote_protocol_handler.inl | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 9ae24551c..8aef31a5a 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -37,11 +37,11 @@ #include <boost/interprocess/detail/atomic.hpp> #include <list> -#include <unordered_map> +#include <ctime> #include "cryptonote_basic/cryptonote_format_utils.h" #include "profile_tools.h" -#include "p2p/network_throttle-detail.hpp" +#include "net/network_throttle-detail.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.cn" @@ -266,13 +266,17 @@ namespace cryptonote return true; // from v6, if the peer advertises a top block version, reject if it's not what it should be (will only work if no voting) - const uint8_t version = m_core.get_ideal_hard_fork_version(hshd.current_height - 1); - if (version >= 6 && version != hshd.top_version) + if (hshd.current_height > 0) { - if (version < hshd.top_version) - MCLOG_RED(el::Level::Warning, "global", context << " peer claims higher version that we think - we may be forked from the network and a software upgrade may be needed"); - LOG_DEBUG_CC(context, "Ignoring due to wrong top version for block " << (hshd.current_height - 1) << ": " << (unsigned)hshd.top_version << ", expected " << (unsigned)version); - return false; + const uint8_t version = m_core.get_ideal_hard_fork_version(hshd.current_height - 1); + if (version >= 6 && version != hshd.top_version) + { + if (version < hshd.top_version) + MCLOG_RED(el::Level::Warning, "global", context << " peer claims higher version that we think (" << + (unsigned)hshd.top_version << " for " << (hshd.current_height - 1) << "instead of " << (unsigned)version << + ") - we may be forked from the network and a software upgrade may be needed"); + return false; + } } context.m_remote_blockchain_height = hshd.current_height; @@ -999,6 +1003,11 @@ skip: MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) << ", we need " << previous_height); + if (blocks.empty()) + { + MERROR("Next span has no blocks"); + break; + } block new_block; if (!parse_and_validate_block_from_blob(blocks.front().block, new_block)) @@ -1414,6 +1423,10 @@ skip: // take out blocks we already have while (!context.m_needed_objects.empty() && m_core.have_block(context.m_needed_objects.front())) { + // if we're popping the last hash, record it so we can ask again from that hash, + // this prevents never being able to progress on peers we get old hash lists from + if (context.m_needed_objects.size() == 1) + context.m_last_known_hash = context.m_needed_objects.front(); context.m_needed_objects.pop_front(); } const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; @@ -1490,6 +1503,7 @@ skip: NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); m_core.get_short_chain_history(r.block_ids); + CHECK_AND_ASSERT_MES(!r.block_ids.empty(), false, "Short chain history is empty"); if (!start_from_current_chain) { @@ -1557,7 +1571,7 @@ skip: size_t t_cryptonote_protocol_handler<t_core>::get_synchronizing_connections_count() { size_t count = 0; - m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id)->bool{ + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ if(context.m_state == cryptonote_connection_context::state_synchronizing) ++count; return true; @@ -1577,6 +1591,12 @@ skip: drop_connection(context, true, false); return 1; } + if (arg.total_height < arg.m_block_ids.size() || arg.start_height > arg.total_height - arg.m_block_ids.size()) + { + LOG_ERROR_CCONTEXT("sent invalid start/nblocks/height, dropping connection"); + drop_connection(context, true, false); + return 1; + } context.m_remote_blockchain_height = arg.total_height; context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1; |