aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2017-08-25 11:14:46 -0400
committerLee Clagett <code@leeclagett.com>2017-10-05 11:57:09 -0400
commit8b0068773525e585ce4c98d4ea2ce66dd6cf4aad (patch)
treedd14a8fb911acf97900548c7c1965c2d6a46a331
parentMerge pull request #2518 (diff)
downloadmonero-8b0068773525e585ce4c98d4ea2ce66dd6cf4aad.tar.xz
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
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl4
-rw-r--r--contrib/epee/include/net/net_utils_base.h194
-rw-r--r--contrib/epee/src/CMakeLists.txt4
-rw-r--r--contrib/epee/src/net_utils_base.cpp60
-rw-r--r--src/p2p/net_node.inl8
-rw-r--r--src/p2p/net_peerlist_boost_serialization.h23
-rw-r--r--src/p2p/p2p_protocol_defs.h6
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--tests/unit_tests/ban.cpp2
-rw-r--r--tests/unit_tests/epee_utils.cpp231
-rw-r--r--tests/unit_tests/test_peerlist.cpp2
11 files changed, 445 insertions, 91 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/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();
}
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index c61a6e684..294515f83 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -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
diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp
new file mode 100644
index 000000000..22afcf819
--- /dev/null
+++ b/contrib/epee/src/net_utils_base.cpp
@@ -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);
+ }
+}}
+
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index f1ca50f76..6162d649b 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -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);
diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h
index 6ea2d48fd..079524aa1 100644
--- a/src/p2p/net_peerlist_boost_serialization.h
+++ b/src/p2p/net_peerlist_boost_serialization.h
@@ -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)
{
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index f2b2cd1da..d49d83989 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -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()
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 9b91f438a..b9678f414 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -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);
diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp
index b8d57452e..d15716a42 100644
--- a/tests/unit_tests/ban.cpp
+++ b/tests/unit_tests/ban.cpp
@@ -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;
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index e8ddbe3f5..f6cb0c163 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -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>());
+}
diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp
index 4a546b50d..849020d25 100644
--- a/tests/unit_tests/test_peerlist.cpp
+++ b/tests/unit_tests/test_peerlist.cpp
@@ -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);}