Upgrades to epee::net_utils::network_address
- internal nullptr checks - prevent modifications to network_address (shallow copy issues) - automagically works with any type containing interface functions - removed fnv1a hashing - ipv4_network_address now flattened with no base class
This commit is contained in:
parent
a2041c9874
commit
8b00687735
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
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
|
||||
static const uint8_t ID = 1;
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
uint32_t m_ip;
|
||||
uint16_t m_port;
|
||||
#pragma pack(pop)
|
||||
|
||||
public:
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
if (USE_READLINE AND GNU_READLINE_FOUND)
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp string_tools.cpp readline_buffer.cpp)
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp readline_buffer.cpp)
|
||||
else()
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp string_tools.cpp)
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp)
|
||||
endif()
|
||||
|
||||
# Build and install libepee if we're building for GUI
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include "net/net_utils_base.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <typeindex>
|
||||
#include "net/local_ip.h"
|
||||
|
||||
namespace epee { namespace net_utils
|
||||
{
|
||||
const uint8_t ipv4_network_address::ID;
|
||||
|
||||
bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept
|
||||
{ return is_same_host(other) && port() == other.port(); }
|
||||
|
||||
bool ipv4_network_address::less(const ipv4_network_address& other) const noexcept
|
||||
{ return is_same_host(other) ? port() < other.port() : ip() < other.ip(); }
|
||||
|
||||
std::string ipv4_network_address::str() const
|
||||
{ return string_tools::get_ip_string_from_int32(ip()) + ":" + std::to_string(port()); }
|
||||
|
||||
std::string ipv4_network_address::host_str() const { return string_tools::get_ip_string_from_int32(ip()); }
|
||||
bool ipv4_network_address::is_loopback() const { return net_utils::is_ip_loopback(ip()); }
|
||||
bool ipv4_network_address::is_local() const { return net_utils::is_ip_local(ip()); }
|
||||
|
||||
|
||||
bool network_address::equal(const network_address& other) const
|
||||
{
|
||||
// clang typeid workaround
|
||||
network_address::interface const* const self_ = self.get();
|
||||
network_address::interface const* const other_self = other.self.get();
|
||||
if (self_ == other_self) return true;
|
||||
if (!self_ || !other_self) return false;
|
||||
if (typeid(*self_) != typeid(*other_self)) return false;
|
||||
return self_->equal(*other_self);
|
||||
}
|
||||
|
||||
bool network_address::less(const network_address& other) const
|
||||
{
|
||||
// clang typeid workaround
|
||||
network_address::interface const* const self_ = self.get();
|
||||
network_address::interface const* const other_self = other.self.get();
|
||||
if (self_ == other_self) return false;
|
||||
if (!self_ || !other_self) return self == nullptr;
|
||||
if (typeid(*self_) != typeid(*other_self))
|
||||
return self_->get_type_id() < other_self->get_type_id();
|
||||
return self_->less(*other_self);
|
||||
}
|
||||
|
||||
bool network_address::is_same_host(const network_address& other) const
|
||||
{
|
||||
// clang typeid workaround
|
||||
network_address::interface const* const self_ = self.get();
|
||||
network_address::interface const* const other_self = other.self.get();
|
||||
if (self_ == other_self) return true;
|
||||
if (!self_ || !other_self) return false;
|
||||
if (typeid(*self_) != typeid(*other_self)) return false;
|
||||
return self_->is_same_host(*other_self);
|
||||
}
|
||||
}}
|
||||
|
|
@ -390,7 +390,7 @@ namespace nodetool
|
|||
ip::tcp::endpoint endpoint = *i;
|
||||
if (endpoint.address().is_v4())
|
||||
{
|
||||
epee::net_utils::network_address na(new epee::net_utils::ipv4_network_address(boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port()));
|
||||
epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port()}};
|
||||
seed_nodes.push_back(na);
|
||||
MINFO("Added seed node: " << na.str());
|
||||
}
|
||||
|
@ -1521,7 +1521,7 @@ namespace nodetool
|
|||
return false;
|
||||
std::string ip = epee::string_tools::get_ip_string_from_int32(actual_ip);
|
||||
std::string port = epee::string_tools::num_to_string_fast(node_data.my_port);
|
||||
epee::net_utils::network_address address(new epee::net_utils::ipv4_network_address(actual_ip, node_data.my_port));
|
||||
epee::net_utils::network_address address{epee::net_utils::ipv4_network_address(actual_ip, node_data.my_port)};
|
||||
peerid_type pr = node_data.peer_id;
|
||||
bool r = m_net_server.connect_async(ip, port, m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ address, pr, this](
|
||||
const typename net_server::t_connection_context& ping_context,
|
||||
|
@ -1669,7 +1669,7 @@ namespace nodetool
|
|||
if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port)
|
||||
{
|
||||
peerid_type peer_id_l = arg.node_data.peer_id;
|
||||
uint32_t port_l = arg.node_data.my_port;
|
||||
uint32_t port_l = arg.node_data.my_port;
|
||||
//try ping to be sure that we can add this peer to peer_list
|
||||
try_ping(arg.node_data, context, [peer_id_l, port_l, context, this]()
|
||||
{
|
||||
|
@ -1678,7 +1678,7 @@ namespace nodetool
|
|||
//called only(!) if success pinged, update local peerlist
|
||||
peerlist_entry pe;
|
||||
const epee::net_utils::network_address na = context.m_remote_address;
|
||||
pe.adr.reset(new epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l));
|
||||
pe.adr = epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l);
|
||||
time_t last_seen;
|
||||
time(&last_seen);
|
||||
pe.last_seen = static_cast<int64_t>(last_seen);
|
||||
|
|
|
@ -31,11 +31,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "net/net_utils_base.h"
|
||||
#include "p2p/p2p_protocol_defs.h"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
template <class T, class Archive>
|
||||
inline void do_serialize(Archive &a, epee::net_utils::network_address& na, T local)
|
||||
{
|
||||
if (typename Archive::is_saving()) local = na.as<T>();
|
||||
a & local;
|
||||
if (!typename Archive::is_saving()) na = local;
|
||||
}
|
||||
template <class Archive, class ver_type>
|
||||
inline void serialize(Archive &a, epee::net_utils::network_address& na, const ver_type ver)
|
||||
{
|
||||
|
@ -46,10 +54,8 @@ namespace boost
|
|||
switch (type)
|
||||
{
|
||||
case epee::net_utils::ipv4_network_address::ID:
|
||||
if (!typename Archive::is_saving())
|
||||
na.reset(new epee::net_utils::ipv4_network_address(0, 0));
|
||||
a & na.as<epee::net_utils::ipv4_network_address>();
|
||||
break;
|
||||
do_serialize(a, na, epee::net_utils::ipv4_network_address{0, 0});
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported network address type");
|
||||
}
|
||||
|
@ -57,13 +63,14 @@ namespace boost
|
|||
template <class Archive, class ver_type>
|
||||
inline void serialize(Archive &a, epee::net_utils::ipv4_network_address& na, const ver_type ver)
|
||||
{
|
||||
a & na.m_ip;
|
||||
a & na.m_port;
|
||||
uint32_t ip{na.ip()};
|
||||
uint16_t port{na.port()};
|
||||
a & ip;
|
||||
a & port;
|
||||
if (!typename Archive::is_saving())
|
||||
na.init_ids();
|
||||
na = epee::net_utils::ipv4_network_address{ip, port};
|
||||
}
|
||||
|
||||
|
||||
template <class Archive, class ver_type>
|
||||
inline void serialize(Archive &a, nodetool::peerlist_entry& pl, const ver_type ver)
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace nodetool
|
|||
ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
|
||||
for(const peerlist_entry& pe: pl)
|
||||
{
|
||||
ss << pe.id << "\t" << pe.adr->str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
|
||||
ss << pe.id << "\t" << pe.adr.str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ namespace nodetool
|
|||
std::list<peerlist_entry_base<network_address_old>> local_peerlist;
|
||||
epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
|
||||
for (const auto &p: local_peerlist)
|
||||
((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
|
||||
((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
|
||||
}
|
||||
}
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
@ -275,7 +275,7 @@ namespace nodetool
|
|||
std::list<peerlist_entry_base<network_address_old>> local_peerlist;
|
||||
epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
|
||||
for (const auto &p: local_peerlist)
|
||||
((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
|
||||
((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
|
||||
}
|
||||
}
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
|
|
@ -1395,7 +1395,7 @@ namespace cryptonote
|
|||
}
|
||||
else
|
||||
{
|
||||
na.reset(new epee::net_utils::ipv4_network_address(i->ip, 0));
|
||||
na = epee::net_utils::ipv4_network_address{i->ip, 0};
|
||||
}
|
||||
if (i->ban)
|
||||
m_p2p.block_host(na, i->seconds);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "p2p/net_node.h"
|
||||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||
|
||||
#define MAKE_IPV4_ADDRESS(a,b,c,d) new epee::net_utils::ipv4_network_address(MAKE_IP(a,b,c,d),0)
|
||||
#define MAKE_IPV4_ADDRESS(a,b,c,d) epee::net_utils::ipv4_network_address{MAKE_IP(a,b,c,d),0}
|
||||
|
||||
namespace cryptonote {
|
||||
class blockchain_storage;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <array>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/range/algorithm/equal.hpp>
|
||||
#include <boost/range/algorithm_ext/iota.hpp>
|
||||
#include <cstdint>
|
||||
|
@ -42,7 +43,11 @@
|
|||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "boost/archive/portable_binary_iarchive.hpp"
|
||||
#include "boost/archive/portable_binary_oarchive.hpp"
|
||||
#include "hex.h"
|
||||
#include "net/net_utils_base.h"
|
||||
#include "p2p/net_peerlist_boost_serialization.h"
|
||||
#include "span.h"
|
||||
#include "string_tools.h"
|
||||
|
||||
|
@ -100,6 +105,40 @@ namespace
|
|||
boost::range::iota(out, 0);
|
||||
return out;
|
||||
}
|
||||
|
||||
#define CHECK_EQUAL(lhs, rhs) \
|
||||
EXPECT_TRUE( lhs == rhs ); \
|
||||
EXPECT_TRUE( rhs == lhs ); \
|
||||
EXPECT_FALSE( lhs != rhs ); \
|
||||
EXPECT_FALSE( rhs != lhs ); \
|
||||
EXPECT_FALSE( lhs < rhs ); \
|
||||
EXPECT_FALSE( rhs < lhs ); \
|
||||
EXPECT_TRUE( lhs <= rhs ); \
|
||||
EXPECT_TRUE( rhs <= lhs ); \
|
||||
EXPECT_FALSE( lhs > rhs ); \
|
||||
EXPECT_FALSE( rhs > lhs ); \
|
||||
EXPECT_TRUE( lhs >= rhs ); \
|
||||
EXPECT_TRUE( rhs >= lhs )
|
||||
|
||||
#define CHECK_LESS(lhs, rhs) \
|
||||
EXPECT_FALSE( lhs == rhs ); \
|
||||
EXPECT_FALSE( rhs == lhs ); \
|
||||
EXPECT_TRUE( lhs != rhs ); \
|
||||
EXPECT_TRUE( rhs != lhs ); \
|
||||
EXPECT_TRUE( lhs < rhs ); \
|
||||
EXPECT_FALSE( rhs < lhs ); \
|
||||
EXPECT_TRUE( lhs <= rhs ); \
|
||||
EXPECT_FALSE( rhs <= lhs ); \
|
||||
EXPECT_FALSE( lhs > rhs ); \
|
||||
EXPECT_TRUE( rhs > lhs ); \
|
||||
EXPECT_FALSE( lhs >= rhs ); \
|
||||
EXPECT_TRUE( rhs >= lhs )
|
||||
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
#define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( rhs , lhs )
|
||||
#else
|
||||
#define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( lhs , rhs )
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Span, Traits)
|
||||
|
@ -419,3 +458,195 @@ TEST(StringTools, GetIpInt32)
|
|||
EXPECT_EQ(htonl(0xff0aff00), ip);
|
||||
}
|
||||
|
||||
TEST(NetUtils, IPv4NetworkAddress)
|
||||
{
|
||||
const auto ip1 = boost::endian::native_to_big(0x330012FFu);
|
||||
const auto ip_loopback = boost::endian::native_to_big(0x7F000001u);
|
||||
const auto ip_local = boost::endian::native_to_big(0x0A000000u);
|
||||
|
||||
epee::net_utils::ipv4_network_address address1{ip1, 65535};
|
||||
CHECK_EQUAL(address1, address1);
|
||||
EXPECT_STREQ("51.0.18.255:65535", address1.str().c_str());
|
||||
EXPECT_STREQ("51.0.18.255", address1.host_str().c_str());
|
||||
EXPECT_FALSE(address1.is_loopback());
|
||||
EXPECT_FALSE(address1.is_local());
|
||||
EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
|
||||
EXPECT_EQ(ip1, address1.ip());
|
||||
EXPECT_EQ(65535, address1.port());
|
||||
EXPECT_TRUE(epee::net_utils::ipv4_network_address{std::move(address1)} == address1);
|
||||
EXPECT_TRUE(epee::net_utils::ipv4_network_address{address1} == address1);
|
||||
|
||||
const epee::net_utils::ipv4_network_address loopback{ip_loopback, 0};
|
||||
CHECK_EQUAL(loopback, loopback);
|
||||
CHECK_LESS_ENDIAN(address1, loopback);
|
||||
EXPECT_STREQ("127.0.0.1:0", loopback.str().c_str());
|
||||
EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str());
|
||||
EXPECT_TRUE(loopback.is_loopback());
|
||||
EXPECT_FALSE(loopback.is_local());
|
||||
EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
|
||||
EXPECT_EQ(ip_loopback, loopback.ip());
|
||||
EXPECT_EQ(0, loopback.port());
|
||||
|
||||
const epee::net_utils::ipv4_network_address local{ip_local, 8080};
|
||||
CHECK_EQUAL(local, local);
|
||||
CHECK_LESS(local, address1);
|
||||
CHECK_LESS(local, loopback);
|
||||
EXPECT_FALSE(local.is_loopback());
|
||||
EXPECT_TRUE(local.is_local());
|
||||
|
||||
epee::net_utils::ipv4_network_address address2{ip1, 55};
|
||||
CHECK_EQUAL(address2, address2);
|
||||
CHECK_LESS_ENDIAN(address2, loopback);
|
||||
CHECK_LESS(local, address2);
|
||||
EXPECT_STREQ("51.0.18.255:55", address2.str().c_str());
|
||||
EXPECT_STREQ("51.0.18.255", address2.host_str().c_str());
|
||||
|
||||
|
||||
address2 = std::move(address1);
|
||||
CHECK_EQUAL(address2, address1);
|
||||
|
||||
address2 = local;
|
||||
CHECK_EQUAL(address2, local);
|
||||
CHECK_LESS(address2, address1);
|
||||
|
||||
{
|
||||
std::stringstream stream;
|
||||
{
|
||||
boost::archive::portable_binary_oarchive ostream{stream};
|
||||
ostream << address1;
|
||||
}
|
||||
{
|
||||
boost::archive::portable_binary_iarchive istream{stream};
|
||||
istream >> address2;
|
||||
}
|
||||
}
|
||||
CHECK_EQUAL(address1, address2);
|
||||
EXPECT_EQ(ip1, address2.ip());
|
||||
EXPECT_EQ(65535, address2.port());
|
||||
}
|
||||
|
||||
TEST(NetUtils, NetworkAddress)
|
||||
{
|
||||
const auto ip1 = boost::endian::native_to_big(0x330012FFu);
|
||||
const auto ip_loopback = boost::endian::native_to_big(0x7F000001u);
|
||||
const auto ip_local = boost::endian::native_to_big(0x0A000000u);
|
||||
|
||||
struct custom_address {
|
||||
constexpr static bool equal(const custom_address&) noexcept { return false; }
|
||||
constexpr static bool less(const custom_address&) noexcept { return false; }
|
||||
constexpr static bool is_same_host(const custom_address&) noexcept { return false; }
|
||||
constexpr static bool is_loopback() noexcept { return false; }
|
||||
constexpr static bool is_local() noexcept { return false; }
|
||||
static std::string str() { return {}; }
|
||||
static std::string host_str() { return {}; }
|
||||
constexpr static uint8_t get_type_id() noexcept { return uint8_t(-1); }
|
||||
};
|
||||
|
||||
const epee::net_utils::network_address empty;
|
||||
CHECK_EQUAL(empty, empty);
|
||||
EXPECT_TRUE(empty.is_same_host(empty));
|
||||
EXPECT_STREQ("<none>", empty.str().c_str());
|
||||
EXPECT_STREQ("<none>", empty.host_str().c_str());
|
||||
EXPECT_FALSE(empty.is_loopback());
|
||||
EXPECT_FALSE(empty.is_local());
|
||||
EXPECT_EQ(0, empty.get_type_id());
|
||||
EXPECT_THROW(empty.as<custom_address>(), std::bad_cast);
|
||||
|
||||
epee::net_utils::network_address address1{
|
||||
epee::net_utils::ipv4_network_address{ip1, 65535}
|
||||
};
|
||||
CHECK_EQUAL(address1, address1);
|
||||
CHECK_EQUAL(epee::net_utils::network_address{address1}, address1);
|
||||
CHECK_LESS(empty, address1);
|
||||
EXPECT_TRUE(address1.is_same_host(address1));
|
||||
EXPECT_FALSE(empty.is_same_host(address1));
|
||||
EXPECT_FALSE(address1.is_same_host(empty));
|
||||
EXPECT_STREQ("51.0.18.255:65535", address1.str().c_str());
|
||||
EXPECT_STREQ("51.0.18.255", address1.host_str().c_str());
|
||||
EXPECT_FALSE(address1.is_loopback());
|
||||
EXPECT_FALSE(address1.is_local());
|
||||
EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
|
||||
EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>());
|
||||
EXPECT_THROW(address1.as<custom_address>(), std::bad_cast);
|
||||
|
||||
const epee::net_utils::network_address loopback{
|
||||
epee::net_utils::ipv4_network_address{ip_loopback, 0}
|
||||
};
|
||||
CHECK_EQUAL(loopback, loopback);
|
||||
CHECK_LESS(empty, loopback);
|
||||
CHECK_LESS_ENDIAN(address1, loopback);
|
||||
EXPECT_TRUE(loopback.is_same_host(loopback));
|
||||
EXPECT_FALSE(loopback.is_same_host(address1));
|
||||
EXPECT_FALSE(address1.is_same_host(loopback));
|
||||
EXPECT_STREQ("127.0.0.1:0", loopback.str().c_str());
|
||||
EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str());
|
||||
EXPECT_TRUE(loopback.is_loopback());
|
||||
EXPECT_FALSE(loopback.is_local());
|
||||
EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id());
|
||||
|
||||
const epee::net_utils::network_address local{
|
||||
epee::net_utils::ipv4_network_address{ip_local, 8080}
|
||||
};
|
||||
CHECK_EQUAL(local, local);
|
||||
CHECK_LESS(local, loopback);
|
||||
CHECK_LESS(local, address1);
|
||||
EXPECT_FALSE(local.is_loopback());
|
||||
EXPECT_TRUE(local.is_local());
|
||||
|
||||
epee::net_utils::network_address address2{
|
||||
epee::net_utils::ipv4_network_address{ip1, 55}
|
||||
};
|
||||
CHECK_EQUAL(address2, address2);
|
||||
CHECK_LESS(address2, address1);
|
||||
CHECK_LESS(local, address2);
|
||||
CHECK_LESS_ENDIAN(address2, loopback);
|
||||
EXPECT_TRUE(address1.is_same_host(address2));
|
||||
EXPECT_TRUE(address2.is_same_host(address1));
|
||||
EXPECT_STREQ("51.0.18.255:55", address2.str().c_str());
|
||||
EXPECT_STREQ("51.0.18.255", address2.host_str().c_str());
|
||||
|
||||
address2 = std::move(address1);
|
||||
CHECK_EQUAL(address1, address1);
|
||||
CHECK_EQUAL(empty, address1);
|
||||
CHECK_LESS(address1, address2);
|
||||
EXPECT_FALSE(address1.is_same_host(address2));
|
||||
EXPECT_FALSE(address2.is_same_host(address1));
|
||||
EXPECT_STREQ("51.0.18.255:65535", address2.str().c_str());
|
||||
EXPECT_STREQ("51.0.18.255", address2.host_str().c_str());
|
||||
EXPECT_FALSE(address1.is_loopback());
|
||||
EXPECT_FALSE(address1.is_local());
|
||||
EXPECT_THROW(address1.as<epee::net_utils::ipv4_network_address>(), std::bad_cast);
|
||||
EXPECT_NO_THROW(address2.as<epee::net_utils::ipv4_network_address>());
|
||||
|
||||
address2 = local;
|
||||
CHECK_EQUAL(address2, local);
|
||||
CHECK_LESS(address1, address2);
|
||||
EXPECT_TRUE(address2.is_same_host(local));
|
||||
EXPECT_TRUE(local.is_same_host(address2));
|
||||
EXPECT_FALSE(address2.is_same_host(address1));
|
||||
EXPECT_FALSE(address1.is_same_host(address2));
|
||||
|
||||
{
|
||||
std::stringstream stream;
|
||||
{
|
||||
boost::archive::portable_binary_oarchive ostream{stream};
|
||||
ostream << address2;
|
||||
}
|
||||
{
|
||||
boost::archive::portable_binary_iarchive istream{stream};
|
||||
istream >> address1;
|
||||
}
|
||||
}
|
||||
CHECK_EQUAL(address1, address2);
|
||||
EXPECT_TRUE(address1.is_same_host(address2));
|
||||
EXPECT_TRUE(address2.is_same_host(address1));
|
||||
EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>());
|
||||
|
||||
address1 = custom_address{};
|
||||
CHECK_EQUAL(address1, address1);
|
||||
CHECK_LESS(address2, address1);
|
||||
EXPECT_FALSE(address1.is_same_host(loopback));
|
||||
EXPECT_FALSE(loopback.is_same_host(address1));
|
||||
EXPECT_THROW(address1.as<epee::net_utils::ipv4_network_address>(), std::bad_cast);
|
||||
EXPECT_NO_THROW(address1.as<custom_address>());
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ TEST(peer_list, peer_list_general)
|
|||
{
|
||||
nodetool::peerlist_manager plm;
|
||||
plm.init(false);
|
||||
#define MAKE_IPV4_ADDRESS(a,b,c,d,e) new epee::net_utils::ipv4_network_address(MAKE_IP(a,b,c,d),e)
|
||||
#define MAKE_IPV4_ADDRESS(a,b,c,d,e) epee::net_utils::ipv4_network_address{MAKE_IP(a,b,c,d),e}
|
||||
#define ADD_GRAY_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple; ple.last_seen=last_seen_;ple.adr = addr_; ple.id = id_;plm.append_with_peer_gray(ple);}
|
||||
#define ADD_WHITE_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple;ple.last_seen=last_seen_; ple.adr = addr_; ple.id = id_;plm.append_with_peer_white(ple);}
|
||||
|
||||
|
|
Loading…
Reference in New Issue