mirror of
https://github.com/wownero/wownero.git
synced 2026-11-12 19:33:54 +01:00
epee: validate Levin response command before buffering
This commit is contained in:
@@ -193,6 +193,7 @@ public:
|
|||||||
struct invoke_response_handler_base
|
struct invoke_response_handler_base
|
||||||
{
|
{
|
||||||
virtual ~invoke_response_handler_base() {}
|
virtual ~invoke_response_handler_base() {}
|
||||||
|
virtual int command() const noexcept=0;
|
||||||
virtual bool handle(int res, const epee::span<const uint8_t> buff, connection_context& context)=0;
|
virtual bool handle(int res, const epee::span<const uint8_t> buff, connection_context& context)=0;
|
||||||
virtual void cancel()=0;
|
virtual void cancel()=0;
|
||||||
virtual bool cancel_timer()=0;
|
virtual bool cancel_timer()=0;
|
||||||
@@ -242,6 +243,11 @@ public:
|
|||||||
failure(LEVIN_ERROR_CONNECTION_DESTROYED);
|
failure(LEVIN_ERROR_CONNECTION_DESTROYED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int command() const noexcept override final
|
||||||
|
{
|
||||||
|
return m_command;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool handle(int res, const epee::span<const uint8_t> buff, typename async_protocol_handler::connection_context& context) override final
|
virtual bool handle(int res, const epee::span<const uint8_t> buff, typename async_protocol_handler::connection_context& context) override final
|
||||||
{
|
{
|
||||||
if(!cancel_timer())
|
if(!cancel_timer())
|
||||||
@@ -286,6 +292,29 @@ public:
|
|||||||
critical_section m_invoke_response_handlers_lock;
|
critical_section m_invoke_response_handlers_lock;
|
||||||
std::list<std::weak_ptr<invoke_response_handler_base>> m_invoke_response_handlers;
|
std::list<std::weak_ptr<invoke_response_handler_base>> m_invoke_response_handlers;
|
||||||
|
|
||||||
|
bool validate_response_command()
|
||||||
|
{
|
||||||
|
if (m_oponent_protocol_ver != LEVIN_PROTOCOL_VER_1 || !(m_current_head.m_flags & LEVIN_PACKET_RESPONSE))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CRITICAL_REGION_LOCAL(m_invoke_response_handlers_lock);
|
||||||
|
if (m_invoke_response_handlers.empty())
|
||||||
|
{
|
||||||
|
MERROR(m_connection_context << "Received levin response but have no invoke handlers");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front().lock();
|
||||||
|
if (!response_handler || m_current_head.m_command != static_cast<uint32_t>(response_handler->command()))
|
||||||
|
{
|
||||||
|
MERROR(m_connection_context << "Received levin response command " << m_current_head.m_command
|
||||||
|
<< " while waiting for " << (response_handler ? response_handler->command() : -1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<class callback_t>
|
template<class callback_t>
|
||||||
bool add_invoke_response_handler(const callback_t &cb, const std::chrono::milliseconds timeout, std::shared_ptr<net_utils::service_endpoint<derived_handler>> con, int command)
|
bool add_invoke_response_handler(const callback_t &cb, const std::chrono::milliseconds timeout, std::shared_ptr<net_utils::service_endpoint<derived_handler>> con, int command)
|
||||||
{
|
{
|
||||||
@@ -466,6 +495,9 @@ public:
|
|||||||
|
|
||||||
buff_to_invoke = {buff_to_invoke.data(), std::size_t(inner_size)};
|
buff_to_invoke = {buff_to_invoke.data(), std::size_t(inner_size)};
|
||||||
|
|
||||||
|
if (!validate_response_command())
|
||||||
|
return false;
|
||||||
|
|
||||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||||
if(buff_to_invoke.size() > std::min<size_t>(max_packet_size, max_bytes))
|
if(buff_to_invoke.size() > std::min<size_t>(max_packet_size, max_bytes))
|
||||||
{
|
{
|
||||||
@@ -571,9 +603,12 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_oponent_protocol_ver = m_current_head.m_protocol_version;
|
||||||
|
if (!validate_response_command())
|
||||||
|
return false;
|
||||||
|
|
||||||
m_cache_in_buffer.erase(sizeof(bucket_head2));
|
m_cache_in_buffer.erase(sizeof(bucket_head2));
|
||||||
m_state = stream_state_body;
|
m_state = stream_state_body;
|
||||||
m_oponent_protocol_ver = m_current_head.m_protocol_version;
|
|
||||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||||
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user