aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/include/net')
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.h22
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl146
-rw-r--r--contrib/epee/include/net/connection_basic.hpp3
-rw-r--r--contrib/epee/include/net/http_protocol_handler.h9
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl49
-rw-r--r--contrib/epee/include/net/http_server_handlers_map2.h1
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h10
-rw-r--r--contrib/epee/include/net/local_ip.h2
-rw-r--r--contrib/epee/include/net/net_helper.h3
-rw-r--r--contrib/epee/include/net/net_utils_base.h1
10 files changed, 178 insertions, 68 deletions
diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h
index 2f7325be5..3f726a352 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.h
+++ b/contrib/epee/include/net/abstract_tcp_server2.h
@@ -119,6 +119,7 @@ namespace net_utils
//----------------- i_service_endpoint ---------------------
virtual bool do_send(const void* ptr, size_t cb); ///< (see do_send from i_service_endpoint)
virtual bool do_send_chunk(const void* ptr, size_t cb); ///< will send (or queue) a part of data
+ virtual bool send_done();
virtual bool close();
virtual bool call_run_once_service_io();
virtual bool request_callback();
@@ -137,8 +138,11 @@ namespace net_utils
/// 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;
+ boost::posix_time::milliseconds get_default_timeout();
+ boost::posix_time::milliseconds get_timeout_from_bytes_read(size_t bytes);
+
+ /// host connection count tracking
+ unsigned int host_count(const std::string &host, int delta = 0);
/// Buffer for incoming data.
boost::array<char, 8192> buffer_;
@@ -154,6 +158,7 @@ namespace net_utils
std::list<boost::shared_ptr<connection<t_protocol_handler> > > m_self_refs; // add_ref/release support
critical_section m_self_refs_lock;
critical_section m_chunking_lock; // held while we add small chunks of the big do_send() to small do_send_chunk()
+ critical_section m_shutdown_lock; // held while shutting down
t_connection_type m_connection_type;
@@ -165,6 +170,8 @@ namespace net_utils
boost::asio::deadline_timer m_timer;
bool m_local;
+ bool m_ready_to_close;
+ std::string m_host;
public:
void setRpcStation();
@@ -239,7 +246,6 @@ namespace net_utils
m_timer(io_serice)
{}
boost::asio::deadline_timer m_timer;
- uint64_t m_period;
};
template <class t_handler>
@@ -255,25 +261,27 @@ namespace net_utils
{
return m_handler();
}
+ uint64_t m_period;
};
template<class t_handler>
bool add_idle_handler(t_handler t_callback, uint64_t timeout_ms)
{
- boost::shared_ptr<idle_callback_conext_base> ptr(new idle_callback_conext<t_handler>(io_service_, t_callback, timeout_ms));
+ boost::shared_ptr<idle_callback_conext<t_handler>> ptr(new idle_callback_conext<t_handler>(io_service_, t_callback, timeout_ms));
//needed call handler here ?...
ptr->m_timer.expires_from_now(boost::posix_time::milliseconds(ptr->m_period));
- ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler, this, ptr));
+ ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler<t_handler>, this, ptr));
return true;
}
- bool global_timer_handler(/*const boost::system::error_code& err, */boost::shared_ptr<idle_callback_conext_base> ptr)
+ template<class t_handler>
+ bool global_timer_handler(/*const boost::system::error_code& err, */boost::shared_ptr<idle_callback_conext<t_handler>> ptr)
{
//if handler return false - he don't want to be called anymore
if(!ptr->call_handler())
return true;
ptr->m_timer.expires_from_now(boost::posix_time::milliseconds(ptr->m_period));
- ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler, this, ptr));
+ ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler<t_handler>, this, ptr));
return true;
}
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index bc54acae4..9b03941ee 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -43,6 +43,8 @@
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
#include <boost/thread/thread.hpp> // TODO
#include <boost/thread/condition_variable.hpp> // TODO
+#include "warnings.h"
+#include "string_tools.h"
#include "misc_language.h"
#include "net/local_ip.h"
#include "pragma_comp_defs.h"
@@ -51,13 +53,11 @@
#include <iomanip>
#include <algorithm>
-#include "../../../../src/cryptonote_core/cryptonote_core.h" // e.g. for the send_stop_signal()
-
#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 DEFAULT_TIMEOUT_MS_LOCAL 1800000 // 30 minutes
+#define DEFAULT_TIMEOUT_MS_REMOTE 300000 // 5 minutes
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
PRAGMA_WARNING_PUSH
@@ -86,7 +86,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
m_throttle_speed_in("speed_in", "throttle_speed_in"),
m_throttle_speed_out("speed_out", "throttle_speed_out"),
m_timer(io_service),
- m_local(false)
+ m_local(false),
+ m_ready_to_close(false)
{
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
}
@@ -146,12 +147,10 @@ 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_);
+ m_local = epee::net_utils::is_ip_loopback(ip_) || epee::net_utils::is_ip_local(ip_);
- // create a random uuid
- boost::uuids::uuid random_uuid;
- // that stuff turns out to be included, even though it's from src... Taking advantage
- random_uuid = crypto::rand<boost::uuids::uuid>();
+ // create a random uuid, we don't need crypto strength here
+ const boost::uuids::uuid random_uuid = boost::uuids::random_generator()();
context.set_details(random_uuid, epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income);
_dbg3("[sock " << socket_.native_handle() << "] new connection from " << print_connection_context_short(context) <<
@@ -165,9 +164,12 @@ PRAGMA_WARNING_DISABLE_VS(4355)
return false;
}
+ m_host = context.m_remote_address.host_str();
+ try { host_count(m_host, 1); } catch(...) { /* ignore */ }
+
m_protocol_handler.after_init_connection();
- reset_timer(get_default_time(), false);
+ reset_timer(get_default_timeout(), false);
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
@@ -324,6 +326,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
logger_handle_net_read(bytes_transferred);
context.m_last_recv = time(NULL);
context.m_recv_cnt += bytes_transferred;
+ m_ready_to_close = false;
bool recv_res = m_protocol_handler.handle_recv(buffer_.data(), bytes_transferred);
if(!recv_res)
{
@@ -356,6 +359,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
_dbg3("[sock " << socket_.native_handle() << "] Some problems at read: " << e.message() << ':' << e.value());
shutdown();
}
+ else
+ {
+ _dbg3("[sock " << socket_.native_handle() << "] peer closed connection");
+ if (m_ready_to_close)
+ shutdown();
+ }
+ m_ready_to_close = true;
}
// If an error occurs then no new asynchronous operations are started. This
// means that all shared_ptr references to the connection object will
@@ -531,7 +541,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
if(m_send_que.size() > 1)
{ // active operation should be in progress, nothing to do, just wait last operation callback
auto size_now = cb;
- MDEBUG("do_send() NOW just queues: packet="<<size_now<<" B, is added to queue-size="<<m_send_que.size());
+ MDEBUG("do_send_chunk() NOW just queues: packet="<<size_now<<" B, is added to queue-size="<<m_send_que.size());
//do_send_handler_delayed( ptr , size_now ); // (((H))) // empty function
LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] Async send requested " << m_send_que.front().size());
@@ -546,12 +556,12 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}
auto size_now = m_send_que.front().size();
- MDEBUG("do_send() NOW SENSD: packet="<<size_now<<" B");
+ MDEBUG("do_send_chunk() NOW SENSD: packet="<<size_now<<" B");
if (speed_limit_is_enabled())
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);
+ reset_timer(get_default_timeout(), 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)
@@ -566,29 +576,51 @@ PRAGMA_WARNING_DISABLE_VS(4355)
return true;
- CATCH_ENTRY_L0("connection<t_protocol_handler>::do_send", false);
+ CATCH_ENTRY_L0("connection<t_protocol_handler>::do_send_chunk", false);
} // do_send_chunk
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
- boost::posix_time::milliseconds connection<t_protocol_handler>::get_default_time() const
+ boost::posix_time::milliseconds connection<t_protocol_handler>::get_default_timeout()
{
+ unsigned count;
+ try { count = host_count(m_host); } catch (...) { count = 0; }
+ const unsigned shift = std::min(std::max(count, 1u) - 1, 8u);
+ boost::posix_time::milliseconds timeout(0);
if (m_local)
- return DEFAULT_TIMEOUT_MS_LOCAL;
+ timeout = boost::posix_time::milliseconds(DEFAULT_TIMEOUT_MS_LOCAL >> shift);
else
- return DEFAULT_TIMEOUT_MS_REMOTE;
+ timeout = boost::posix_time::milliseconds(DEFAULT_TIMEOUT_MS_REMOTE >> shift);
+ return timeout;
}
//---------------------------------------------------------------------------------
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 connection<t_protocol_handler>::get_timeout_from_bytes_read(size_t bytes)
{
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();
+ if (ms > get_default_timeout())
+ ms = get_default_timeout();
return ms;
}
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
+ unsigned int connection<t_protocol_handler>::host_count(const std::string &host, int delta)
+ {
+ static boost::mutex hosts_mutex;
+ CRITICAL_REGION_LOCAL(hosts_mutex);
+ static std::map<std::string, unsigned int> hosts;
+ unsigned int &val = hosts[host];
+ if (delta > 0)
+ MTRACE("New connection from host " << host << ": " << val);
+ else if (delta < 0)
+ MTRACE("Closed connection from host " << host << ": " << val);
+ CHECK_AND_ASSERT_THROW_MES(delta >= 0 || val >= (unsigned)-delta, "Count would go negative");
+ CHECK_AND_ASSERT_THROW_MES(delta <= 0 || val <= std::numeric_limits<unsigned int>::max() - (unsigned)delta, "Count would wrap");
+ val += delta;
+ return val;
+ }
+ //---------------------------------------------------------------------------------
+ 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)
@@ -615,11 +647,20 @@ PRAGMA_WARNING_DISABLE_VS(4355)
template<class t_protocol_handler>
bool connection<t_protocol_handler>::shutdown()
{
+ CRITICAL_REGION_BEGIN(m_shutdown_lock);
+ if (m_was_shutdown)
+ return true;
+ m_was_shutdown = true;
// 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;
+ if (!m_host.empty())
+ {
+ try { host_count(m_host, -1); } catch (...) { /* ignore */ }
+ m_host = "";
+ }
+ CRITICAL_REGION_END();
m_protocol_handler.release_protocol();
return true;
}
@@ -628,6 +669,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
bool connection<t_protocol_handler>::close()
{
TRY_ENTRY();
+ auto self = safe_shared_from_this();
+ if(!self)
+ return false;
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
m_timer.cancel();
size_t send_que_size = 0;
@@ -645,6 +689,15 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
+ bool connection<t_protocol_handler>::send_done()
+ {
+ if (m_ready_to_close)
+ return close();
+ m_ready_to_close = true;
+ return true;
+ }
+ //---------------------------------------------------------------------------------
+ template<class t_protocol_handler>
bool connection<t_protocol_handler>::cancel()
{
return close();
@@ -687,7 +740,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}else
{
//have more data to send
- reset_timer(get_default_time(), false);
+ reset_timer(get_default_timeout(), 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())
@@ -984,7 +1037,8 @@ POP_WARNINGS
void boosted_tcp_server<t_protocol_handler>::handle_accept(const boost::system::error_code& e)
{
MDEBUG("handle_accept");
- TRY_ENTRY();
+ try
+ {
if (!e)
{
if (m_connection_type == e_connection_type_RPC) {
@@ -1002,11 +1056,25 @@ POP_WARNINGS
conn->start(true, 1 < m_threads_count);
conn->save_dbg_log();
- }else
+ return;
+ }
+ else
{
- _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count);
+ MERROR("Error in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e);
+ }
}
- CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::handle_accept", void());
+ catch (const std::exception &e)
+ {
+ MERROR("Exception in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e.what());
+ }
+
+ // error path, if e or exception
+ _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count);
+ misc_utils::sleep_no_w(100);
+ new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type));
+ acceptor_.async_accept(new_connection_->socket(),
+ boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
+ boost::asio::placeholders::error));
}
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
@@ -1041,8 +1109,16 @@ POP_WARNINGS
sock_.open(remote_endpoint.protocol());
if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" )
{
- boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(adr.c_str()), 0);
- sock_.bind(local_endpoint);
+ boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0);
+ boost::system::error_code ec;
+ sock_.bind(local_endpoint, ec);
+ if (ec)
+ {
+ MERROR("Error binding to " << bind_ip << ": " << ec.message());
+ if (sock_.is_open())
+ sock_.close();
+ return false;
+ }
}
/*
@@ -1147,8 +1223,16 @@ POP_WARNINGS
sock_.open(remote_endpoint.protocol());
if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" )
{
- boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(adr.c_str()), 0);
- sock_.bind(local_endpoint);
+ boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0);
+ boost::system::error_code ec;
+ sock_.bind(local_endpoint, ec);
+ if (ec)
+ {
+ MERROR("Error binding to " << bind_ip << ": " << ec.message());
+ if (sock_.is_open())
+ sock_.close();
+ return false;
+ }
}
boost::shared_ptr<boost::asio::deadline_timer> sh_deadline(new boost::asio::deadline_timer(io_service_));
diff --git a/contrib/epee/include/net/connection_basic.hpp b/contrib/epee/include/net/connection_basic.hpp
index 095e747a5..7e8750047 100644
--- a/contrib/epee/include/net/connection_basic.hpp
+++ b/contrib/epee/include/net/connection_basic.hpp
@@ -92,7 +92,6 @@ class connection_basic { // not-templated base class for rapid developmet of som
critical_section m_send_que_lock;
std::list<std::string> m_send_que;
volatile bool m_is_multithreaded;
- double m_start_time;
/// Strand to ensure the connection's handlers are not called concurrently.
boost::asio::io_service::strand strand_;
/// Socket for the connection.
@@ -112,8 +111,6 @@ class connection_basic { // not-templated base class for rapid developmet of som
void logger_handle_net_write(size_t size); // network data written
void logger_handle_net_read(size_t size); // network data read
- void set_start_time();
-
// config for rate limit
static void set_rate_up_limit(uint64_t limit);
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index e602fac2b..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()
@@ -144,6 +144,7 @@ namespace net_utils
size_t m_newlines;
protected:
i_service_endpoint* m_psnd_hndlr;
+ t_connection_context& m_conn_context;
};
template<class t_connection_context>
@@ -175,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)
@@ -197,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()
@@ -219,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 f1da5067a..b53bdc200 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -32,6 +32,7 @@
#include "string_tools.h"
#include "file_io_utils.h"
#include "net_parse_helpers.h"
+#include "time_helper.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
@@ -196,16 +197,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_newlines(0),
- m_psnd_hndlr(psnd_hndlr)
+ m_psnd_hndlr(psnd_hndlr),
+ m_conn_context(conn_context)
{
}
@@ -281,7 +283,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;
}
@@ -295,7 +297,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;
}
@@ -310,10 +312,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;
}
@@ -327,8 +329,10 @@ namespace net_utils
inline bool analize_http_method(const boost::smatch& result, http::http_method& method, int& http_ver_major, int& http_ver_minor)
{
CHECK_AND_ASSERT_MES(result[0].matched, false, "simple_http_connection_handler::analize_http_method() assert failed...");
- http_ver_major = boost::lexical_cast<int>(result[11]);
- http_ver_minor = boost::lexical_cast<int>(result[12]);
+ if (!boost::conversion::try_lexical_convert<int>(result[11], http_ver_major))
+ return false;
+ if (!boost::conversion::try_lexical_convert<int>(result[12], http_ver_minor))
+ return false;
if(result[3].matched)
method = http::http_method_options;
@@ -350,13 +354,18 @@ namespace net_utils
template<class t_connection_context>
bool simple_http_connection_handler<t_connection_context>::handle_invoke_query_line()
{
- STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+).(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
+ STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+)\\.(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
// 123 4 5 6 7 8 9 10 11 12
//size_t match_len = 0;
boost::smatch result;
if(boost::regex_search(m_cache, result, rexp_match_command_line, boost::match_default) && result[0].matched)
{
- analize_http_method(result, m_query_info.m_http_method, m_query_info.m_http_ver_hi, m_query_info.m_http_ver_hi);
+ if (!analize_http_method(result, m_query_info.m_http_method, m_query_info.m_http_ver_hi, m_query_info.m_http_ver_hi))
+ {
+ m_state = http_state_error;
+ MERROR("Failed to analyze method");
+ return false;
+ }
m_query_info.m_URI = result[10];
if (!parse_uri(m_query_info.m_URI, m_query_info.m_uri_content))
{
@@ -375,7 +384,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;
}
@@ -399,14 +408,14 @@ namespace net_utils
template<class t_connection_context>
bool simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(size_t pos)
{
- //LOG_PRINT_L4("HTTP HEAD:\r\n" << m_cache.substr(0, pos));
+ LOG_PRINT_L3("HTTP HEAD:\r\n" << m_cache.substr(0, pos));
m_query_info.m_full_request_buf_size = pos;
m_query_info.m_request_head.assign(m_cache.begin(), m_cache.begin()+pos);
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;
}
@@ -422,7 +431,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;
}
@@ -455,7 +464,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;
}
@@ -536,7 +545,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;
@@ -553,7 +562,8 @@ namespace net_utils
if(!(boost::regex_search( str, result, rexp_mach_field, boost::match_default) && result[0].matched))
return false;
- len = boost::lexical_cast<size_t>(result[0]);
+ try { len = boost::lexical_cast<size_t>(result[0]); }
+ catch(...) { return false; }
return true;
}
//-----------------------------------------------------------------------------------
@@ -582,6 +592,7 @@ namespace net_utils
m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
if ((response.m_body.size() && (query_info.m_http_method != http::http_method_head)) || (query_info.m_http_method == http::http_method_options))
m_psnd_hndlr->do_send((void*)response.m_body.data(), response.m_body.size());
+ m_psnd_hndlr->send_done();
return res;
}
//-----------------------------------------------------------------------------------
diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h
index 429e3e1af..00a867d3e 100644
--- a/contrib/epee/include/net/http_server_handlers_map2.h
+++ b/contrib/epee/include/net/http_server_handlers_map2.h
@@ -122,6 +122,7 @@
if(!ps.load_from_json(query_info.m_body)) \
{ \
boost::value_initialized<epee::json_rpc::error_response> rsp; \
+ static_cast<epee::json_rpc::error_response&>(rsp).jsonrpc = "2.0"; \
static_cast<epee::json_rpc::error_response&>(rsp).error.code = -32700; \
static_cast<epee::json_rpc::error_response&>(rsp).error.message = "Parse error"; \
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index 0b1fe05fa..08aa1d468 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -99,7 +99,7 @@ public:
size_t get_connections_count();
void set_handler(levin_commands_handler<t_connection_context>* handler, void (*destroy)(levin_commands_handler<t_connection_context>*) = NULL);
- async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE)
+ async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
{}
~async_protocol_handler_config() { set_handler(NULL, NULL); }
void del_out_connections(size_t count);
@@ -272,9 +272,14 @@ public:
m_wait_count = 0;
m_oponent_protocol_ver = 0;
m_connection_initialized = false;
+ m_invoke_buf_ready = 0;
+ m_invoke_result_code = LEVIN_ERROR_CONNECTION;
}
virtual ~async_protocol_handler()
{
+ try
+ {
+
m_deletion_initiated = true;
if(m_connection_initialized)
{
@@ -288,6 +293,9 @@ public:
CHECK_AND_ASSERT_MES_NO_RET(0 == boost::interprocess::ipcdetail::atomic_read32(&m_wait_count), "Failed to wait for operation completion. m_wait_count = " << m_wait_count);
MTRACE(m_connection_context << "~async_protocol_handler()");
+
+ }
+ catch (...) { /* ignore */ }
}
bool start_outer_call()
diff --git a/contrib/epee/include/net/local_ip.h b/contrib/epee/include/net/local_ip.h
index 0d458963c..52c5855b9 100644
--- a/contrib/epee/include/net/local_ip.h
+++ b/contrib/epee/include/net/local_ip.h
@@ -48,7 +48,7 @@ namespace epee
if( (ip | 0xffffff00) == 0xffffffac)
{
- uint32_t second_num = (ip << 8) & 0xff000000;
+ uint32_t second_num = (ip >> 8) & 0xff;
if(second_num >= 16 && second_num <= 31 )
return true;
}
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index 2c2efcd82..94744ac21 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -106,7 +106,8 @@ namespace net_utils
~blocked_mode_client()
{
//profile_tools::local_coast lc("~blocked_mode_client()", 3);
- shutdown();
+ try { shutdown(); }
+ catch(...) { /* ignore */ }
}
inline
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index 7615786be..a133942fb 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -281,6 +281,7 @@ namespace net_utils
{
virtual bool do_send(const void* ptr, size_t cb)=0;
virtual bool close()=0;
+ virtual bool send_done()=0;
virtual bool call_run_once_service_io()=0;
virtual bool request_callback()=0;
virtual boost::asio::io_service& get_io_service()=0;