34#include <boost/asio/post.hpp>
35#include <boost/foreach.hpp>
36#include <boost/uuid/random_generator.hpp>
37#include <boost/chrono.hpp>
38#include <boost/utility/value_init.hpp>
39#include <boost/asio/bind_executor.hpp>
40#include <boost/asio/deadline_timer.hpp>
41#include <boost/date_time/posix_time/posix_time.hpp>
42#include <boost/thread/condition_variable.hpp>
43#include <boost/make_shared.hpp>
44#include <boost/thread.hpp>
55#undef MONERO_DEFAULT_LOG_CATEGORY
56#define MONERO_DEFAULT_LOG_CATEGORY "net"
58#define AGGRESSIVE_TIMEOUT_THRESHOLD 120
59#define NEW_CONNECTION_TIMEOUT_LOCAL 1200000
60#define NEW_CONNECTION_TIMEOUT_REMOTE 10000
61#define DEFAULT_TIMEOUT_MS_LOCAL 1800000
62#define DEFAULT_TIMEOUT_MS_REMOTE 300000
63#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
73 CHECK_AND_ASSERT_THROW_MES(
bool(ptr),
"shared_state cannot be null");
83 static std::mutex hosts_mutex;
84 std::lock_guard<std::mutex> guard(hosts_mutex);
85 static std::map<std::string, unsigned int> hosts;
86 unsigned int &val = hosts[m_host];
88 MTRACE(
"New connection from host " << m_host <<
": " << val);
90 MTRACE(
"Closed connection from host " << m_host <<
": " << val);
91 CHECK_AND_ASSERT_THROW_MES(delta >= 0 || val >= (
unsigned)-delta,
"Count would go negative");
92 CHECK_AND_ASSERT_THROW_MES(delta <= 0 || val <= std::numeric_limits<unsigned int>::max() - (
unsigned)delta,
"Count would wrap");
101 try {
count = host_count(); }
catch (...) {}
102 const unsigned shift = (
104 std::min(std::max(
count, 1u) - 1, 8u) :
117 return std::chrono::duration_cast<connection<T>::duration_t>(
118 std::chrono::duration<double, std::chrono::milliseconds::period>(
127 switch (m_state.status)
129 case status_t::RUNNING:
132 case status_t::INTERRUPTED:
135 case status_t::TERMINATING:
146 if (m_state.timers.general.wait_expire) {
147 m_state.timers.general.cancel_expire =
true;
148 m_state.timers.general.reset_expire =
true;
149 m_timers.general.expires_after(
151 duration + (add ? (m_timers.general.expiry() - std::chrono::steady_clock::now()) :
duration_t{}),
152 get_default_timeout()
157 m_timers.general.expires_after(
159 duration + (add ? (m_timers.general.expiry() - std::chrono::steady_clock::now()) :
duration_t{}),
160 get_default_timeout()
170 if (m_state.timers.general.wait_expire)
172 m_state.timers.general.wait_expire =
true;
174 auto on_wait = [
this, self] {
175 std::lock_guard<std::mutex> guard(m_state.lock);
176 m_state.timers.general.wait_expire =
false;
177 if (m_state.timers.general.cancel_expire) {
178 m_state.timers.general.cancel_expire =
false;
179 if (m_state.timers.general.reset_expire) {
180 m_state.timers.general.reset_expire =
false;
183 else if (m_state.status == status_t::INTERRUPTED)
185 else if (m_state.status == status_t::TERMINATING)
188 else if (m_state.status == status_t::RUNNING)
190 else if (m_state.status == status_t::INTERRUPTED)
193 m_timers.general.async_wait([
this, self, on_wait](
const ec_t & ec){
194 boost::asio::post(m_strand, on_wait);
201 if (!m_state.timers.general.wait_expire)
203 m_state.timers.general.cancel_expire =
true;
204 m_state.timers.general.reset_expire =
false;
205 m_timers.general.cancel();
211 if (m_state.socket.wait_handshake)
218 if (!m_state.ssl.forced && !m_state.ssl.detected) {
219 m_state.socket.wait_read =
true;
220 boost::asio::async_read(
223 m_state.data.read.buffer.data(),
224 m_state.data.read.buffer.size()
227 boost::asio::bind_executor(
229 [
this, self](
const ec_t &ec,
size_t bytes_transferred){
230 std::lock_guard<std::mutex> guard(m_state.lock);
231 m_state.socket.wait_read = false;
232 if (m_state.socket.cancel_read) {
233 m_state.socket.cancel_read = false;
234 state_status_check();
236 else if (ec.value()) {
241 static_cast<const unsigned char *
>(
242 m_state.data.read.buffer.data()
247 m_state.ssl.enabled = false;
248 finish_read(bytes_transferred);
251 m_state.ssl.detected = true;
260 m_state.socket.wait_handshake =
true;
261 auto on_handshake = [
this, self](
const ec_t &ec,
size_t bytes_transferred){
262 std::lock_guard<std::mutex> guard(m_state.lock);
263 m_state.socket.wait_handshake =
false;
264 if (m_state.socket.cancel_handshake) {
265 m_state.socket.cancel_handshake =
false;
266 state_status_check();
268 else if (ec.value()) {
271 socket_t::shutdown_both,
275 m_state.socket.connected =
false;
279 m_state.ssl.handshaked =
true;
284 const auto handshake = handshake_t::server;
285 static_cast<shared_state&
>(
290 [
this, self, on_handshake]{
294 m_state.data.read.buffer.data(),
295 m_state.ssl.forced ? 0 :
298 boost::asio::bind_executor(m_strand, on_handshake)
307 if (m_state.timers.throttle.in.wait_expire || m_state.socket.wait_read ||
308 m_state.socket.handle_read || m_state.socket.shutdown_read
313 if (speed_limit_is_enabled()) {
314 auto calc_duration = []{
316 network_throttle_manager_t::m_lock_get_global_throttle_in
318 return std::chrono::duration_cast<connection<T>::duration_t>(
319 std::chrono::duration<double, std::chrono::seconds::period>(
321 network_throttle_manager_t::get_global_throttle_in(
322 ).get_sleep_time_after_tick(1),
328 const auto duration = calc_duration();
330 m_timers.throttle.in.expires_after(duration);
331 m_state.timers.throttle.in.wait_expire =
true;
332 auto on_wait = [
this, self](
const ec_t &ec){
333 std::lock_guard<std::mutex> guard(m_state.lock);
334 m_state.timers.throttle.in.wait_expire =
false;
335 if (m_state.timers.throttle.in.cancel_expire) {
336 m_state.timers.throttle.in.cancel_expire =
false;
337 state_status_check();
342 m_timers.throttle.in.async_wait([
this, self, on_wait](
const ec_t &ec){
343 std::lock_guard<std::mutex> guard(m_state.lock);
344 const bool error_status = m_state.timers.throttle.in.cancel_expire || ec.value();
346 boost::asio::post(m_strand, std::bind(on_wait, ec));
348 m_state.timers.throttle.in.wait_expire =
false;
355 m_state.socket.wait_read =
true;
356 auto on_read = [
this, self](
const ec_t &ec,
size_t bytes_transferred){
357 std::lock_guard<std::mutex> guard(m_state.lock);
358 m_state.socket.wait_read =
false;
359 if (m_state.socket.cancel_read) {
360 m_state.socket.cancel_read =
false;
361 state_status_check();
367 m_state.stat.in.throttle.handle_trafic_exact(bytes_transferred);
368 const auto speed = m_state.stat.in.throttle.get_current_speed();
369 m_conn_context.m_current_speed_down =
speed;
370 m_conn_context.m_max_speed_down = std::max(
371 m_conn_context.m_max_speed_down,
374 if (speed_limit_is_enabled()) {
376 network_throttle_manager_t::m_lock_get_global_throttle_in
378 network_throttle_manager_t::get_global_throttle_in(
379 ).handle_trafic_exact(bytes_transferred);
381 connection_basic::logger_handle_net_read(bytes_transferred);
382 m_conn_context.m_last_recv = time(NULL);
383 m_conn_context.m_recv_cnt += bytes_transferred;
384 start_timer(get_timeout_from_bytes_read(bytes_transferred),
true);
386 finish_read(bytes_transferred);
389 if (!m_state.ssl.enabled)
390 connection_basic::socket_.next_layer().async_read_some(
392 m_state.data.read.buffer.data(),
393 m_state.data.read.buffer.size()
395 boost::asio::bind_executor(m_strand, on_read)
400 [
this, self, on_read]{
401 connection_basic::socket_.async_read_some(
403 m_state.data.read.buffer.data(),
404 m_state.data.read.buffer.size()
406 boost::asio::bind_executor(m_strand, on_read)
420 m_state.
socket.handle_read =
true;
423 connection_basic::strand_,
424 [
this, self, bytes_transferred]{
425 bool success = m_handler.handle_recv(
426 reinterpret_cast<char *
>(m_state.data.read.buffer.data()),
429 std::lock_guard<std::mutex> guard(m_state.lock);
430 const bool error_status = m_state.status == status_t::INTERRUPTED
431 || m_state.status == status_t::TERMINATING
434 m_state.socket.handle_read =
false;
442 std::lock_guard<std::mutex> guard(m_state.lock);
443 m_state.socket.handle_read =
false;
444 if (m_state.status == status_t::INTERRUPTED)
446 else if (m_state.status == status_t::TERMINATING)
450 if (m_state.socket.wait_write) {
452 connection_basic::socket_.next_layer().shutdown(
453 socket_t::shutdown_receive,
456 m_state.socket.shutdown_read =
true;
458 if (!m_state.socket.wait_write || ec.value()) {
471 if (m_state.timers.throttle.out.wait_expire || m_state.socket.wait_write ||
472 m_state.data.write.queue.empty() ||
473 (m_state.ssl.enabled && !m_state.ssl.handshaked)
478 if (speed_limit_is_enabled()) {
479 auto calc_duration = [
this]{
481 network_throttle_manager_t::m_lock_get_global_throttle_out
483 return std::chrono::duration_cast<connection<T>::duration_t>(
484 std::chrono::duration<double, std::chrono::seconds::period>(
486 network_throttle_manager_t::get_global_throttle_out(
487 ).get_sleep_time_after_tick(
488 m_state.data.write.queue.back().size()
495 const auto duration = calc_duration();
497 m_timers.throttle.out.expires_after(duration);
498 m_state.timers.throttle.out.wait_expire =
true;
499 auto on_wait = [
this, self](
const ec_t &ec){
500 std::lock_guard<std::mutex> guard(m_state.lock);
501 m_state.timers.throttle.out.wait_expire =
false;
502 if (m_state.timers.throttle.out.cancel_expire) {
503 m_state.timers.throttle.out.cancel_expire =
false;
504 state_status_check();
509 m_timers.throttle.out.async_wait([
this, self, on_wait](
const ec_t &ec){
510 std::lock_guard<std::mutex> guard(m_state.lock);
511 const bool error_status = m_state.timers.throttle.out.cancel_expire || ec.value();
513 boost::asio::post(m_strand, std::bind(on_wait, ec));
515 m_state.timers.throttle.out.wait_expire =
false;
522 m_state.socket.wait_write =
true;
523 auto on_write = [
this, self](
const ec_t &ec,
size_t bytes_transferred){
524 std::lock_guard<std::mutex> guard(m_state.lock);
525 m_state.socket.wait_write =
false;
526 if (m_state.socket.cancel_write) {
527 m_state.socket.cancel_write =
false;
528 m_state.data.write.queue.clear();
529 m_state.data.write.total_bytes = 0;
530 state_status_check();
532 else if (ec.value()) {
533 m_state.data.write.queue.clear();
534 m_state.data.write.total_bytes = 0;
539 m_state.stat.out.throttle.handle_trafic_exact(bytes_transferred);
540 const auto speed = m_state.stat.out.throttle.get_current_speed();
541 m_conn_context.m_current_speed_up =
speed;
542 m_conn_context.m_max_speed_down = std::max(
543 m_conn_context.m_max_speed_down,
546 if (speed_limit_is_enabled()) {
548 network_throttle_manager_t::m_lock_get_global_throttle_out
550 network_throttle_manager_t::get_global_throttle_out(
551 ).handle_trafic_exact(bytes_transferred);
553 connection_basic::logger_handle_net_write(bytes_transferred);
554 m_conn_context.m_last_send = time(NULL);
555 m_conn_context.m_send_cnt += bytes_transferred;
557 start_timer(get_default_timeout(),
true);
559 const std::size_t byte_count = m_state.data.write.queue.back().size();
560 assert(bytes_transferred == byte_count);
561 m_state.data.write.queue.pop_back();
562 m_state.data.write.total_bytes -=
563 std::min(m_state.data.write.total_bytes, byte_count);
564 m_state.condition.notify_all();
565 if (m_state.data.write.queue.empty() && m_state.socket.shutdown_read) {
573 if (!m_state.ssl.enabled)
574 boost::asio::async_write(
575 connection_basic::socket_.next_layer(),
577 m_state.data.write.queue.back().data(),
578 m_state.data.write.queue.back().size()
580 boost::asio::bind_executor(m_strand, on_write)
585 [
this, self, on_write]{
586 boost::asio::async_write(
587 connection_basic::socket_,
589 m_state.data.write.queue.back().data(),
590 m_state.data.write.queue.back().size()
592 boost::asio::bind_executor(m_strand, on_write)
601 if (m_state.socket.wait_shutdown)
604 m_state.socket.wait_shutdown =
true;
605 auto on_shutdown = [
this, self](
const ec_t &ec){
606 std::lock_guard<std::mutex> guard(m_state.lock);
607 m_state.socket.wait_shutdown =
false;
608 if (m_state.socket.cancel_shutdown) {
609 m_state.socket.cancel_shutdown =
false;
610 switch (m_state.status)
612 case status_t::RUNNING:
615 case status_t::INTERRUPTED:
618 case status_t::TERMINATING:
631 [
this, self, on_shutdown]{
632 connection_basic::socket_.async_shutdown(
633 boost::asio::bind_executor(m_strand, on_shutdown)
637 start_timer(get_default_timeout());
643 bool wait_socket =
false;
644 if (m_state.socket.wait_handshake)
645 wait_socket = m_state.
socket.cancel_handshake =
true;
646 if (m_state.timers.throttle.in.wait_expire) {
647 m_state.timers.throttle.in.cancel_expire =
true;
648 m_timers.throttle.in.cancel();
650 if (m_state.socket.wait_read)
651 wait_socket = m_state.socket.cancel_read =
true;
652 if (m_state.timers.throttle.out.wait_expire) {
653 m_state.timers.throttle.out.cancel_expire =
true;
654 m_timers.throttle.out.cancel();
656 if (m_state.socket.wait_write)
657 wait_socket = m_state.socket.cancel_write =
true;
658 if (m_state.socket.wait_shutdown)
659 wait_socket = m_state.socket.cancel_shutdown =
true;
662 connection_basic::socket_.next_layer().cancel(ec);
669 if (m_state.protocol.released || m_state.protocol.wait_release)
671 m_state.protocol.wait_release =
true;
672 m_state.lock.unlock();
673 m_handler.release_protocol();
675 m_state.protocol.wait_release =
false;
676 m_state.protocol.released =
true;
677 if (m_state.status == status_t::INTERRUPTED)
679 else if (m_state.status == status_t::TERMINATING)
686 if (m_state.status != status_t::RUNNING)
688 m_state.status = status_t::INTERRUPTED;
692 m_state.condition.notify_all();
699 assert(m_state.status == status_t::INTERRUPTED);
700 if (m_state.timers.general.wait_expire)
702 if (m_state.socket.wait_handshake)
704 if (m_state.timers.throttle.in.wait_expire)
706 if (m_state.socket.wait_read)
708 if (m_state.socket.handle_read)
710 if (m_state.timers.throttle.out.wait_expire)
715 if (m_state.socket.wait_shutdown)
717 if (m_state.protocol.wait_init)
719 if (m_state.protocol.wait_callback)
721 if (m_state.protocol.wait_release)
723 if (m_state.socket.connected) {
724 if (!m_state.ssl.enabled) {
726 connection_basic::socket_.next_layer().shutdown(
727 socket_t::shutdown_both,
730 connection_basic::socket_.next_layer().close(ec);
731 m_state.socket.connected =
false;
732 m_state.status = status_t::WASTED;
738 m_state.status = status_t::WASTED;
744 if (m_state.status != status_t::RUNNING &&
745 m_state.status != status_t::INTERRUPTED
748 m_state.status = status_t::TERMINATING;
752 m_state.condition.notify_all();
759 assert(m_state.status == status_t::TERMINATING);
760 if (m_state.timers.general.wait_expire)
762 if (m_state.socket.wait_handshake)
764 if (m_state.timers.throttle.in.wait_expire)
766 if (m_state.socket.wait_read)
768 if (m_state.socket.handle_read)
770 if (m_state.timers.throttle.out.wait_expire)
779 if (m_state.socket.wait_shutdown)
781 if (m_state.protocol.wait_init)
783 if (m_state.protocol.wait_callback)
785 if (m_state.protocol.wait_release)
787 if (m_state.socket.connected) {
789 connection_basic::socket_.next_layer().shutdown(
790 socket_t::shutdown_both,
793 connection_basic::socket_.next_layer().close(ec);
794 m_state.socket.connected =
false;
796 m_state.status = status_t::WASTED;
804 boost::asio::post(m_strand, [
this, self] {
805 std::lock_guard<std::mutex> guard(m_state.lock);
813 std::lock_guard<std::mutex> guard(m_state.lock);
814 if (m_state.status != status_t::RUNNING || m_state.socket.wait_handshake)
816 if (std::numeric_limits<std::size_t>::max() - m_state.data.write.total_bytes < message.size())
821 auto wait_consume = [
this] {
822 auto random_delay = []{
823 using engine = std::mt19937;
824 std::random_device
dev;
825 std::seed_seq::result_type rand[
828 std::generate_n(rand, engine::state_size, std::ref(
dev));
829 std::seed_seq
seed(rand, rand + engine::state_size);
831 return std::chrono::milliseconds(
832 std::uniform_int_distribution<>(5000, 6000)(rng)
844 m_state.data.write.wait_consume =
true;
845 bool success = m_state.condition.wait_for(
850 m_state.status != status_t::RUNNING ||
852 m_state.data.write.queue.size() <=
854 m_state.data.write.total_bytes <=
860 m_state.data.write.wait_consume =
false;
866 return m_state.status == status_t::RUNNING;
868 auto wait_sender = [
this] {
869 m_state.condition.wait(
873 m_state.status != status_t::RUNNING ||
874 !m_state.data.write.wait_consume
878 return m_state.status == status_t::RUNNING;
882 constexpr size_t CHUNK_SIZE = 32 * 1024;
884 message.size() <= 2 * CHUNK_SIZE
888 const std::size_t byte_count = message.size();
889 m_state.data.write.queue.emplace_front(std::move(message));
890 m_state.data.write.total_bytes += byte_count;
894 while (!message.empty()) {
897 m_state.data.write.queue.emplace_front(
898 message.take_slice(CHUNK_SIZE)
900 m_state.data.write.total_bytes += m_state.data.write.queue.front().size();
904 m_state.condition.notify_all();
911 bool is_multithreaded,
912 boost::optional<network_address> real_remote
915 std::unique_lock<std::mutex> guard(m_state.lock);
916 if (m_state.status != status_t::TERMINATED)
920 auto endpoint = connection_basic::socket_.next_layer().remote_endpoint(
926 endpoint.address().is_v6() ?
933 boost::asio::detail::socket_ops::host_to_network_long(
934 endpoint.address().to_v4().to_uint()
943 connection_basic::get_state()
945 if (filter && !filter->is_remote_host_allowed(*real_remote))
949 connection_basic::get_state()
951 if (is_income && limit && limit->is_host_limit(*real_remote))
955 #if !defined(_WIN32) || !defined(__i686)
956 connection_basic::socket_.next_layer().set_option(
957 boost::asio::detail::socket_option::integer<IPPROTO_IP, IP_TOS>{
958 connection_basic::get_tos_flag()
965 connection_basic::socket_.next_layer().set_option(
966 boost::asio::ip::tcp::no_delay{
false},
971 connection_basic::m_is_multithreaded = is_multithreaded;
972 m_conn_context.set_details(
973 boost::uuids::random_generator()(),
976 connection_basic::m_ssl_support == ssl_support_t::e_ssl_support_enabled
978 m_host = real_remote->host_str();
979 try { host_count(1); }
catch(...) { }
980 m_local = real_remote->is_loopback() || real_remote->is_local();
981 m_state.ssl.enabled = (
982 connection_basic::m_ssl_support != ssl_support_t::e_ssl_support_disabled
984 m_state.ssl.forced = (
985 connection_basic::m_ssl_support == ssl_support_t::e_ssl_support_enabled
987 m_state.socket.connected =
true;
988 m_state.status = status_t::RUNNING;
990 std::chrono::milliseconds(
994 m_state.protocol.wait_init =
true;
996 m_handler.after_init_connection();
998 m_state.protocol.wait_init =
false;
999 m_state.protocol.initialized =
true;
1000 if (m_state.status == status_t::INTERRUPTED)
1002 else if (m_state.status == status_t::TERMINATING)
1004 else if (!is_income || !m_state.ssl.enabled)
1011 template<
typename T>
1030 template<
typename T>
1041 m_connection_type(connection_type),
1042 m_io_context{io_context},
1043 m_conn_context(
std::move(initial)),
1044 m_strand{m_io_context},
1045 m_timers{m_io_context}
1049 template<
typename T>
1052 std::lock_guard<std::mutex> guard(m_state.lock);
1053 assert(m_state.status == status_t::TERMINATED ||
1054 m_state.status == status_t::WASTED ||
1055 m_io_context.stopped()
1057 if (m_state.status != status_t::WASTED)
1059 try { host_count(-1); }
catch (...) { }
1062 template<
typename T>
1065 bool is_multithreaded
1068 return start_internal(is_income, is_multithreaded, {});
1071 template<
typename T>
1074 bool is_multithreaded,
1078 return start_internal(is_income, is_multithreaded, real_remote);
1081 template<
typename T>
1084 std::lock_guard<std::mutex> guard(m_state.lock);
1091 port =
"<not connected>";
1094 address = endpoint.address().to_string();
1095 port = std::to_string(endpoint.port());
1098 " connection type " << std::to_string(m_connection_type) <<
1101 " <--> " << m_conn_context.m_remote_address.str() <<
1106 template<
typename T>
1112 template<
typename T>
1118 template<
typename T>
1121 return send(std::move(message));
1124 template<
typename T>
1130 template<
typename T>
1133 std::lock_guard<std::mutex> guard(m_state.lock);
1134 if (m_state.status != status_t::RUNNING)
1140 template<
typename T>
1144 if (!m_io_context.poll_one())
1148 if (!m_io_context.run_one())
1154 template<
typename T>
1157 std::lock_guard<std::mutex> guard(m_state.lock);
1158 if (m_state.status != status_t::RUNNING)
1161 ++m_state.protocol.wait_callback;
1163 m_handler.handle_qued_callback();
1164 std::lock_guard<std::mutex> guard(m_state.lock);
1165 --m_state.protocol.wait_callback;
1166 if (m_state.status == status_t::INTERRUPTED)
1168 else if (m_state.status == status_t::TERMINATING)
1174 template<
typename T>
1177 return m_io_context;
1180 template<
typename T>
1185 std::lock_guard<std::mutex> guard(m_state.lock);
1186 this->self = std::move(self);
1187 ++m_state.protocol.reference_counter;
1190 catch (boost::bad_weak_ptr &exception) {
1195 template<
typename T>
1199 std::lock_guard<std::mutex> guard(m_state.lock);
1200 if (!(--m_state.protocol.reference_counter))
1201 self = std::move(this->self);
1205 template<
typename T>
1208 std::lock_guard<std::mutex> guard(m_state.lock);
1212 template<
class t_protocol_handler>
1214 m_state(
std::make_shared<typename
connection<t_protocol_handler>::shared_state>()),
1215 m_io_context_local_instance(new
worker()),
1216 io_context_(m_io_context_local_instance->io_context),
1217 acceptor_(io_context_),
1218 acceptor_ipv6(io_context_),
1220 m_stop_signal_sent(
false), m_port(0),
1223 m_connection_type( connection_type ),
1225 new_connection_ipv6()
1231 template<
class t_protocol_handler>
1233 m_state(
std::make_shared<typename
connection<t_protocol_handler>::shared_state>()),
1234 io_context_(extarnal_io_context),
1235 acceptor_(io_context_),
1236 acceptor_ipv6(io_context_),
1238 m_stop_signal_sent(
false), m_port(0),
1241 m_connection_type(connection_type),
1243 new_connection_ipv6()
1249 template<
class t_protocol_handler>
1252 this->send_stop_signal();
1253 timed_wait_server_stop(10000);
1256 template<
class t_protocol_handler>
1264 template<
class t_protocol_handler>
1266 uint32_t port_ipv6,
const std::string& address_ipv6,
bool use_ipv6,
bool require_ipv4,
1270 m_stop_signal_sent =
false;
1272 m_port_ipv6 = port_ipv6;
1274 m_address_ipv6 = address_ipv6;
1275 m_use_ipv6 = use_ipv6;
1276 m_require_ipv4 = require_ipv4;
1279 m_state->configure_ssl(std::move(ssl_options));
1281 std::string ipv4_failed =
"";
1282 std::string ipv6_failed =
"";
1284 boost::asio::ip::tcp::resolver resolver(io_context_);
1288 const auto results = resolver.resolve(
1289 address, boost::lexical_cast<std::string>(
port), boost::asio::ip::tcp::resolver::canonical_name
1291 acceptor_.open(results.begin()->endpoint().protocol());
1293 acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(
true));
1295 acceptor_.bind(*results.begin());
1297 boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_.local_endpoint();
1298 m_port = binded_endpoint.port();
1299 MDEBUG(
"start accept (IPv4)");
1301 acceptor_.async_accept(new_connection_->socket(),
1303 boost::asio::placeholders::error));
1305 catch (
const std::exception &e)
1307 ipv4_failed = e.what();
1310 if (ipv4_failed !=
"")
1312 MERROR(
"Failed to bind IPv4: " << ipv4_failed);
1315 throw std::runtime_error(
"Failed to bind IPv4 (set to required)");
1323 if (port_ipv6 == 0) port_ipv6 =
port;
1325 const auto results = resolver.resolve(
1326 address_ipv6, boost::lexical_cast<std::string>(port_ipv6), boost::asio::ip::tcp::resolver::canonical_name
1329 acceptor_ipv6.open(results.begin()->endpoint().protocol());
1331 acceptor_ipv6.set_option(boost::asio::ip::tcp::acceptor::reuse_address(
true));
1333 acceptor_ipv6.set_option(boost::asio::ip::v6_only(
true));
1334 acceptor_ipv6.bind(*results.begin());
1335 acceptor_ipv6.listen();
1336 boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_ipv6.local_endpoint();
1337 m_port_ipv6 = binded_endpoint.port();
1338 MDEBUG(
"start accept (IPv6)");
1340 acceptor_ipv6.async_accept(new_connection_ipv6->socket(),
1342 boost::asio::placeholders::error));
1344 catch (
const std::exception &e)
1346 ipv6_failed = e.what();
1350 if (use_ipv6 && ipv6_failed !=
"")
1352 MERROR(
"Failed to bind IPv6: " << ipv6_failed);
1353 if (ipv4_failed !=
"")
1355 throw std::runtime_error(
"Failed to bind IPv4 and IPv6");
1361 catch (
const std::exception &e)
1363 MFATAL(
"Error starting server: " << e.what());
1368 MFATAL(
"Error starting server");
1373 template<
class t_protocol_handler>
1375 const std::string port_ipv6,
const std::string address_ipv6,
bool use_ipv6,
bool require_ipv4,
1382 MERROR(
"Failed to convert port no = " <<
port);
1387 MERROR(
"Failed to convert port no = " << port_ipv6);
1390 return this->init_server(p,
address, p_ipv6, address_ipv6, use_ipv6, require_ipv4, std::move(ssl_options));
1393 template<
class t_protocol_handler>
1397 const uint32_t local_thr_index = m_thread_index++;
1398 std::string thread_name = std::string(
"[") + m_thread_name_prefix;
1399 thread_name += boost::to_string(local_thr_index) +
"]";
1400 MLOG_SET_THREAD_NAME(thread_name);
1402 while(!m_stop_signal_sent)
1409 catch(
const std::exception& ex)
1411 _erro(
"Exception at server worker thread, what=" << ex.what());
1415 _erro(
"Exception at server worker thread, unknown execption");
1420 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::worker_thread",
false);
1423 template<
class t_protocol_handler>
1426 m_thread_name_prefix = prefix_name;
1427 auto it = server_type_map.find(m_thread_name_prefix);
1428 if (it==server_type_map.end())
throw std::runtime_error(
"Unknown prefix/server type:" + std::string(prefix_name));
1429 auto connection_type = it->second;
1430 MINFO(
"Set server type to: " << connection_type <<
" from name: " << m_thread_name_prefix <<
", prefix_name = " << prefix_name);
1433 template<
class t_protocol_handler>
1436 assert(m_state !=
nullptr);
1437 m_state->pfilter = pfilter;
1440 template<
class t_protocol_handler>
1443 assert(m_state !=
nullptr);
1444 m_state->plimit = plimit;
1447 template<
class t_protocol_handler>
1450 assert(m_state !=
nullptr);
1451 m_state->response_soft_limit = limit;
1454 template<
class t_protocol_handler>
1458 m_threads_count = threads_count;
1459 m_main_thread_id = boost::this_thread::get_id();
1460 MLOG_SET_THREAD_NAME(
"[SRV_MAIN]");
1461 while(!m_stop_signal_sent)
1466 for (std::size_t i = 0; i < threads_count; ++i)
1468 boost::shared_ptr<boost::thread> thread(
new boost::thread(
1470 _note(
"Run server thread name: " << m_thread_name_prefix);
1471 m_threads.push_back(thread);
1477 _fact(
"JOINING all threads");
1478 for (std::size_t i = 0; i < m_threads.size(); ++i) {
1479 m_threads[i]->join();
1481 _fact(
"JOINING all threads - almost");
1483 _fact(
"JOINING all threads - DONE");
1487 _dbg1(
"Reiniting OK.");
1491 if(wait && !m_stop_signal_sent)
1494 _dbg1(
"Net service stopped without stop request, restarting...");
1495 if(!this->init_server(m_port, m_address, m_port_ipv6, m_address_ipv6, m_use_ipv6, m_require_ipv4))
1497 _dbg1(
"Reiniting service failed, exit.");
1501 _dbg1(
"Reiniting OK.");
1506 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::run_server",
false);
1509 template<
class t_protocol_handler>
1514 BOOST_FOREACH(boost::shared_ptr<boost::thread>& thp, m_threads)
1516 if(thp->get_id() == boost::this_thread::get_id())
1519 if(m_threads_count == 1 && boost::this_thread::get_id() == m_main_thread_id)
1522 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::is_thread_worker",
false);
1525 template<
class t_protocol_handler>
1529 boost::chrono::milliseconds ms(wait_mseconds);
1530 for (std::size_t i = 0; i < m_threads.size(); ++i)
1532 if(m_threads[i]->joinable() && !m_threads[i]->try_join_for(ms))
1534 _dbg1(
"Interrupting thread " << m_threads[i]->native_handle());
1535 m_threads[i]->interrupt();
1539 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::timed_wait_server_stop",
false);
1542 template<
class t_protocol_handler>
1545 m_stop_signal_sent =
true;
1547 state->stop_signal_sent =
true;
1549 connections_mutex.lock();
1550 for (
auto &c: connections_)
1554 connections_.clear();
1555 connections_mutex.unlock();
1557 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::send_stop_signal()",
void());
1560 template<
class t_protocol_handler>
1563 this->handle_accept(e,
false);
1566 template<
class t_protocol_handler>
1569 this->handle_accept(e,
true);
1572 template<
class t_protocol_handler>
1575 MDEBUG(
"handle_accept");
1577 boost::asio::ip::tcp::acceptor* current_acceptor = &acceptor_;
1582 current_acceptor = &acceptor_ipv6;
1583 current_new_connection = &new_connection_ipv6;
1587 bool accept_started =
false;
1593 const char *ssl_message =
"unknown";
1594 switch ((*current_new_connection)->get_ssl_support())
1600 MDEBUG(
"New server for RPC connections, SSL " << ssl_message);
1601 (*current_new_connection)->setRpcStation();
1605 current_acceptor->async_accept((*current_new_connection)->socket(),
1606 boost::bind(accept_function_pointer,
this,
1607 boost::asio::placeholders::error));
1608 accept_started =
true;
1610 boost::asio::socket_base::keep_alive opt(
true);
1611 conn->socket().set_option(opt);
1615 res =
conn->start(
true, 1 < m_threads_count);
1617 res =
conn->start(
true, 1 < m_threads_count, default_remote);
1623 conn->save_dbg_log();
1628 MERROR(
"Error in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e);
1631 catch (
const std::exception &e)
1633 MERROR(
"Exception in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e.what());
1639 assert(m_state !=
nullptr);
1640 _erro(
"Some problems at accept: " << e.message() <<
", connections_count = " << m_state->sock_count);
1642 (*current_new_connection).reset(
new connection<t_protocol_handler>(io_context_, m_state, m_connection_type, (*current_new_connection)->get_ssl_support()));
1643 current_acceptor->async_accept((*current_new_connection)->socket(),
1644 boost::bind(accept_function_pointer,
this,
1645 boost::asio::placeholders::error));
1648 template<
class t_protocol_handler>
1651 if(std::addressof(get_io_context()) == std::addressof(sock.get_executor().context()))
1654 if(
conn->start(
false, 1 < m_threads_count, std::move(real_remote)))
1656 conn->get_context(out);
1657 conn->save_dbg_log();
1663 MWARNING(out <<
" was not added, socket/io_context mismatch");
1668 template<
class t_protocol_handler>
1673 sock_.open(remote_endpoint.protocol());
1674 if(bind_ip !=
"0.0.0.0" && bind_ip !=
"0" && bind_ip !=
"" )
1676 boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::make_address(bind_ip), 0);
1677 boost::system::error_code ec;
1678 sock_.bind(local_endpoint, ec);
1681 MERROR(
"Error binding to " << bind_ip <<
": " << ec.message());
1682 if (sock_.is_open())
1684 return CONNECT_FAILURE;
1692 boost::system::error_code ec = boost::asio::error::would_block;
1695 struct local_async_context
1697 boost::system::error_code ec;
1698 boost::mutex connect_mut;
1699 boost::condition_variable cond;
1702 boost::shared_ptr<local_async_context> local_shared_context(
new local_async_context());
1703 local_shared_context->ec = boost::asio::error::would_block;
1704 boost::unique_lock<boost::mutex> lock(local_shared_context->connect_mut);
1705 auto connect_callback = [](boost::system::error_code ec_, boost::shared_ptr<local_async_context> shared_context)
1707 shared_context->connect_mut.lock(); shared_context->ec = ec_; shared_context->cond.notify_one(); shared_context->connect_mut.unlock();
1710 sock_.async_connect(remote_endpoint, std::bind<void>(connect_callback, std::placeholders::_1, local_shared_context));
1711 while(local_shared_context->ec == boost::asio::error::would_block)
1713 bool r = local_shared_context->cond.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(conn_timeout));
1714 if (m_stop_signal_sent)
1716 if (sock_.is_open())
1718 return CONNECT_FAILURE;
1720 if(local_shared_context->ec == boost::asio::error::would_block && !r)
1724 _dbg3(
"Failed to connect to " << adr <<
":" <<
port <<
", because of timeout (" << conn_timeout <<
")");
1725 return CONNECT_FAILURE;
1728 ec = local_shared_context->ec;
1730 if (ec || !sock_.is_open())
1732 _dbg3(
"Some problems at connect, message: " << ec.message());
1733 if (sock_.is_open())
1735 return CONNECT_FAILURE;
1738 _dbg3(
"Connected success to " << adr <<
':' <<
port);
1740 const ssl_support_t ssl_support = new_connection_l->get_ssl_support();
1744 MDEBUG(
"Handshaking SSL...");
1745 if (!new_connection_l->handshake(boost::asio::ssl::stream_base::client))
1749 boost::system::error_code ignored_ec;
1750 sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
1752 return CONNECT_NO_SSL;
1754 MERROR(
"SSL handshake failed");
1755 if (sock_.is_open())
1757 return CONNECT_FAILURE;
1761 return CONNECT_SUCCESS;
1763 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::try_connect", CONNECT_FAILURE);
1766 template<
class t_protocol_handler>
1772 connections_mutex.lock();
1773 connections_.insert(new_connection_l);
1774 MDEBUG(
"connections_ size now " << connections_.size());
1775 connections_mutex.unlock();
1777 boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket();
1779 bool try_ipv6 =
false;
1781 boost::asio::ip::tcp::resolver resolver(io_context_);
1782 boost::asio::ip::tcp::resolver::results_type results{};
1783 boost::system::error_code resolve_error;
1788 results = resolver.resolve(
1789 boost::asio::ip::tcp::v4(), adr,
port, boost::asio::ip::tcp::resolver::canonical_name, resolve_error
1792 catch (
const boost::system::system_error& e)
1794 if (!m_use_ipv6 || (resolve_error != boost::asio::error::host_not_found &&
1795 resolve_error != boost::asio::error::host_not_found_try_again))
1806 std::string bind_ip_to_use;
1812 _erro(
"Failed to resolve " << adr);
1818 MINFO(
"Resolving address as IPv4 failed, trying IPv6");
1823 bind_ip_to_use = bind_ip;
1828 results = resolver.resolve(
1829 boost::asio::ip::tcp::v6(), adr,
port, boost::asio::ip::tcp::resolver::canonical_name, resolve_error
1834 _erro(
"Failed to resolve " << adr);
1839 if (bind_ip ==
"0.0.0.0")
1841 bind_ip_to_use =
"::";
1845 bind_ip_to_use =
"";
1852 const auto iterator = results.begin();
1854 MDEBUG(
"Trying to connect to " << adr <<
":" <<
port <<
", bind_ip = " << bind_ip_to_use);
1857 boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
1859 auto try_connect_result = try_connect(new_connection_l, adr,
port, sock_, remote_endpoint, bind_ip_to_use, conn_timeout, ssl_support);
1860 if (try_connect_result == CONNECT_FAILURE)
1865 MERROR(
"SSL handshake failed on an autodetect connection, reconnecting without SSL");
1866 new_connection_l->disable_ssl();
1868 if (try_connect_result != CONNECT_SUCCESS)
1873 connections_mutex.lock();
1874 connections_.erase(new_connection_l);
1875 connections_mutex.unlock();
1876 bool r = new_connection_l->start(
false, 1 < m_threads_count);
1879 new_connection_l->get_context(conn_context);
1883 assert(m_state !=
nullptr);
1884 _erro(
"[sock " << new_connection_l->socket().native_handle() <<
"] Failed to start connection, connections_count = " << m_state->sock_count);
1887 new_connection_l->save_dbg_log();
1891 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::connect",
false);
1894 template<
class t_protocol_handler>
template<
class t_callback>
1899 connections_mutex.lock();
1900 connections_.insert(new_connection_l);
1901 MDEBUG(
"connections_ size now " << connections_.size());
1902 connections_mutex.unlock();
1904 boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket();
1906 bool try_ipv6 =
false;
1908 boost::asio::ip::tcp::resolver resolver(io_context_);
1909 boost::asio::ip::tcp::resolver::results_type results{};
1910 boost::system::error_code resolve_error;
1915 results = resolver.resolve(
1916 boost::asio::ip::tcp::v4(), adr,
port, boost::asio::ip::tcp::resolver::canonical_name, resolve_error
1919 catch (
const boost::system::system_error& e)
1921 if (!m_use_ipv6 || (resolve_error != boost::asio::error::host_not_found &&
1922 resolve_error != boost::asio::error::host_not_found_try_again))
1937 _erro(
"Failed to resolve " << adr);
1942 MINFO(
"Resolving address as IPv4 failed, trying IPv6");
1948 results = resolver.resolve(
1949 boost::asio::ip::tcp::v6(), adr,
port, boost::asio::ip::tcp::resolver::canonical_name, resolve_error
1954 _erro(
"Failed to resolve " << adr);
1959 boost::asio::ip::tcp::endpoint remote_endpoint(*results.begin());
1961 sock_.open(remote_endpoint.protocol());
1962 if(bind_ip !=
"0.0.0.0" && bind_ip !=
"0" && bind_ip !=
"" )
1964 boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::make_address(bind_ip.c_str()), 0);
1965 boost::system::error_code ec;
1966 sock_.bind(local_endpoint, ec);
1969 MERROR(
"Error binding to " << bind_ip <<
": " << ec.message());
1970 if (sock_.is_open())
1976 boost::shared_ptr<boost::asio::deadline_timer> sh_deadline(
new boost::asio::deadline_timer(io_context_));
1978 sh_deadline->expires_from_now(boost::posix_time::milliseconds(conn_timeout));
1979 sh_deadline->async_wait([=](
const boost::system::error_code& error)
1981 if(error != boost::asio::error::operation_aborted)
1983 _dbg3(
"Failed to connect to " << adr <<
':' <<
port <<
", because of timeout (" << conn_timeout <<
")");
1984 new_connection_l->socket().close();
1988 sock_.async_connect(remote_endpoint, [=](
const boost::system::error_code& ec_)
1991 boost::system::error_code ignored_ec;
1992 boost::asio::ip::tcp::socket::endpoint_type lep = new_connection_l->socket().local_endpoint(ignored_ec);
1995 if(!sh_deadline->cancel())
1997 cb(conn_context, boost::asio::error::operation_aborted);
2000 _dbg3(
"[sock " << new_connection_l->socket().native_handle() <<
"] Connected success to " << adr <<
':' <<
port <<
2001 " from " << lep.address().to_string() <<
':' << lep.port());
2004 connections_mutex.lock();
2005 connections_.erase(new_connection_l);
2006 connections_mutex.unlock();
2007 bool r = new_connection_l->start(
false, 1 < m_threads_count);
2010 new_connection_l->get_context(conn_context);
2011 cb(conn_context, ec_);
2015 _dbg3(
"[sock " << new_connection_l->socket().native_handle() <<
"] Failed to start connection to " << adr <<
':' <<
port);
2016 cb(conn_context, boost::asio::error::fault);
2021 _dbg3(
"[sock " << new_connection_l->socket().native_handle() <<
"] Failed to connect to " << adr <<
':' <<
port <<
2022 " from " << lep.address().to_string() <<
':' << lep.port() <<
": " << ec_.message() <<
':' << ec_.value());
2023 cb(conn_context, ec_);
2027 CATCH_ENTRY_L0(
"boosted_tcp_server<t_protocol_handler>::connect_async",
false);
#define ABSTRACT_SERVER_SEND_QUE_MAX_COUNT
Definition abstract_tcp_server2.h:67
#define NEW_CONNECTION_TIMEOUT_LOCAL
Definition abstract_tcp_server2.inl:59
#define NEW_CONNECTION_TIMEOUT_REMOTE
Definition abstract_tcp_server2.inl:60
#define TIMEOUT_EXTRA_MS_PER_BYTE
Definition abstract_tcp_server2.inl:63
#define AGGRESSIVE_TIMEOUT_THRESHOLD
Definition abstract_tcp_server2.inl:58
#define DEFAULT_TIMEOUT_MS_LOCAL
Definition abstract_tcp_server2.inl:61
#define DEFAULT_TIMEOUT_MS_REMOTE
Definition abstract_tcp_server2.inl:62
static void close()
Definition blockchain_blackball.cpp:279
Definition byte_slice.h:69
Definition abstract_tcp_server2.h:347
boost::shared_ptr< connection< t_protocol_handler > > connection_ptr
Definition abstract_tcp_server2.h:356
try_connect_result_t
Definition abstract_tcp_server2.h:349
~boosted_tcp_server()
Definition abstract_tcp_server2.inl:1250
t_protocol_handler::connection_context t_connection_context
Definition abstract_tcp_server2.h:357
boosted_tcp_server(t_connection_type connection_type)
Definition abstract_tcp_server2.inl:1213
void create_server_type_map()
Definition abstract_tcp_server2.inl:1257
std::string m_thread_name_prefix
Definition abstract_tcp_server2.h:532
bool init_server(uint32_t port, const std::string &address="0.0.0.0", uint32_t port_ipv6=0, const std::string &address_ipv6="::", bool use_ipv6=false, bool require_ipv4=true, ssl_options_t ssl_options=ssl_support_t::e_ssl_support_autodetect)
Definition abstract_tcp_server2.inl:1265
std::atomic< long > sock_count
Definition connection_basic.hpp:67
Definition connection_basic.hpp:101
boost::asio::ssl::stream< boost::asio::ip::tcp::socket > socket_
Socket for the connection.
Definition connection_basic.hpp:117
boost::asio::io_context::strand strand_
Strand to ensure the connection's handlers are not called concurrently.
Definition connection_basic.hpp:115
boost::asio::ip::tcp::socket & socket()
Definition connection_basic.hpp:130
connection_basic_shared_state & get_state() noexcept
Definition connection_basic.hpp:128
volatile bool m_is_multithreaded
Definition connection_basic.hpp:113
Represents a single connection from a client.
Definition abstract_tcp_server2.h:100
void setRpcStation()
Definition abstract_tcp_server2.inl:1206
virtual bool call_run_once_service_io()
Definition abstract_tcp_server2.inl:1141
boost::asio::ip::tcp::socket socket_t
Definition abstract_tcp_server2.h:114
virtual bool send_done()
Definition abstract_tcp_server2.inl:1125
void start_timer(duration_t duration, bool add={})
Definition abstract_tcp_server2.inl:144
t_protocol_handler::connection_context t_connection_context
Definition abstract_tcp_server2.h:102
boost::asio::io_context io_context_t
Definition abstract_tcp_server2.h:112
void async_wait_timer()
Definition abstract_tcp_server2.inl:168
connection(io_context_t &io_context, std::shared_ptr< shared_state > state, t_connection_type connection_type, epee::net_utils::ssl_support_t ssl_support, t_connection_context &&initial=t_connection_context{})
Construct a connection with the given io_context.
Definition abstract_tcp_server2.inl:1012
virtual bool do_send(byte_slice message)
(see do_send from i_service_endpoint)
Definition abstract_tcp_server2.inl:1119
virtual bool release()
Definition abstract_tcp_server2.inl:1196
virtual bool request_callback()
Definition abstract_tcp_server2.inl:1155
bool speed_limit_is_enabled() const
tells us should we be sleeping here (e.g. do not sleep on RPC connections)
Definition abstract_tcp_server2.inl:1107
boost::shared_ptr< connection_t > connection_ptr
Definition abstract_tcp_server2.h:105
void start_handshake()
Definition abstract_tcp_server2.inl:209
virtual io_context_t & get_io_context()
Definition abstract_tcp_server2.inl:1175
duration_t get_timeout_from_bytes_read(size_t bytes) const
Definition abstract_tcp_server2.inl:115
virtual ~connection() noexcept(false)
Definition abstract_tcp_server2.inl:1050
void cancel_timer()
Definition abstract_tcp_server2.inl:199
void state_status_check()
Definition abstract_tcp_server2.inl:125
void save_dbg_log()
Definition abstract_tcp_server2.inl:1082
virtual bool add_ref()
Definition abstract_tcp_server2.inl:1181
unsigned int host_count(int delta=0)
Definition abstract_tcp_server2.inl:81
bool start(bool is_income, bool is_multithreaded)
Start the first asynchronous operation for the connection.
Definition abstract_tcp_server2.inl:1063
timer_t::duration duration_t
Definition abstract_tcp_server2.h:108
bool cancel()
Definition abstract_tcp_server2.inl:1113
virtual bool close()
Definition abstract_tcp_server2.inl:1131
duration_t get_default_timeout()
Definition abstract_tcp_server2.inl:98
boost::system::error_code ec_t
Definition abstract_tcp_server2.h:109
Definition net_utils_base.h:69
constexpr uint16_t port() const noexcept
Definition net_utils_base.h:87
Definition net_utils_base.h:172
uint16_t port() const noexcept
Definition net_utils_base.h:193
Definition net_utils_base.h:225
const uint8_t seed[32]
Definition code-generator.cpp:37
bool success
Definition cold-transaction.cpp:57
std::unique_ptr< test_connection > conn(new test_connection(io_service, m_handler_config))
int * count
Definition gmock_stress_test.cc:176
const char * res
Definition hmac_keccak.cpp:42
static int dev
Definition ipfrdr.c:126
uint32_t address
Definition getifaddr.c:269
#define AUTO_VAL_INIT(v)
Definition misc_language.h:36
Definition portable_binary_archive.hpp:29
boost::shared_ptr< call_befor_die_base > auto_scope_leave_caller
Definition misc_language.h:80
bool sleep_no_w(long ms)
Definition misc_language.cpp:35
auto_scope_leave_caller create_scope_leave_handler(t_scope_leave_handler f)
Definition misc_language.h:97
T & check_and_get(std::shared_ptr< T > &ptr)
Definition abstract_tcp_server2.inl:71
std::string to_string(t_connection_type type)
Definition connection_basic.cpp:70
bool is_ssl(const unsigned char *data, size_t len)
Definition net_ssl.cpp:424
constexpr size_t get_ssl_magic_size()
Definition net_ssl.h:150
t_connection_type
Definition connection_basic.hpp:93
@ e_connection_type_NET
Definition connection_basic.hpp:94
@ e_connection_type_RPC
Definition connection_basic.hpp:95
@ e_connection_type_P2P
Definition connection_basic.hpp:96
ssl_support_t
Definition net_ssl.h:49
@ e_ssl_support_autodetect
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
if(!cryptonote::get_account_address_from_str_or_url(info, cryptonote::TESTNET, "9uVsvEryzpN8WH2t1WWhFFCG5tS8cBNdmJYNRuckLENFimfauV5pZKeS1P2CbxGkSDTUPHXWwiYE5ZGSXDAGbaZgDxobqDN"))
Definition signature.cpp:53
boost::endian::big_uint16_t port
Definition socks.cpp:61
#define false
Definition stdbool.h:37
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
The io_context used to perform asynchronous operations.
Definition abstract_tcp_server2.h:509
Definition abstract_tcp_server2.h:274
std::size_t response_soft_limit
Definition abstract_tcp_server2.h:286
Definition abstract_tcp_server2.h:76
Definition abstract_tcp_server2.h:83
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153
#define CRITICAL_REGION_END()
Definition syncobj.h:158
#define CRITICAL_REGION_BEGIN(x)
Definition syncobj.h:154