diff options
Diffstat (limited to 'contrib/epee/include/net')
-rw-r--r-- | contrib/epee/include/net/abstract_tcp_server2.inl | 4 | ||||
-rw-r--r-- | contrib/epee/include/net/http_client.h | 12 | ||||
-rw-r--r-- | contrib/epee/include/net/net_helper.h | 140 | ||||
-rw-r--r-- | contrib/epee/include/net/net_utils_base.h | 194 |
4 files changed, 234 insertions, 116 deletions
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 76988a26e..94ef7c3b3 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -137,14 +137,14 @@ PRAGMA_WARNING_DISABLE_VS(4355) CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value()); context = boost::value_initialized<t_connection_context>(); - long ip_ = boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong()); + const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())}; // 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>(); - context.set_details(random_uuid, new epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income); + 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) << " to " << local_ep.address().to_string() << ':' << local_ep.port() << ", total sockets objects " << m_ref_sock_count); diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 8e099e2bc..ed89ca0c7 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -274,6 +274,7 @@ using namespace std; chunked_state m_chunked_state; std::string m_chunked_cache; critical_section m_lock; + bool m_ssl; public: explicit http_simple_client() @@ -291,33 +292,35 @@ using namespace std; , m_chunked_state() , m_chunked_cache() , m_lock() + , m_ssl(false) {} const std::string &get_host() const { return m_host_buff; }; const std::string &get_port() const { return m_port; }; - bool set_server(const std::string& address, boost::optional<login> user) + bool set_server(const std::string& address, boost::optional<login> user, bool ssl = false) { http::url_content parsed{}; const bool r = parse_url(address, parsed); CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address); - set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user)); + set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), ssl); return true; } - void set_server(std::string host, std::string port, boost::optional<login> user) + void set_server(std::string host, std::string port, boost::optional<login> user, bool ssl = false) { CRITICAL_REGION_LOCAL(m_lock); disconnect(); m_host_buff = std::move(host); m_port = std::move(port); m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{}; + m_ssl = ssl; } bool connect(std::chrono::milliseconds timeout) { CRITICAL_REGION_LOCAL(m_lock); - return m_net_client.connect(m_host_buff, m_port, timeout); + return m_net_client.connect(m_host_buff, m_port, timeout, m_ssl); } //--------------------------------------------------------------------------- bool disconnect() @@ -392,7 +395,6 @@ using namespace std; res = m_net_client.send(body, timeout); CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND"); - m_response_info.clear(); m_state = reciev_machine_state_header; if (!handle_reciev(timeout)) diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 1d808cc4c..c8e4c7818 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -37,6 +37,7 @@ #include <ostream> #include <string> #include <boost/asio.hpp> +#include <boost/asio/ssl.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/preprocessor/selection/min.hpp> #include <boost/lambda/bind.hpp> @@ -85,11 +86,13 @@ namespace net_utils public: inline - blocked_mode_client():m_socket(m_io_service), - m_initialized(false), + blocked_mode_client():m_initialized(false), m_connected(false), m_deadline(m_io_service), - m_shutdowned(0) + m_shutdowned(0), + m_ssl(false), + m_ctx(boost::asio::ssl::context::sslv23), + m_ssl_socket(m_io_service,m_ctx) { @@ -113,18 +116,25 @@ namespace net_utils } inline - bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0") + bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") { - return connect(addr, std::to_string(port), timeout, bind_ip); + return connect(addr, std::to_string(port), timeout, ssl, bind_ip); } inline - bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0") + bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") { m_connected = false; + m_ssl = ssl; try { - m_socket.close(); + m_ssl_socket.next_layer().close(); + + // Set SSL options + // disable sslv2 + m_ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); + m_ctx.set_default_verify_paths(); + // Get a list of endpoints corresponding to the server name. @@ -147,11 +157,11 @@ namespace net_utils boost::asio::ip::tcp::endpoint remote_endpoint(*iterator); - m_socket.open(remote_endpoint.protocol()); + m_ssl_socket.next_layer().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(addr.c_str()), 0); - m_socket.bind(local_endpoint); + m_ssl_socket.next_layer().bind(local_endpoint); } @@ -160,17 +170,24 @@ namespace net_utils boost::system::error_code ec = boost::asio::error::would_block; - //m_socket.connect(remote_endpoint); - m_socket.async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1); + m_ssl_socket.next_layer().async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1); while (ec == boost::asio::error::would_block) { m_io_service.run_one(); } - if (!ec && m_socket.is_open()) + if (!ec && m_ssl_socket.next_layer().is_open()) { m_connected = true; m_deadline.expires_at(std::chrono::steady_clock::time_point::max()); + // SSL Options + if(m_ssl) { + // Disable verification of host certificate + m_ssl_socket.set_verify_mode(boost::asio::ssl::verify_peer); + // Handshake + m_ssl_socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true)); + m_ssl_socket.handshake(boost::asio::ssl::stream_base::client); + } return true; }else { @@ -193,7 +210,6 @@ namespace net_utils return true; } - inline bool disconnect() { @@ -202,8 +218,9 @@ namespace net_utils if(m_connected) { m_connected = false; - m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both); - + if(m_ssl) + shutdown_ssl(); + m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both); } } @@ -240,7 +257,7 @@ namespace net_utils // object is used as a callback and will update the ec variable when the // operation completes. The blocking_udp_client.cpp example shows how you // can use boost::bind rather than boost::lambda. - boost::asio::async_write(m_socket, boost::asio::buffer(buff), boost::lambda::var(ec) = boost::lambda::_1); + async_write(buff.c_str(), buff.size(), ec); // Block until the asynchronous operation has completed. while (ec == boost::asio::error::would_block) @@ -302,9 +319,7 @@ namespace net_utils */ boost::system::error_code ec; - size_t writen = m_socket.write_some(boost::asio::buffer(data, sz), ec); - - + size_t writen = write(data, sz, ec); if (!writen || ec) { @@ -334,10 +349,7 @@ namespace net_utils bool is_connected() { - return m_connected && m_socket.is_open(); - //TRY_ENTRY() - //return m_socket.is_open(); - //CATCH_ENTRY_L0("is_connected", false) + return m_connected && m_ssl_socket.next_layer().is_open(); } inline @@ -369,8 +381,8 @@ namespace net_utils handler_obj hndlr(ec, bytes_transfered); char local_buff[10000] = {0}; - //m_socket.async_read_some(boost::asio::buffer(local_buff, sizeof(local_buff)), hndlr); - boost::asio::async_read(m_socket, boost::asio::buffer(local_buff, sizeof(local_buff)), boost::asio::transfer_at_least(1), hndlr); + + async_read(local_buff, boost::asio::transfer_at_least(1), hndlr); // Block until the asynchronous operation has completed. while (ec == boost::asio::error::would_block && !boost::interprocess::ipcdetail::atomic_read32(&m_shutdowned)) @@ -451,10 +463,8 @@ namespace net_utils handler_obj hndlr(ec, bytes_transfered); - - //char local_buff[10000] = {0}; - boost::asio::async_read(m_socket, boost::asio::buffer((char*)buff.data(), buff.size()), boost::asio::transfer_at_least(buff.size()), hndlr); - + async_read((char*)buff.data(), boost::asio::transfer_at_least(buff.size()), hndlr); + // Block until the asynchronous operation has completed. while (ec == boost::asio::error::would_block && !boost::interprocess::ipcdetail::atomic_read32(&m_shutdowned)) { @@ -500,10 +510,18 @@ namespace net_utils bool shutdown() { m_deadline.cancel(); - boost::system::error_code ignored_ec; - m_socket.cancel(ignored_ec); - m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); - m_socket.close(ignored_ec); + boost::system::error_code ec; + if(m_ssl) + shutdown_ssl(); + m_ssl_socket.next_layer().cancel(ec); + if(ec) + MDEBUG("Problems at cancel: " << ec.message()); + m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + if(ec) + MDEBUG("Problems at shutdown: " << ec.message()); + m_ssl_socket.next_layer().close(ec); + if(ec) + MDEBUG("Problems at close: " << ec.message()); boost::interprocess::ipcdetail::atomic_write32(&m_shutdowned, 1); m_connected = false; return true; @@ -520,7 +538,7 @@ namespace net_utils boost::asio::ip::tcp::socket& get_socket() { - return m_socket; + return m_ssl_socket.next_layer(); } private: @@ -537,7 +555,7 @@ namespace net_utils // connect(), read_line() or write_line() functions to return. LOG_PRINT_L3("Timed out socket"); m_connected = false; - m_socket.close(); + m_ssl_socket.next_layer().close(); // There is no longer an active deadline. The expiry is set to positive // infinity so that the actor takes no action until a new deadline is set. @@ -547,12 +565,54 @@ namespace net_utils // Put the actor back to sleep. m_deadline.async_wait(boost::bind(&blocked_mode_client::check_deadline, this)); } - + void shutdown_ssl() { + // ssl socket shutdown blocks if server doesn't respond. We close after 2 secs + boost::system::error_code ec = boost::asio::error::would_block; + m_deadline.expires_from_now(std::chrono::milliseconds(2000)); + m_ssl_socket.async_shutdown(boost::lambda::var(ec) = boost::lambda::_1); + while (ec == boost::asio::error::would_block) + { + m_io_service.run_one(); + } + // Ignore "short read" error + if (ec.category() == boost::asio::error::get_ssl_category() && ec.value() != ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) + MDEBUG("Problems at ssl shutdown: " << ec.message()); + } + + protected: + bool write(const void* data, size_t sz, boost::system::error_code& ec) + { + bool success; + if(m_ssl) + success = boost::asio::write(m_ssl_socket, boost::asio::buffer(data, sz), ec); + else + success = boost::asio::write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), ec); + return success; + } + + void async_write(const void* data, size_t sz, boost::system::error_code& ec) + { + if(m_ssl) + boost::asio::async_write(m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); + else + boost::asio::async_write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); + } + + void async_read(char* buff, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj& hndlr) + { + if(!m_ssl) + boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(buff, sizeof(buff)), transfer_at_least, hndlr); + else + boost::asio::async_read(m_ssl_socket, boost::asio::buffer(buff, sizeof(buff)), transfer_at_least, hndlr); + + } protected: boost::asio::io_service m_io_service; - boost::asio::ip::tcp::socket m_socket; + boost::asio::ssl::context m_ctx; + boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_ssl_socket; + bool m_ssl; bool m_initialized; bool m_connected; boost::asio::steady_timer m_deadline; @@ -618,8 +678,8 @@ namespace net_utils boost::system::error_code ec; - size_t writen = m_socket.write_some(boost::asio::buffer(data, sz), ec); - + size_t writen = write(data, sz, ec); + if (!writen || ec) { LOG_PRINT_L3("Problems at write: " << ec.message()); @@ -660,7 +720,7 @@ namespace net_utils // asynchronous operations are cancelled. This allows the blocked // connect(), read_line() or write_line() functions to return. LOG_PRINT_L3("Timed out socket"); - m_socket.close(); + m_ssl_socket.next_layer().close(); // There is no longer an active deadline. The expiry is set to positive // infinity so that the actor takes no action until a new deadline is set. diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h index df83517ff..0e31ee86f 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/net/net_utils_base.h @@ -29,11 +29,12 @@ #ifndef _NET_UTILS_BASE_H_ #define _NET_UTILS_BASE_H_ -#include <typeinfo> #include <boost/asio/io_service.hpp> #include <boost/uuid/uuid.hpp> +#include <memory> +#include <typeinfo> +#include <type_traits> #include "serialization/keyvalue_serialization.h" -#include "net/local_ip.h" #include "string_tools.h" #include "misc_log_ex.h" @@ -49,78 +50,119 @@ namespace epee { namespace net_utils { - struct network_address_base + class ipv4_network_address { - public: - bool operator==(const network_address_base &other) const { return m_full_id == other.m_full_id; } - bool operator!=(const network_address_base &other) const { return !operator==(other); } - bool operator<(const network_address_base &other) const { return m_full_id < other.m_full_id; } - bool is_same_host(const network_address_base &other) const { return m_host_id == other.m_host_id; } - virtual std::string str() const = 0; - virtual std::string host_str() const = 0; - virtual bool is_loopback() const = 0; - virtual bool is_local() const = 0; - virtual uint8_t get_type_id() const = 0; - protected: - // A very simple non cryptographic hash function by Fowler, Noll, Vo - uint64_t fnv1a(const uint8_t *data, size_t len) const { - uint64_t h = 0xcbf29ce484222325; - while (len--) - h = (h ^ *data++) * 0x100000001b3; - return h; - } - uint64_t m_host_id; - uint64_t m_full_id; + uint32_t m_ip; + uint16_t m_port; - protected: - virtual ~network_address_base() {} - }; - struct ipv4_network_address: public network_address_base - { - void init_ids() - { - m_host_id = fnv1a((const uint8_t*)&m_ip, sizeof(m_ip)); - m_full_id = fnv1a((const uint8_t*)&m_ip, sizeof(m_ip) + sizeof(m_port)); - } public: - ipv4_network_address(uint32_t ip, uint16_t port): network_address_base(), m_ip(ip), m_port(port) { init_ids(); } - uint32_t ip() const { return m_ip; } - uint16_t port() const { return m_port; } - virtual std::string str() const { return epee::string_tools::get_ip_string_from_int32(m_ip) + ":" + std::to_string(m_port); } - virtual std::string host_str() const { return epee::string_tools::get_ip_string_from_int32(m_ip); } - virtual bool is_loopback() const { return epee::net_utils::is_ip_loopback(m_ip); } - virtual bool is_local() const { return epee::net_utils::is_ip_local(m_ip); } - virtual uint8_t get_type_id() const { return ID; } - public: // serialization + constexpr ipv4_network_address(uint32_t ip, uint16_t port) noexcept + : m_ip(ip), m_port(port) {} + + bool equal(const ipv4_network_address& other) const noexcept; + bool less(const ipv4_network_address& other) const noexcept; + constexpr bool is_same_host(const ipv4_network_address& other) const noexcept + { return ip() == other.ip(); } + + constexpr uint32_t ip() const noexcept { return m_ip; } + constexpr uint16_t port() const noexcept { return m_port; } + std::string str() const; + std::string host_str() const; + bool is_loopback() const; + bool is_local() const; + static constexpr uint8_t get_type_id() noexcept { return ID; } + static const uint8_t ID = 1; -#pragma pack(push) -#pragma pack(1) - uint32_t m_ip; - uint16_t m_port; -#pragma pack(pop) BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(m_ip) KV_SERIALIZE(m_port) - if (!is_store) - const_cast<ipv4_network_address&>(this_ref).init_ids(); END_KV_SERIALIZE_MAP() }; - class network_address: public boost::shared_ptr<network_address_base> + + inline bool operator==(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return lhs.equal(rhs); } + inline bool operator!=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !lhs.equal(rhs); } + inline bool operator<(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return lhs.less(rhs); } + inline bool operator<=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !rhs.less(lhs); } + inline bool operator>(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return rhs.less(lhs); } + inline bool operator>=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !lhs.less(rhs); } + + class network_address { + struct interface + { + virtual ~interface() {}; + + virtual bool equal(const interface&) const = 0; + virtual bool less(const interface&) const = 0; + virtual bool is_same_host(const interface&) const = 0; + + virtual std::string str() const = 0; + virtual std::string host_str() const = 0; + virtual bool is_loopback() const = 0; + virtual bool is_local() const = 0; + virtual uint8_t get_type_id() const = 0; + }; + + template<typename T> + struct implementation final : interface + { + T value; + + implementation(const T& src) : value(src) {} + ~implementation() = default; + + // Type-checks for cast are done in cpp + static const T& cast(const interface& src) noexcept + { return static_cast<const implementation<T>&>(src).value; } + + virtual bool equal(const interface& other) const override + { return value.equal(cast(other)); } + + virtual bool less(const interface& other) const override + { return value.less(cast(other)); } + + virtual bool is_same_host(const interface& other) const override + { return value.is_same_host(cast(other)); } + + virtual std::string str() const override { return value.str(); } + virtual std::string host_str() const override { return value.host_str(); } + virtual bool is_loopback() const override { return value.is_loopback(); } + virtual bool is_local() const override { return value.is_local(); } + virtual uint8_t get_type_id() const override { return value.get_type_id(); } + }; + + std::shared_ptr<interface> self; + + template<typename Type> + Type& as_mutable() const + { + // types `implmentation<Type>` and `implementation<const Type>` are unique + using Type_ = typename std::remove_const<Type>::type; + network_address::interface* const self_ = self.get(); // avoid clang warning in typeid + if (!self_ || typeid(implementation<Type_>) != typeid(*self_)) + throw std::bad_cast{}; + return static_cast<implementation<Type_>*>(self_)->value; + } public: - network_address() {} - network_address(ipv4_network_address *address): boost::shared_ptr<network_address_base>(address) {} - bool operator==(const network_address &other) const { return (*this)->operator==(*other); } - bool operator!=(const network_address &other) const { return (*this)->operator!=(*other); } - bool operator<(const network_address &other) const { return (*this)->operator<(*other); } - bool is_same_host(const network_address &other) const { return (*this)->is_same_host(*other); } - std::string str() const { return (*this) ? (*this)->str() : "<none>"; } - std::string host_str() const { return (*this) ? (*this)->host_str() : "<none>"; } - bool is_loopback() const { return (*this)->is_loopback(); } - bool is_local() const { return (*this)->is_local(); } - uint8_t get_type_id() const { return (*this)->get_type_id(); } - template<typename Type> Type &as() { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(Type*)get(); } - template<typename Type> const Type &as() const { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(const Type*)get(); } + network_address() : self(nullptr) {} + template<typename T> + network_address(const T& src) + : self(std::make_shared<implementation<T>>(src)) {} + bool equal(const network_address &other) const; + bool less(const network_address &other) const; + bool is_same_host(const network_address &other) const; + std::string str() const { return self ? self->str() : "<none>"; } + std::string host_str() const { return self ? self->host_str() : "<none>"; } + bool is_loopback() const { return self ? self->is_loopback() : false; } + bool is_local() const { return self ? self->is_local() : false; } + uint8_t get_type_id() const { return self ? self->get_type_id() : 0; } + template<typename Type> const Type &as() const { return as_mutable<const Type>(); } BEGIN_KV_SERIALIZE_MAP() uint8_t type = is_store ? this_ref.get_type_id() : 0; @@ -129,13 +171,27 @@ namespace net_utils { case ipv4_network_address::ID: if (!is_store) - const_cast<network_address&>(this_ref).reset(new ipv4_network_address(0, 0)); - KV_SERIALIZE(template as<ipv4_network_address>()); + const_cast<network_address&>(this_ref) = ipv4_network_address{0, 0}; + KV_SERIALIZE(template as_mutable<ipv4_network_address>()); break; default: MERROR("Unsupported network address type: " << type); return false; } END_KV_SERIALIZE_MAP() }; + + inline bool operator==(const network_address& lhs, const network_address& rhs) + { return lhs.equal(rhs); } + inline bool operator!=(const network_address& lhs, const network_address& rhs) + { return !lhs.equal(rhs); } + inline bool operator<(const network_address& lhs, const network_address& rhs) + { return lhs.less(rhs); } + inline bool operator<=(const network_address& lhs, const network_address& rhs) + { return !rhs.less(lhs); } + inline bool operator>(const network_address& lhs, const network_address& rhs) + { return rhs.less(lhs); } + inline bool operator>=(const network_address& lhs, const network_address& rhs) + { return !lhs.less(rhs); } + inline bool create_network_address(network_address &address, const std::string &string, uint16_t default_port = 0) { uint32_t ip; @@ -144,7 +200,7 @@ namespace net_utils { if (default_port && !port) port = default_port; - address.reset(new ipv4_network_address(ip, port)); + address = ipv4_network_address{ip, port}; return true; } return false; @@ -182,7 +238,7 @@ namespace net_utils {} connection_context_base(): m_connection_id(), - m_remote_address(new ipv4_network_address(0,0)), + m_remote_address(ipv4_network_address{0,0}), m_is_income(false), m_started(time(NULL)), m_last_recv(0), @@ -235,7 +291,7 @@ namespace net_utils std::string print_connection_context(const connection_context_base& ctx) { std::stringstream ss; - ss << ctx.m_remote_address->str() << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT"); + ss << ctx.m_remote_address.str() << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT"); return ss.str(); } @@ -243,7 +299,7 @@ namespace net_utils std::string print_connection_context_short(const connection_context_base& ctx) { std::stringstream ss; - ss << ctx.m_remote_address->str() << (ctx.m_is_income ? " INC":" OUT"); + ss << ctx.m_remote_address.str() << (ctx.m_is_income ? " INC":" OUT"); return ss.str(); } |