aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/epee/include/console_handler.h24
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.h8
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl61
-rw-r--r--contrib/epee/include/net/http_protocol_handler.h10
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl44
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization_overloads.h2
6 files changed, 124 insertions, 25 deletions
diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h
index 4ea3fa54b..0e22a971c 100644
--- a/contrib/epee/include/console_handler.h
+++ b/contrib/epee/include/console_handler.h
@@ -401,13 +401,19 @@ eof:
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>();
boost::thread([=](){console_handler->run<t_server, t_handler>(ptsrv, handlr, prompt, usage);}).detach();
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>
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>
- 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;
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>
- 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) );
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>
bool f(int i, a l)
{
diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h
index ccde928ba..2f7325be5 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.h
+++ b/contrib/epee/include/net/abstract_tcp_server2.h
@@ -135,6 +135,11 @@ namespace net_utils
/// Handle completion of a write operation.
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.
boost::array<char, 8192> 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_out_mutex;
+ boost::asio::deadline_timer m_timer;
+ bool m_local;
+
public:
void setRpcStation();
};
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 52b4c85ba..91a94c21e 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -44,6 +44,7 @@
#include <boost/thread/thread.hpp> // TODO
#include <boost/thread/condition_variable.hpp> // TODO
#include "misc_language.h"
+#include "net/local_ip.h"
#include "pragma_comp_defs.h"
#include <sstream>
@@ -55,6 +56,10 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#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
namespace epee
{
@@ -79,7 +84,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
m_pfilter( pfilter ),
m_connection_type( connection_type ),
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);
}
@@ -139,6 +146,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
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())};
+ m_local = epee::net_utils::is_ip_loopback(ip_);
// create a random uuid
boost::uuids::uuid random_uuid;
@@ -159,6 +167,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
m_protocol_handler.after_init_connection();
+ reset_timer(get_default_time(), false);
+
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection<t_protocol_handler>::handle_read, self,
@@ -304,6 +314,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
delay *= 0.5;
if (delay > 0) {
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));
}
} while(delay > 0);
@@ -329,6 +340,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
shutdown();
}else
{
+ reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
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)))
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 ) ,
//strand_.wrap(
boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2)
@@ -557,9 +570,53 @@ PRAGMA_WARNING_DISABLE_VS(4355)
} // do_send_chunk
//---------------------------------------------------------------------------------
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()
{
// Initiate graceful connection closure.
+ m_timer.cancel();
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
m_was_shutdown = true;
@@ -572,6 +629,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
{
TRY_ENTRY();
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
+ m_timer.cancel();
size_t send_que_size = 0;
CRITICAL_REGION_BEGIN(m_send_que_lock);
send_que_size = m_send_que.size();
@@ -629,6 +687,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}else
{
//have more data to send
+ reset_timer(get_default_time(), false);
auto size_now = m_send_que.front().size();
MDEBUG("handle_write() NOW SENDS: packet="<<size_now<<" B" <<", from queue size="<<m_send_que.size());
if (speed_limit_is_enabled())
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index b4485d1cd..1780f2393 100644
--- a/contrib/epee/include/net/http_protocol_handler.h
+++ b/contrib/epee/include/net/http_protocol_handler.h
@@ -69,7 +69,7 @@ namespace net_utils
typedef t_connection_context connection_context;//t_connection_context net_utils::connection_context_base connection_context;
typedef http_server_config config_type;
- simple_http_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config);
+ simple_http_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context);
virtual ~simple_http_connection_handler(){}
bool release_protocol()
@@ -141,8 +141,10 @@ namespace net_utils
size_t m_len_summary, m_len_remain;
config_type& m_config;
bool m_want_close;
+ size_t m_newlines;
protected:
i_service_endpoint* m_psnd_hndlr;
+ t_connection_context& m_conn_context;
};
template<class t_connection_context>
@@ -174,9 +176,8 @@ namespace net_utils
typedef custum_handler_config<t_connection_context> config_type;
http_custom_handler(i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context)
- : simple_http_connection_handler<t_connection_context>(psnd_hndlr, config),
+ : simple_http_connection_handler<t_connection_context>(psnd_hndlr, config, conn_context),
m_config(config),
- m_conn_context(conn_context),
m_auth(m_config.m_user ? http_server_auth{*m_config.m_user, config.rng} : http_server_auth{})
{}
inline bool handle_request(const http_request_info& query_info, http_response_info& response)
@@ -196,7 +197,7 @@ namespace net_utils
response.m_response_comment = "OK";
response.m_body.clear();
- return m_config.m_phandler->handle_http_request(query_info, response, m_conn_context);
+ return m_config.m_phandler->handle_http_request(query_info, response, this->m_conn_context);
}
virtual bool thread_init()
@@ -218,7 +219,6 @@ namespace net_utils
private:
//simple_http_connection_handler::config_type m_stub_config;
config_type& m_config;
- t_connection_context& m_conn_context;
http_server_auth m_auth;
};
}
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index c18f7f706..b35bcb670 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -38,6 +38,7 @@
#define HTTP_MAX_URI_LEN 9000
#define HTTP_MAX_HEADER_LEN 100000
+#define HTTP_MAX_STARTING_NEWLINES 8
namespace epee
{
@@ -195,15 +196,17 @@ namespace net_utils
//--------------------------------------------------------------------------------------------
template<class t_connection_context>
- simple_http_connection_handler<t_connection_context>::simple_http_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config):
+ simple_http_connection_handler<t_connection_context>::simple_http_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context):
m_state(http_state_retriving_comand_line),
m_body_transfer_type(http_body_transfer_undefined),
- m_is_stop_handling(false),
+ m_is_stop_handling(false),
m_len_summary(0),
m_len_remain(0),
- m_config(config),
+ m_config(config),
m_want_close(false),
- m_psnd_hndlr(psnd_hndlr)
+ m_newlines(0),
+ m_psnd_hndlr(psnd_hndlr),
+ m_conn_context(conn_context)
{
}
@@ -216,6 +219,7 @@ namespace net_utils
m_body_transfer_type = http_body_transfer_undefined;
m_query_info.clear();
m_len_summary = 0;
+ m_newlines = 0;
return true;
}
//--------------------------------------------------------------------------------------------
@@ -236,6 +240,8 @@ namespace net_utils
bool simple_http_connection_handler<t_connection_context>::handle_buff_in(std::string& buf)
{
+ size_t ndel;
+
if(m_cache.size())
m_cache += buf;
else
@@ -253,11 +259,19 @@ namespace net_utils
break;
//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
//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;
}
@@ -268,7 +282,7 @@ namespace net_utils
m_is_stop_handling = true;
if(m_cache.size() > HTTP_MAX_URI_LEN)
{
- LOG_ERROR("simple_http_connection_handler::handle_buff_out: Too long URI line");
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler::handle_buff_out: Too long URI line");
m_state = http_state_error;
return false;
}
@@ -282,7 +296,7 @@ namespace net_utils
m_is_stop_handling = true;
if(m_cache.size() > HTTP_MAX_HEADER_LEN)
{
- LOG_ERROR("simple_http_connection_handler::handle_buff_in: Too long header area");
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler::handle_buff_in: Too long header area");
m_state = http_state_error;
return false;
}
@@ -297,10 +311,10 @@ namespace net_utils
case http_state_connection_close:
return false;
default:
- LOG_ERROR("simple_http_connection_handler::handle_char_out: Wrong state: " << m_state);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler::handle_char_out: Wrong state: " << m_state);
return false;
case http_state_error:
- LOG_ERROR("simple_http_connection_handler::handle_char_out: Error state!!!");
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler::handle_char_out: Error state!!!");
return false;
}
@@ -362,7 +376,7 @@ namespace net_utils
}else
{
m_state = http_state_error;
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::handle_invoke_query_line(): Failed to match first line: " << m_cache);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler<t_connection_context>::handle_invoke_query_line(): Failed to match first line: " << m_cache);
return false;
}
@@ -393,7 +407,7 @@ namespace net_utils
if(!parse_cached_header(m_query_info.m_header_info, m_cache, pos))
{
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): failed to anilize request header: " << m_cache);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): failed to anilize request header: " << m_cache);
m_state = http_state_error;
return false;
}
@@ -409,7 +423,7 @@ namespace net_utils
m_body_transfer_type = http_body_transfer_measure;
if(!get_len_from_content_lenght(m_query_info.m_header_info.m_content_length, m_len_summary))
{
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): Failed to get_len_from_content_lenght();, m_query_info.m_content_length="<<m_query_info.m_header_info.m_content_length);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): Failed to get_len_from_content_lenght();, m_query_info.m_content_length="<<m_query_info.m_header_info.m_content_length);
m_state = http_state_error;
return false;
}
@@ -442,7 +456,7 @@ namespace net_utils
case http_body_transfer_multipart:
case http_body_transfer_undefined:
default:
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::handle_retriving_query_body(): Unexpected m_body_query_type state:" << m_body_transfer_type);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler<t_connection_context>::handle_retriving_query_body(): Unexpected m_body_query_type state:" << m_body_transfer_type);
m_state = http_state_error;
return false;
}
@@ -523,7 +537,7 @@ namespace net_utils
body_info.m_etc_fields.push_back(std::pair<std::string, std::string>(result[field_etc_name], result[field_val]));
else
{
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::parse_cached_header() not matched last entry in:"<<m_cache_to_process);
+ LOG_ERROR_CC(m_conn_context, "simple_http_connection_handler<t_connection_context>::parse_cached_header() not matched last entry in:" << m_cache_to_process);
}
it_current_bound = result[(int)result.size()-1]. first;
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
index 7087136cc..09087f785 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -156,7 +156,7 @@ namespace epee
typename stl_container::value_type* pelem = (typename stl_container::value_type*)buff.data();
CHECK_AND_ASSERT_MES(!(loaded_size%sizeof(typename stl_container::value_type)),
false,
- "size in blob " << loaded_size << " not have not zero modulo for sizeof(value_type) = " << sizeof(typename stl_container::value_type));
+ "size in blob " << loaded_size << " not have not zero modulo for sizeof(value_type) = " << sizeof(typename stl_container::value_type) << ", type " << typeid(typename stl_container::value_type).name());
size_t count = (loaded_size/sizeof(typename stl_container::value_type));
for(size_t i = 0; i < count; i++)
container.insert(container.end(), *(pelem++));