Merge pull request #3866
6a58c88
console_handler: fix start_default_console use of prompt parameter (moneromooo-monero)885a117
http_protocol_handler: speedup newline discarding (moneromooo-monero)4d15864
abstract_tcp_server2: timeout on RPC connections (moneromooo-monero)dfd36bb
http_protocol_handler: limit the number of starting newlines (moneromooo-monero)
This commit is contained in:
commit
8a7b3ff138
|
@ -401,13 +401,19 @@ eof:
|
||||||
|
|
||||||
|
|
||||||
template<class t_server, class t_handler>
|
template<class t_server, class t_handler>
|
||||||
bool start_default_console(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
bool start_default_console(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
|
||||||
{
|
{
|
||||||
std::shared_ptr<async_console_handler> console_handler = std::make_shared<async_console_handler>();
|
std::shared_ptr<async_console_handler> console_handler = std::make_shared<async_console_handler>();
|
||||||
boost::thread([=](){console_handler->run<t_server, t_handler>(ptsrv, handlr, prompt, usage);}).detach();
|
boost::thread([=](){console_handler->run<t_server, t_handler>(ptsrv, handlr, prompt, usage);}).detach();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class t_server, class t_handler>
|
||||||
|
bool start_default_console(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
||||||
|
{
|
||||||
|
return start_default_console(ptsrv, handlr, [prompt](){ return prompt; }, usage);
|
||||||
|
}
|
||||||
|
|
||||||
template<class t_server>
|
template<class t_server>
|
||||||
bool start_default_console(t_server* ptsrv, const std::string& prompt, const std::string& usage = "")
|
bool start_default_console(t_server* ptsrv, const std::string& prompt, const std::string& usage = "")
|
||||||
{
|
{
|
||||||
|
@ -421,19 +427,31 @@ eof:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class t_server, class t_handler>
|
template<class t_server, class t_handler>
|
||||||
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
|
||||||
{
|
{
|
||||||
async_console_handler console_handler;
|
async_console_handler console_handler;
|
||||||
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, _1, _2, handlr), prompt, usage);
|
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, _1, _2, handlr), prompt, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class t_server, class t_handler>
|
template<class t_server, class t_handler>
|
||||||
bool start_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
||||||
|
{
|
||||||
|
return run_default_console_handler_no_srv_param(ptsrv, handlr, [prompt](){return prompt;},usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class t_server, class t_handler>
|
||||||
|
bool start_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
|
||||||
{
|
{
|
||||||
boost::thread( boost::bind(run_default_console_handler_no_srv_param<t_server, t_handler>, ptsrv, handlr, prompt, usage) );
|
boost::thread( boost::bind(run_default_console_handler_no_srv_param<t_server, t_handler>, ptsrv, handlr, prompt, usage) );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class t_server, class t_handler>
|
||||||
|
bool start_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
||||||
|
{
|
||||||
|
return start_default_console_handler_no_srv_param(ptsrv, handlr, [prompt](){return prompt;}, usage);
|
||||||
|
}
|
||||||
|
|
||||||
/*template<class a>
|
/*template<class a>
|
||||||
bool f(int i, a l)
|
bool f(int i, a l)
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,6 +135,11 @@ namespace net_utils
|
||||||
/// Handle completion of a write operation.
|
/// Handle completion of a write operation.
|
||||||
void handle_write(const boost::system::error_code& e, size_t cb);
|
void handle_write(const boost::system::error_code& e, size_t cb);
|
||||||
|
|
||||||
|
/// reset connection timeout timer and callback
|
||||||
|
void reset_timer(boost::posix_time::milliseconds ms, bool add);
|
||||||
|
boost::posix_time::milliseconds get_default_time() const;
|
||||||
|
boost::posix_time::milliseconds get_timeout_from_bytes_read(size_t bytes) const;
|
||||||
|
|
||||||
/// Buffer for incoming data.
|
/// Buffer for incoming data.
|
||||||
boost::array<char, 8192> buffer_;
|
boost::array<char, 8192> buffer_;
|
||||||
//boost::array<char, 1024> buffer_;
|
//boost::array<char, 1024> buffer_;
|
||||||
|
@ -158,6 +163,9 @@ namespace net_utils
|
||||||
boost::mutex m_throttle_speed_in_mutex;
|
boost::mutex m_throttle_speed_in_mutex;
|
||||||
boost::mutex m_throttle_speed_out_mutex;
|
boost::mutex m_throttle_speed_out_mutex;
|
||||||
|
|
||||||
|
boost::asio::deadline_timer m_timer;
|
||||||
|
bool m_local;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setRpcStation();
|
void setRpcStation();
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <boost/thread/thread.hpp> // TODO
|
#include <boost/thread/thread.hpp> // TODO
|
||||||
#include <boost/thread/condition_variable.hpp> // TODO
|
#include <boost/thread/condition_variable.hpp> // TODO
|
||||||
#include "misc_language.h"
|
#include "misc_language.h"
|
||||||
|
#include "net/local_ip.h"
|
||||||
#include "pragma_comp_defs.h"
|
#include "pragma_comp_defs.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -55,6 +56,10 @@
|
||||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||||
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
||||||
|
|
||||||
|
#define DEFAULT_TIMEOUT_MS_LOCAL boost::posix_time::milliseconds(120000) // 2 minutes
|
||||||
|
#define DEFAULT_TIMEOUT_MS_REMOTE boost::posix_time::milliseconds(10000) // 10 seconds
|
||||||
|
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
|
||||||
|
|
||||||
PRAGMA_WARNING_PUSH
|
PRAGMA_WARNING_PUSH
|
||||||
namespace epee
|
namespace epee
|
||||||
{
|
{
|
||||||
|
@ -79,7 +84,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
m_pfilter( pfilter ),
|
m_pfilter( pfilter ),
|
||||||
m_connection_type( connection_type ),
|
m_connection_type( connection_type ),
|
||||||
m_throttle_speed_in("speed_in", "throttle_speed_in"),
|
m_throttle_speed_in("speed_in", "throttle_speed_in"),
|
||||||
m_throttle_speed_out("speed_out", "throttle_speed_out")
|
m_throttle_speed_out("speed_out", "throttle_speed_out"),
|
||||||
|
m_timer(io_service),
|
||||||
|
m_local(false)
|
||||||
{
|
{
|
||||||
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
|
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +146,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
|
|
||||||
context = boost::value_initialized<t_connection_context>();
|
context = boost::value_initialized<t_connection_context>();
|
||||||
const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())};
|
const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())};
|
||||||
|
m_local = epee::net_utils::is_ip_loopback(ip_);
|
||||||
|
|
||||||
// create a random uuid
|
// create a random uuid
|
||||||
boost::uuids::uuid random_uuid;
|
boost::uuids::uuid random_uuid;
|
||||||
|
@ -159,6 +167,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
|
|
||||||
m_protocol_handler.after_init_connection();
|
m_protocol_handler.after_init_connection();
|
||||||
|
|
||||||
|
reset_timer(get_default_time(), false);
|
||||||
|
|
||||||
socket_.async_read_some(boost::asio::buffer(buffer_),
|
socket_.async_read_some(boost::asio::buffer(buffer_),
|
||||||
strand_.wrap(
|
strand_.wrap(
|
||||||
boost::bind(&connection<t_protocol_handler>::handle_read, self,
|
boost::bind(&connection<t_protocol_handler>::handle_read, self,
|
||||||
|
@ -304,6 +314,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
delay *= 0.5;
|
delay *= 0.5;
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
long int ms = (long int)(delay * 100);
|
long int ms = (long int)(delay * 100);
|
||||||
|
reset_timer(boost::posix_time::milliseconds(ms + 1), true);
|
||||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(ms));
|
boost::this_thread::sleep_for(boost::chrono::milliseconds(ms));
|
||||||
}
|
}
|
||||||
} while(delay > 0);
|
} while(delay > 0);
|
||||||
|
@ -329,6 +340,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
shutdown();
|
shutdown();
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
|
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
|
||||||
socket_.async_read_some(boost::asio::buffer(buffer_),
|
socket_.async_read_some(boost::asio::buffer(buffer_),
|
||||||
strand_.wrap(
|
strand_.wrap(
|
||||||
boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(),
|
boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(),
|
||||||
|
@ -539,6 +551,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
do_send_handler_write( ptr , size_now ); // (((H)))
|
do_send_handler_write( ptr , size_now ); // (((H)))
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), false, "Unexpected queue size");
|
CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), false, "Unexpected queue size");
|
||||||
|
reset_timer(get_default_time(), false);
|
||||||
boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now ) ,
|
boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now ) ,
|
||||||
//strand_.wrap(
|
//strand_.wrap(
|
||||||
boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2)
|
boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2)
|
||||||
|
@ -557,9 +570,53 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
} // do_send_chunk
|
} // do_send_chunk
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
template<class t_protocol_handler>
|
template<class t_protocol_handler>
|
||||||
|
boost::posix_time::milliseconds connection<t_protocol_handler>::get_default_time() const
|
||||||
|
{
|
||||||
|
if (m_local)
|
||||||
|
return DEFAULT_TIMEOUT_MS_LOCAL;
|
||||||
|
else
|
||||||
|
return DEFAULT_TIMEOUT_MS_REMOTE;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
template<class t_protocol_handler>
|
||||||
|
boost::posix_time::milliseconds connection<t_protocol_handler>::get_timeout_from_bytes_read(size_t bytes) const
|
||||||
|
{
|
||||||
|
boost::posix_time::milliseconds ms = (boost::posix_time::milliseconds)(unsigned)(bytes * TIMEOUT_EXTRA_MS_PER_BYTE);
|
||||||
|
ms += m_timer.expires_from_now();
|
||||||
|
if (ms > get_default_time())
|
||||||
|
ms = get_default_time();
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
template<class t_protocol_handler>
|
||||||
|
void connection<t_protocol_handler>::reset_timer(boost::posix_time::milliseconds ms, bool add)
|
||||||
|
{
|
||||||
|
if (m_connection_type != e_connection_type_RPC)
|
||||||
|
return;
|
||||||
|
MTRACE("Setting " << ms << " expiry");
|
||||||
|
auto self = safe_shared_from_this();
|
||||||
|
if(!self)
|
||||||
|
{
|
||||||
|
MERROR("Resetting timer on a dead object");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (add)
|
||||||
|
ms += m_timer.expires_from_now();
|
||||||
|
m_timer.expires_from_now(ms);
|
||||||
|
m_timer.async_wait([=](const boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
if(ec == boost::asio::error::operation_aborted)
|
||||||
|
return;
|
||||||
|
MDEBUG(context << "connection timeout, closing");
|
||||||
|
self->close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
template<class t_protocol_handler>
|
||||||
bool connection<t_protocol_handler>::shutdown()
|
bool connection<t_protocol_handler>::shutdown()
|
||||||
{
|
{
|
||||||
// Initiate graceful connection closure.
|
// Initiate graceful connection closure.
|
||||||
|
m_timer.cancel();
|
||||||
boost::system::error_code ignored_ec;
|
boost::system::error_code ignored_ec;
|
||||||
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||||
m_was_shutdown = true;
|
m_was_shutdown = true;
|
||||||
|
@ -572,6 +629,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
{
|
{
|
||||||
TRY_ENTRY();
|
TRY_ENTRY();
|
||||||
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
|
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
|
||||||
|
m_timer.cancel();
|
||||||
size_t send_que_size = 0;
|
size_t send_que_size = 0;
|
||||||
CRITICAL_REGION_BEGIN(m_send_que_lock);
|
CRITICAL_REGION_BEGIN(m_send_que_lock);
|
||||||
send_que_size = m_send_que.size();
|
send_que_size = m_send_que.size();
|
||||||
|
@ -629,6 +687,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
//have more data to send
|
//have more data to send
|
||||||
|
reset_timer(get_default_time(), false);
|
||||||
auto size_now = m_send_que.front().size();
|
auto size_now = m_send_que.front().size();
|
||||||
MDEBUG("handle_write() NOW SENDS: packet="<<size_now<<" B" <<", from queue size="<<m_send_que.size());
|
MDEBUG("handle_write() NOW SENDS: packet="<<size_now<<" B" <<", from queue size="<<m_send_que.size());
|
||||||
if (speed_limit_is_enabled())
|
if (speed_limit_is_enabled())
|
||||||
|
|
|
@ -141,6 +141,7 @@ namespace net_utils
|
||||||
size_t m_len_summary, m_len_remain;
|
size_t m_len_summary, m_len_remain;
|
||||||
config_type& m_config;
|
config_type& m_config;
|
||||||
bool m_want_close;
|
bool m_want_close;
|
||||||
|
size_t m_newlines;
|
||||||
protected:
|
protected:
|
||||||
i_service_endpoint* m_psnd_hndlr;
|
i_service_endpoint* m_psnd_hndlr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#define HTTP_MAX_URI_LEN 9000
|
#define HTTP_MAX_URI_LEN 9000
|
||||||
#define HTTP_MAX_HEADER_LEN 100000
|
#define HTTP_MAX_HEADER_LEN 100000
|
||||||
|
#define HTTP_MAX_STARTING_NEWLINES 8
|
||||||
|
|
||||||
namespace epee
|
namespace epee
|
||||||
{
|
{
|
||||||
|
@ -203,6 +204,7 @@ namespace net_utils
|
||||||
m_len_remain(0),
|
m_len_remain(0),
|
||||||
m_config(config),
|
m_config(config),
|
||||||
m_want_close(false),
|
m_want_close(false),
|
||||||
|
m_newlines(0),
|
||||||
m_psnd_hndlr(psnd_hndlr)
|
m_psnd_hndlr(psnd_hndlr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -216,6 +218,7 @@ namespace net_utils
|
||||||
m_body_transfer_type = http_body_transfer_undefined;
|
m_body_transfer_type = http_body_transfer_undefined;
|
||||||
m_query_info.clear();
|
m_query_info.clear();
|
||||||
m_len_summary = 0;
|
m_len_summary = 0;
|
||||||
|
m_newlines = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
|
@ -236,6 +239,8 @@ namespace net_utils
|
||||||
bool simple_http_connection_handler<t_connection_context>::handle_buff_in(std::string& buf)
|
bool simple_http_connection_handler<t_connection_context>::handle_buff_in(std::string& buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
size_t ndel;
|
||||||
|
|
||||||
if(m_cache.size())
|
if(m_cache.size())
|
||||||
m_cache += buf;
|
m_cache += buf;
|
||||||
else
|
else
|
||||||
|
@ -253,11 +258,19 @@ namespace net_utils
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//check_and_handle_fake_response();
|
//check_and_handle_fake_response();
|
||||||
if((m_cache[0] == '\r' || m_cache[0] == '\n'))
|
ndel = m_cache.find_first_not_of("\r\n");
|
||||||
|
if (ndel != 0)
|
||||||
{
|
{
|
||||||
//some times it could be that before query line cold be few line breaks
|
//some times it could be that before query line cold be few line breaks
|
||||||
//so we have to be calm without panic with assers
|
//so we have to be calm without panic with assers
|
||||||
m_cache.erase(0, 1);
|
m_newlines += std::string::npos == ndel ? m_cache.size() : ndel;
|
||||||
|
if (m_newlines > HTTP_MAX_STARTING_NEWLINES)
|
||||||
|
{
|
||||||
|
LOG_ERROR("simple_http_connection_handler::handle_buff_out: Too many starting newlines");
|
||||||
|
m_state = http_state_error;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_cache.erase(0, ndel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue