aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/net/net_utils_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/include/net/net_utils_base.h')
-rw-r--r--contrib/epee/include/net/net_utils_base.h122
1 files changed, 110 insertions, 12 deletions
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index 4334029f7..ba59daf4f 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -29,8 +29,11 @@
#ifndef _NET_UTILS_BASE_H_
#define _NET_UTILS_BASE_H_
+#include <typeinfo>
#include <boost/asio/io_service.hpp>
#include <boost/uuid/uuid.hpp>
+#include "serialization/keyvalue_serialization.h"
+#include "net/local_ip.h"
#include "string_tools.h"
#include "misc_log_ex.h"
@@ -46,14 +49,111 @@ namespace epee
{
namespace net_utils
{
+ struct network_address_base
+ {
+ 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;
+ };
+ 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
+ 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>
+ {
+ 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(); }
+ const std::type_info &type() const { return typeid(**this); }
+ uint8_t get_type_id() const { return (*this)->get_type_id(); }
+ template<typename Type> Type &as() { if (type() != typeid(Type)) throw std::runtime_error("Bad type"); return *(Type*)get(); }
+ template<typename Type> const Type &as() const { if (type() != typeid(Type)) throw std::runtime_error("Bad type"); return *(const Type*)get(); }
+
+ BEGIN_KV_SERIALIZE_MAP()
+ uint8_t type = is_store ? this_ref.get_type_id() : 0;
+ epee::serialization::selector<is_store>::serialize(type, stg, hparent_section, "type");
+ switch (type)
+ {
+ case ipv4_network_address::ID:
+ if (!is_store)
+ const_cast<network_address&>(this_ref).reset(new ipv4_network_address(0, 0));
+ KV_SERIALIZE(as<ipv4_network_address>());
+ break;
+ default: MERROR("Unsupported network address type: " << type); return false;
+ }
+ END_KV_SERIALIZE_MAP()
+ };
+ inline bool create_network_address(network_address &address, const std::string &string, uint16_t default_port = 0)
+ {
+ uint32_t ip;
+ uint16_t port;
+ if (epee::string_tools::parse_peer_from_string(ip, port, string))
+ {
+ if (default_port && !port)
+ port = default_port;
+ address.reset(new ipv4_network_address(ip, port));
+ return true;
+ }
+ return false;
+ }
/************************************************************************/
/* */
/************************************************************************/
struct connection_context_base
{
const boost::uuids::uuid m_connection_id;
- const uint32_t m_remote_ip;
- const uint32_t m_remote_port;
+ const network_address m_remote_address;
const bool m_is_income;
const time_t m_started;
time_t m_last_recv;
@@ -64,12 +164,11 @@ namespace net_utils
double m_current_speed_up;
connection_context_base(boost::uuids::uuid connection_id,
- long remote_ip, int remote_port, bool is_income,
+ const network_address &remote_address, bool is_income,
time_t last_recv = 0, time_t last_send = 0,
uint64_t recv_cnt = 0, uint64_t send_cnt = 0):
m_connection_id(connection_id),
- m_remote_ip(remote_ip),
- m_remote_port(remote_port),
+ m_remote_address(remote_address),
m_is_income(is_income),
m_started(time(NULL)),
m_last_recv(last_recv),
@@ -81,8 +180,7 @@ namespace net_utils
{}
connection_context_base(): m_connection_id(),
- m_remote_ip(0),
- m_remote_port(0),
+ m_remote_address(new ipv4_network_address(0,0)),
m_is_income(false),
m_started(time(NULL)),
m_last_recv(0),
@@ -95,17 +193,17 @@ namespace net_utils
connection_context_base& operator=(const connection_context_base& a)
{
- set_details(a.m_connection_id, a.m_remote_ip, a.m_remote_port, a.m_is_income);
+ set_details(a.m_connection_id, a.m_remote_address, a.m_is_income);
return *this;
}
private:
template<class t_protocol_handler>
friend class connection;
- void set_details(boost::uuids::uuid connection_id, long remote_ip, int remote_port, bool is_income)
+ void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income)
{
this->~connection_context_base();
- new(this) connection_context_base(connection_id, remote_ip, remote_port, is_income);
+ new(this) connection_context_base(connection_id, remote_address, is_income);
}
};
@@ -135,7 +233,7 @@ namespace net_utils
std::string print_connection_context(const connection_context_base& ctx)
{
std::stringstream ss;
- ss << epee::string_tools::get_ip_string_from_int32(ctx.m_remote_ip) << ":" << ctx.m_remote_port << " " << 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();
}
@@ -143,7 +241,7 @@ namespace net_utils
std::string print_connection_context_short(const connection_context_base& ctx)
{
std::stringstream ss;
- ss << epee::string_tools::get_ip_string_from_int32(ctx.m_remote_ip) << ":" << ctx.m_remote_port << (ctx.m_is_income ? " INC":" OUT");
+ ss << ctx.m_remote_address->str() << (ctx.m_is_income ? " INC":" OUT");
return ss.str();
}