abstracted nework addresses

All code which was using ip and port now uses a new IPv4 object,
subclass of a new network_address class. This will allow easy
addition of I2P addresses later (and also IPv6, etc).
Both old style and new style peer lists are now sent in the P2P
protocol, which is inefficient but allows peers using both
codebases to talk to each other. This will be removed in the
future. No other subclasses than IPv4 exist yet.
This commit is contained in:
moneromooo-monero 2017-05-27 11:35:54 +01:00
parent 694470fae7
commit 072102cfd2
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
18 changed files with 512 additions and 261 deletions

View file

@ -296,7 +296,7 @@ namespace net_utils
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::invoke_connection(SOCKET hnew_sock, long ip_from, int post_from)
bool abstract_tcp_server<THandler>::invoke_connection(SOCKET hnew_sock, const network_address &remote_address)
{
m_connections_lock.lock();
m_connections.push_back(thread_context());
@ -304,8 +304,7 @@ namespace net_utils
m_connections.back().m_socket = hnew_sock;
m_connections.back().powner = this;
m_connections.back().m_self_it = --m_connections.end();
m_connections.back().m_context.m_remote_ip = ip_from;
m_connections.back().m_context.m_remote_port = post_from;
m_connections.back().m_context.m_remote_address = remote_address;
m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back());
return true;

View file

@ -69,7 +69,7 @@ namespace net_utils
struct i_connection_filter
{
virtual bool is_remote_ip_allowed(uint32_t adress)=0;
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address)=0;
protected:
virtual ~i_connection_filter(){}
};

View file

@ -133,6 +133,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
boost::system::error_code ec;
auto remote_ep = socket_.remote_endpoint(ec);
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get remote endpoint: " << ec.message() << ':' << ec.value());
CHECK_AND_NO_ASSERT_MES(remote_ep.address().is_v4(), false, "IPv6 not supported here");
auto local_ep = socket_.local_endpoint(ec);
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value());
@ -145,14 +146,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
// 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, ip_, remote_ep.port(), is_income);
context.set_details(random_uuid, new 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);
if(m_pfilter && !m_pfilter->is_remote_ip_allowed(context.m_remote_ip))
if(m_pfilter && !m_pfilter->is_remote_host_allowed(context.m_remote_address))
{
_dbg2("[sock " << socket_.native_handle() << "] ip denied " << string_tools::get_ip_string_from_int32(context.m_remote_ip) << ", shutdowning connection");
_dbg2("[sock " << socket_.native_handle() << "] host denied " << context.m_remote_address.host_str() << ", shutdowning connection");
close();
return false;
}

View file

@ -471,7 +471,7 @@ bool cp_server_impl<TProtocol>::run_server(int threads_count = 0)
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::add_new_connection(SOCKET new_sock, long ip_from, int port_from)
bool cp_server_impl<TProtocol>::add_new_connection(SOCKET new_sock, const network_address &address_from)
{
PROFILE_FUNC("[add_new_connection]");
@ -487,8 +487,7 @@ bool cp_server_impl<TProtocol>::add_new_connection(SOCKET new_sock, long ip_from
m_connections_lock.unlock();
conn.init_buffers();
conn.m_sock = new_sock;
conn.context.m_remote_ip = ip_from;
conn.context.m_remote_port = port_from;
conn.context.m_remote_address = address_from;
conn.m_completion_port = m_completion_port;
{
PROFILE_FUNC("[add_new_connection] CreateIoCompletionPort");

View file

@ -39,7 +39,7 @@
epee::net_utils::http::http_response_info& response, \
context_type& m_conn_context) \
{\
LOG_PRINT_L2("HTTP [" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \
LOG_PRINT_L2("HTTP [" << m_conn_context.m_remote_address.host_str() << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \
response.m_response_code = 200; \
response.m_response_comment = "Ok"; \
if(!handle_http_request_map(query_info, response, m_conn_context)) \

View file

@ -492,8 +492,7 @@ namespace levin
{
net_utils::connection_context_base conn_context;
conn_context.m_remote_ip = m_ip;
conn_context.m_remote_port = m_port;
conn_context.m_remote_address = m_address;
if(head.m_have_to_return_data)
{
std::string return_buff;

View file

@ -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();
}

View file

@ -193,7 +193,7 @@ POP_WARNINGS
//----------------------------------------------------------------------------
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
//----------------------------------------------------------------------------
inline bool parse_peer_from_string(uint32_t& ip, uint32_t& port, const std::string& addres)
inline bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
{
//parse ip and address
std::string::size_type p = addres.find(':');

View file

@ -49,6 +49,8 @@ namespace cryptonote
bool localhost;
bool local_ip;
std::string address;
std::string host;
std::string ip;
std::string port;
@ -76,6 +78,8 @@ namespace cryptonote
KV_SERIALIZE(incoming)
KV_SERIALIZE(localhost)
KV_SERIALIZE(local_ip)
KV_SERIALIZE(address)
KV_SERIALIZE(host)
KV_SERIALIZE(ip)
KV_SERIALIZE(port)
KV_SERIALIZE(peer_id)

View file

@ -134,17 +134,12 @@ namespace cryptonote
<< std::setw(13) << "Up(now)"
<< ENDL;
uint32_t ip;
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags)
{
bool local_ip = false;
ip = ntohl(cntxt.m_remote_ip);
// TODO: local ip in calss A, B
if (ip > 3232235520 && ip < 3232301055) // 192.168.x.x
local_ip = true;
bool local_ip = cntxt.m_remote_address.is_local();
auto connection_time = time(NULL) - cntxt.m_started;
ss << std::setw(30) << std::left << std::string(cntxt.m_is_income ? " [INC]":"[OUT]") +
epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port)
cntxt.m_remote_address.str()
<< std::setw(20) << std::hex << peer_id
<< std::setw(20) << std::hex << support_flags
<< std::setw(30) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
@ -155,7 +150,7 @@ namespace cryptonote
<< std::setw(10) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_send_cnt / connection_time / 1024)
<< std::setw(13) << std::fixed << cntxt.m_current_speed_up / 1024
<< (local_ip ? "[LAN]" : "")
<< std::left << (ip == LOCALHOST_INT ? "[LOCALHOST]" : "") // 127.0.0.1
<< std::left << (cntxt.m_remote_address.is_loopback() ? "[LOCALHOST]" : "") // 127.0.0.1
<< ENDL;
if (connection_time > 1)
@ -193,8 +188,15 @@ namespace cryptonote
cnx.incoming = cntxt.m_is_income ? true : false;
cnx.ip = epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip);
cnx.port = std::to_string(cntxt.m_remote_port);
cnx.address = cntxt.m_remote_address.str();
cnx.host = cntxt.m_remote_address.host_str();
cnx.ip = "";
cnx.port = "";
if (cntxt.m_remote_address.type() == typeid(epee::net_utils::ipv4_network_address))
{
cnx.ip = cnx.host;
cnx.port = std::to_string(cntxt.m_remote_address.as<epee::net_utils::ipv4_network_address>().port());
}
std::stringstream peer_id_str;
peer_id_str << std::hex << peer_id;
@ -212,25 +214,8 @@ namespace cryptonote
cnx.live_time = timestamp - cntxt.m_started;
uint32_t ip;
ip = ntohl(cntxt.m_remote_ip);
if (ip == LOCALHOST_INT)
{
cnx.localhost = true;
}
else
{
cnx.localhost = false;
}
if (ip > 3232235520 && ip < 3232301055) // 192.168.x.x
{
cnx.local_ip = true;
}
else
{
cnx.local_ip = false;
}
cnx.localhost = cntxt.m_remote_address.is_loopback();
cnx.local_ip = cntxt.m_remote_address.is_local();
auto connection_time = time(NULL) - cntxt.m_started;
if (connection_time == 0)
@ -980,7 +965,7 @@ namespace cryptonote
{
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
m_p2p->drop_connection(context);
m_p2p->add_ip_fail(context.m_remote_ip);
m_p2p->add_host_fail(context.m_remote_address);
m_core.cleanup_handle_incoming_blocks();
return 1;
}
@ -988,7 +973,7 @@ namespace cryptonote
{
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
m_p2p->drop_connection(context);
m_p2p->add_ip_fail(context.m_remote_ip);
m_p2p->add_host_fail(context.m_remote_address);
m_core.cleanup_handle_incoming_blocks();
return 1;
}
@ -1140,7 +1125,7 @@ skip:
{
LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection");
m_p2p->drop_connection(context);
m_p2p->add_ip_fail(context.m_remote_ip);
m_p2p->add_host_fail(context.m_remote_address);
return 1;
}
@ -1149,7 +1134,7 @@ skip:
LOG_ERROR_CCONTEXT("sent m_block_ids starting from unknown id: "
<< epee::string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection");
m_p2p->drop_connection(context);
m_p2p->add_ip_fail(context.m_remote_ip);
m_p2p->add_host_fail(context.m_remote_address);
return 1;
}

View file

@ -123,9 +123,9 @@ namespace nodetool
size_t get_outgoing_connections_count();
peerlist_manager& get_peerlist_manager(){return m_peerlist;}
void delete_connections(size_t count);
virtual bool block_ip(uint32_t adress, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_ip(uint32_t address);
virtual std::map<uint32_t, time_t> get_blocked_ips() { CRITICAL_REGION_LOCAL(m_blocked_ips_lock); return m_blocked_ips; }
virtual bool block_host(const epee::net_utils::network_address &adress, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_host(const epee::net_utils::network_address &address);
virtual std::map<std::string, time_t> get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; }
private:
const std::vector<std::string> m_seed_nodes_list =
{ "seeds.moneroseeds.se"
@ -186,11 +186,11 @@ namespace nodetool
virtual bool drop_connection(const epee::net_utils::connection_context_base& context);
virtual void request_callback(const epee::net_utils::connection_context_base& context);
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f);
virtual bool add_ip_fail(uint32_t address);
virtual bool add_host_fail(const epee::net_utils::network_address &address);
//----------------- i_connection_filter --------------------------------------------------------
virtual bool is_remote_ip_allowed(uint32_t adress);
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address);
//-----------------------------------------------------------------------------------------------
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
bool parse_peer_from_string(epee::net_utils::network_address& pe, const std::string& node_addr, uint16_t default_port = 0);
bool handle_command_line(
const boost::program_options::variables_map& vm
);
@ -209,18 +209,18 @@ namespace nodetool
bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist);
bool make_new_connection_from_peerlist(bool use_white_list);
bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, PeerType peer_type = white, uint64_t first_seen_stamp = 0);
bool try_to_connect_and_handshake_with_new_peer(const epee::net_utils::network_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, PeerType peer_type = white, uint64_t first_seen_stamp = 0);
size_t get_random_index_with_fixed_probability(size_t max_index);
bool is_peer_used(const peerlist_entry& peer);
bool is_peer_used(const anchor_peerlist_entry& peer);
bool is_addr_connected(const net_address& peer);
bool is_addr_connected(const epee::net_utils::network_address& peer);
template<class t_callback>
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
bool try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f);
bool make_expected_connections_count(PeerType peer_type, size_t expected_connections);
void cache_connect_fail_info(const net_address& addr);
bool is_addr_recently_failed(const net_address& addr);
bool is_priority_node(const net_address& na);
void cache_connect_fail_info(const epee::net_utils::network_address& addr);
bool is_addr_recently_failed(const epee::net_utils::network_address& addr);
bool is_priority_node(const epee::net_utils::network_address& na);
std::set<std::string> get_seed_nodes(bool testnet) const;
template <class Container>
@ -236,9 +236,9 @@ namespace nodetool
bool set_rate_down_limit(const boost::program_options::variables_map& vm, int64_t limit);
bool set_rate_limit(const boost::program_options::variables_map& vm, int64_t limit);
bool has_too_many_connections(const uint32_t ip);
bool has_too_many_connections(const epee::net_utils::network_address &address);
bool check_connection_and_handshake_with_peer(const net_address& na, uint64_t last_seen_stamp);
bool check_connection_and_handshake_with_peer(const epee::net_utils::network_address& na, uint64_t last_seen_stamp);
bool gray_peerlist_housekeeping();
void kill() { ///< will be called e.g. from deinit()
@ -308,23 +308,23 @@ namespace nodetool
#ifdef ALLOW_DEBUG_COMMANDS
uint64_t m_last_stat_request_time;
#endif
std::list<net_address> m_priority_peers;
std::vector<net_address> m_exclusive_peers;
std::vector<net_address> m_seed_nodes;
std::list<epee::net_utils::network_address> m_priority_peers;
std::vector<epee::net_utils::network_address> m_exclusive_peers;
std::vector<epee::net_utils::network_address> m_seed_nodes;
std::list<nodetool::peerlist_entry> m_command_line_peers;
uint64_t m_peer_livetime;
//keep connections to initiate some interactions
net_server m_net_server;
boost::uuids::uuid m_network_id;
std::map<net_address, time_t> m_conn_fails_cache;
std::map<epee::net_utils::network_address, time_t> m_conn_fails_cache;
epee::critical_section m_conn_fails_cache_lock;
epee::critical_section m_blocked_ips_lock;
std::map<uint32_t, time_t> m_blocked_ips;
epee::critical_section m_blocked_hosts_lock;
std::map<std::string, time_t> m_blocked_hosts;
epee::critical_section m_ip_fails_score_lock;
std::map<uint32_t, uint64_t> m_ip_fails_score;
epee::critical_section m_host_fails_score_lock;
std::map<std::string, uint64_t> m_host_fails_score;
bool m_testnet;
};

View file

@ -200,16 +200,16 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr)
bool node_server<t_payload_net_handler>::is_remote_host_allowed(const epee::net_utils::network_address &address)
{
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
auto it = m_blocked_ips.find(addr);
if(it == m_blocked_ips.end())
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
auto it = m_blocked_hosts.find(address.host_str());
if(it == m_blocked_hosts.end())
return true;
if(time(nullptr) >= it->second)
{
m_blocked_ips.erase(it);
MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked.");
m_blocked_hosts.erase(it);
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
return true;
}
return false;
@ -229,16 +229,16 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::block_ip(uint32_t addr, time_t seconds)
bool node_server<t_payload_net_handler>::block_host(const epee::net_utils::network_address &addr, time_t seconds)
{
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
m_blocked_ips[addr] = time(nullptr) + seconds;
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
m_blocked_hosts[addr.host_str()] = time(nullptr) + seconds;
// drop any connection to that IP
std::list<boost::uuids::uuid> conns;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if (cntxt.m_remote_ip == addr)
if (cntxt.m_remote_address.is_same_host(addr))
{
conns.push_back(cntxt.m_connection_id);
}
@ -247,42 +247,42 @@ namespace nodetool
for (const auto &c: conns)
m_net_server.get_config_object().close(c);
MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked.");
MCLOG_CYAN(el::Level::Info, "global", "Host " << addr.host_str() << " blocked.");
return true;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::unblock_ip(uint32_t addr)
bool node_server<t_payload_net_handler>::unblock_host(const epee::net_utils::network_address &address)
{
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
auto i = m_blocked_ips.find(addr);
if (i == m_blocked_ips.end())
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
auto i = m_blocked_hosts.find(address.host_str());
if (i == m_blocked_hosts.end())
return false;
m_blocked_ips.erase(i);
MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked.");
m_blocked_hosts.erase(i);
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
return true;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::add_ip_fail(uint32_t address)
bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address)
{
CRITICAL_REGION_LOCAL(m_ip_fails_score_lock);
uint64_t fails = ++m_ip_fails_score[address];
MDEBUG("IP " << epee::string_tools::get_ip_string_from_int32(address) << " fail score=" << fails);
CRITICAL_REGION_LOCAL(m_host_fails_score_lock);
uint64_t fails = ++m_host_fails_score[address.host_str()];
MDEBUG("Host " << address.host_str() << " fail score=" << fails);
if(fails > P2P_IP_FAILS_BEFORE_BLOCK)
{
auto it = m_ip_fails_score.find(address);
CHECK_AND_ASSERT_MES(it != m_ip_fails_score.end(), false, "internal error");
auto it = m_host_fails_score.find(address.host_str());
CHECK_AND_ASSERT_MES(it != m_host_fails_score.end(), false, "internal error");
it->second = P2P_IP_FAILS_BEFORE_BLOCK/2;
block_ip(address);
block_host(address);
}
return true;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr)
bool node_server<t_payload_net_handler>::parse_peer_from_string(epee::net_utils::network_address& pe, const std::string& node_addr, uint16_t default_port)
{
return epee::string_tools::parse_peer_from_string(pe.ip, pe.port, node_addr);
return epee::net_utils::create_network_address(pe, node_addr, default_port);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@ -306,10 +306,9 @@ namespace nodetool
{
nodetool::peerlist_entry pe = AUTO_VAL_INIT(pe);
pe.id = crypto::rand<uint64_t>();
bool r = parse_peer_from_string(pe.adr, pr_str);
const uint16_t default_port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT;
bool r = parse_peer_from_string(pe.adr, pr_str, default_port);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
if (pe.adr.port == 0)
pe.adr.port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT;
m_command_line_peers.push_back(pe);
}
}
@ -359,7 +358,7 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
inline void append_net_address(
std::vector<net_address> & seed_nodes
std::vector<epee::net_utils::network_address> & seed_nodes
, std::string const & addr
)
{
@ -383,15 +382,14 @@ namespace nodetool
ip::tcp::endpoint endpoint = *i;
if (endpoint.address().is_v4())
{
nodetool::net_address na;
na.ip = boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong());
na.port = endpoint.port();
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()));
seed_nodes.push_back(na);
MINFO("Added seed node: " << endpoint.address().to_v4().to_string(ec) << ':' << na.port);
MINFO("Added seed node: " << na.str());
}
else
{
MDEBUG("IPv6 doesn't supported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
MERROR("IPv6 unsupported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
throw std::runtime_error("IPv6 unsupported");
}
}
}
@ -752,10 +750,10 @@ namespace nodetool
return;
}
if(!handle_remote_peerlist(rsp.local_peerlist, rsp.node_data.local_time, context))
if(!handle_remote_peerlist(rsp.local_peerlist_new, rsp.node_data.local_time, context))
{
LOG_ERROR_CC(context, "COMMAND_HANDSHAKE: failed to handle_remote_peerlist(...), closing connection.");
add_ip_fail(context.m_remote_ip);
add_host_fail(context.m_remote_address);
return;
}
hsh_result = true;
@ -769,7 +767,7 @@ namespace nodetool
}
pi = context.peer_id = rsp.node_data.peer_id;
m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_ip, context.m_remote_port);
m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address);
if(rsp.node_data.peer_id == m_config.m_peer_id)
{
@ -820,14 +818,14 @@ namespace nodetool
return;
}
if(!handle_remote_peerlist(rsp.local_peerlist, rsp.local_time, context))
if(!handle_remote_peerlist(rsp.local_peerlist_new, rsp.local_time, context))
{
LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
m_net_server.get_config_object().close(context.m_connection_id );
add_ip_fail(context.m_remote_ip);
add_host_fail(context.m_remote_address);
}
if(!context.m_is_income)
m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_ip, context.m_remote_port);
m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address);
m_payload_handler.process_payload_sync_data(rsp.payload_data, context, false);
});
@ -862,7 +860,7 @@ namespace nodetool
bool used = false;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr.ip == cntxt.m_remote_ip && peer.adr.port == cntxt.m_remote_port))
if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
{
used = true;
return false;//stop enumerating
@ -884,7 +882,7 @@ namespace nodetool
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr.ip == cntxt.m_remote_ip && peer.adr.port == cntxt.m_remote_port))
if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
{
used = true;
@ -898,12 +896,12 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_addr_connected(const net_address& peer)
bool node_server<t_payload_net_handler>::is_addr_connected(const epee::net_utils::network_address& peer)
{
bool connected = false;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if(!cntxt.m_is_income && peer.ip == cntxt.m_remote_ip && peer.port == cntxt.m_remote_port)
if(!cntxt.m_is_income && peer == cntxt.m_remote_address)
{
connected = true;
return false;//stop enumerating
@ -924,7 +922,7 @@ namespace nodetool
} while(0)
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, PeerType peer_type, uint64_t first_seen_stamp)
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const epee::net_utils::network_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, PeerType peer_type, uint64_t first_seen_stamp)
{
if (m_current_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit
{
@ -936,23 +934,24 @@ namespace nodetool
m_current_number_of_out_peers --; // atomic variable, update time = 1s
return false;
}
MDEBUG("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":"
<< epee::string_tools::num_to_string_fast(na.port) << "(peer_type=" << peer_type << ", last_seen: "
MDEBUG("Connecting to " << na.str() << "(peer_type=" << peer_type << ", last_seen: "
<< (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
<< ")...");
CHECK_AND_ASSERT_MES(na.type() == typeid(epee::net_utils::ipv4_network_address), false,
"Only IPv4 addresses are supported here, got " << na.type().name());
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(na.ip),
epee::string_tools::num_to_string_fast(na.port),
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
con);
if(!res)
{
bool is_priority = is_priority_node(na);
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to "
<< epee::string_tools::get_ip_string_from_int32(na.ip)
<< ":" << epee::string_tools::num_to_string_fast(na.port)
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " << na.str()
/*<< ", try " << try_count*/);
//m_peerlist.set_peer_unreachable(pe);
return false;
@ -965,8 +964,7 @@ namespace nodetool
{
bool is_priority = is_priority_node(na);
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer "
<< epee::string_tools::get_ip_string_from_int32(na.ip)
<< ":" << epee::string_tools::num_to_string_fast(na.port)
<< na.str()
/*<< ", try " << try_count*/);
return false;
}
@ -999,25 +997,26 @@ namespace nodetool
}
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::check_connection_and_handshake_with_peer(const net_address& na, uint64_t last_seen_stamp)
bool node_server<t_payload_net_handler>::check_connection_and_handshake_with_peer(const epee::net_utils::network_address& na, uint64_t last_seen_stamp)
{
LOG_PRINT_L1("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":"
<< epee::string_tools::num_to_string_fast(na.port) << "(last_seen: "
LOG_PRINT_L1("Connecting to " << na.str() << "(last_seen: "
<< (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
<< ")...");
CHECK_AND_ASSERT_MES(na.type() == typeid(epee::net_utils::ipv4_network_address), false,
"Only IPv4 addresses are supported here, got " << na.type().name());
const epee::net_utils::ipv4_network_address &ipv4 = na.as<epee::net_utils::ipv4_network_address>();
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(na.ip),
epee::string_tools::num_to_string_fast(na.port),
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
con);
if (!res) {
bool is_priority = is_priority_node(na);
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to "
<< epee::string_tools::get_ip_string_from_int32(na.ip)
<< ":" << epee::string_tools::num_to_string_fast(na.port));
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " << na.str());
return false;
}
@ -1028,9 +1027,7 @@ namespace nodetool
if (!res) {
bool is_priority = is_priority_node(na);
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer "
<< epee::string_tools::get_ip_string_from_int32(na.ip)
<< ":" << epee::string_tools::num_to_string_fast(na.port));
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer " << na.str());
return false;
}
@ -1046,7 +1043,7 @@ namespace nodetool
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_addr_recently_failed(const net_address& addr)
bool node_server<t_payload_net_handler>::is_addr_recently_failed(const epee::net_utils::network_address& addr)
{
CRITICAL_REGION_LOCAL(m_conn_fails_cache_lock);
auto it = m_conn_fails_cache.find(addr);
@ -1063,14 +1060,14 @@ namespace nodetool
bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist)
{
for (const auto& pe: anchor_peerlist) {
_note("Considering connecting (out) to peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port));
_note("Considering connecting (out) to peer: " << pe.id << " " << pe.adr.str());
if(is_peer_used(pe)) {
_note("Peer is used");
continue;
}
if(!is_remote_ip_allowed(pe.adr.ip)) {
if(!is_remote_host_allowed(pe.adr)) {
continue;
}
@ -1078,8 +1075,7 @@ namespace nodetool
continue;
}
MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
MDEBUG("Selected peer: " << pe.id << " " << pe.adr.str()
<< "[peer_type=" << anchor
<< "] first_seen: " << epee::misc_utils::get_time_interval_string(time(NULL) - pe.first_seen));
@ -1130,21 +1126,20 @@ namespace nodetool
++try_count;
_note("Considering connecting (out) to peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port));
_note("Considering connecting (out) to peer: " << pe.id << " " << pe.adr.str());
if(is_peer_used(pe)) {
_note("Peer is used");
continue;
}
if(!is_remote_ip_allowed(pe.adr.ip))
if(!is_remote_host_allowed(pe.adr))
continue;
if(is_addr_recently_failed(pe.adr))
continue;
MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
MDEBUG("Selected peer: " << pe.id << " " << pe.adr.str()
<< "[peer_list=" << (use_white_list ? white : gray)
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
@ -1325,7 +1320,7 @@ namespace nodetool
{
if(be.last_seen > local_time)
{
MWARNING("FOUND FUTURE peerlist for entry " << epee::string_tools::get_ip_string_from_int32(be.adr.ip) << ":" << be.adr.port << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
MWARNING("FOUND FUTURE peerlist for entry " << be.adr.str() << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
return false;
}
be.last_seen += delta;
@ -1421,8 +1416,7 @@ namespace nodetool
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
connection_entry ce;
ce.adr.ip = cntxt.m_remote_ip;
ce.adr.port = cntxt.m_remote_port;
ce.adr = cntxt.m_remote_address;
ce.id = cntxt.peer_id;
ce.is_income = cntxt.m_is_income;
rsp.connections_list.push_back(ce);
@ -1512,19 +1506,24 @@ namespace nodetool
if(!node_data.my_port)
return false;
uint32_t actual_ip = context.m_remote_ip;
if(!m_peerlist.is_ip_allowed(actual_ip))
CHECK_AND_ASSERT_MES(context.m_remote_address.type() == typeid(epee::net_utils::ipv4_network_address), false,
"Only IPv4 addresses are supported here, got " << context.m_remote_address.type().name());
const epee::net_utils::network_address na = context.m_remote_address;
uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip();
if(!m_peerlist.is_host_allowed(context.m_remote_address))
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));
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,*/ ip, port, pr, this](
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,
const boost::system::error_code& ec)->bool
{
if(ec)
{
LOG_WARNING_CC(ping_context, "back ping connect failed to " << ip << ":" << port);
LOG_WARNING_CC(ping_context, "back ping connect failed to " << address.str());
return false;
}
COMMAND_PING::request req;
@ -1543,13 +1542,13 @@ namespace nodetool
{
if(code <= 0)
{
LOG_ERROR_CC(ping_context, "Failed to invoke COMMAND_PING to " << ip << ":" << port << "(" << code << ", " << epee::levin::get_err_descr(code) << ")");
LOG_ERROR_CC(ping_context, "Failed to invoke COMMAND_PING to " << address.str() << "(" << code << ", " << epee::levin::get_err_descr(code) << ")");
return;
}
if(rsp.status != PING_OK_RESPONSE_STATUS_TEXT || pr != rsp.peer_id)
{
LOG_ERROR_CC(ping_context, "back ping invoke wrong response \"" << rsp.status << "\" from" << ip << ":" << port << ", hsh_peer_id=" << pr_ << ", rsp.peer_id=" << rsp.peer_id);
LOG_ERROR_CC(ping_context, "back ping invoke wrong response \"" << rsp.status << "\" from" << address.str() << ", hsh_peer_id=" << pr_ << ", rsp.peer_id=" << rsp.peer_id);
m_net_server.get_config_object().close(ping_context.m_connection_id);
return;
}
@ -1559,7 +1558,7 @@ namespace nodetool
if(!inv_call_res)
{
LOG_ERROR_CC(ping_context, "back ping invoke failed to " << ip << ":" << port);
LOG_ERROR_CC(ping_context, "back ping invoke failed to " << address.str());
m_net_server.get_config_object().close(ping_context.m_connection_id);
return false;
}
@ -1610,7 +1609,7 @@ namespace nodetool
//fill response
rsp.local_time = time(NULL);
m_peerlist.get_peerlist_head(rsp.local_peerlist);
m_peerlist.get_peerlist_head(rsp.local_peerlist_new);
m_payload_handler.get_payload_sync_data(rsp.payload_data);
LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC");
return 1;
@ -1624,7 +1623,7 @@ namespace nodetool
LOG_INFO_CC(context, "WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
drop_connection(context);
add_ip_fail(context.m_remote_ip);
add_host_fail(context.m_remote_address);
return 1;
}
@ -1632,7 +1631,7 @@ namespace nodetool
{
LOG_ERROR_CC(context, "COMMAND_HANDSHAKE came not from incoming connection");
drop_connection(context);
add_ip_fail(context.m_remote_ip);
add_host_fail(context.m_remote_address);
return 1;
}
@ -1650,9 +1649,9 @@ namespace nodetool
return 1;
}
if(has_too_many_connections(context.m_remote_ip))
if(has_too_many_connections(context.m_remote_address))
{
LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << epee::string_tools::get_ip_string_from_int32(context.m_remote_ip) << " REFUSED, too many connections from the same address");
LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << context.m_remote_address.host_str() << " REFUSED, too many connections from the same address");
drop_connection(context);
return 1;
}
@ -1667,16 +1666,18 @@ namespace nodetool
//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]()
{
CHECK_AND_ASSERT_MES(context.m_remote_address.type() == typeid(epee::net_utils::ipv4_network_address), void(),
"Only IPv4 addresses are supported here, got " << context.m_remote_address.type().name());
//called only(!) if success pinged, update local peerlist
peerlist_entry pe;
pe.adr.ip = context.m_remote_ip;
pe.adr.port = port_l;
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));
time_t last_seen;
time(&last_seen);
pe.last_seen = static_cast<int64_t>(last_seen);
pe.id = peer_id_l;
this->m_peerlist.append_with_peer_white(pe);
LOG_DEBUG_CC(context, "PING SUCCESS " << epee::string_tools::get_ip_string_from_int32(context.m_remote_ip) << ":" << port_l);
LOG_DEBUG_CC(context, "PING SUCCESS " << context.m_remote_address.host_str() << ":" << port_l);
});
}
@ -1686,7 +1687,7 @@ namespace nodetool
});
//fill response
m_peerlist.get_peerlist_head(rsp.local_peerlist);
m_peerlist.get_peerlist_head(rsp.local_peerlist_new);
get_local_node_data(rsp.node_data);
m_payload_handler.get_payload_sync_data(rsp.payload_data);
LOG_DEBUG_CC(context, "COMMAND_HANDSHAKE");
@ -1726,7 +1727,7 @@ namespace nodetool
std::stringstream ss;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
ss << epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) << ":" << cntxt.m_remote_port
ss << cntxt.m_remote_address.str()
<< " \t\tpeer_id " << cntxt.peer_id
<< " \t\tconn_id " << epee::string_tools::get_str_from_guid_a(cntxt.m_connection_id) << (cntxt.m_is_income ? " INC":" OUT")
<< std::endl;
@ -1746,9 +1747,8 @@ namespace nodetool
void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context)
{
if (!m_net_server.is_stop_signal_sent() && !context.m_is_income) {
nodetool::net_address na = AUTO_VAL_INIT(na);
na.ip = context.m_remote_ip;
na.port = context.m_remote_port;
epee::net_utils::network_address na = AUTO_VAL_INIT(na);
na = context.m_remote_address;
m_peerlist.remove_from_peer_anchor(na);
}
@ -1757,7 +1757,7 @@ namespace nodetool
}
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_priority_node(const net_address& na)
bool node_server<t_payload_net_handler>::is_priority_node(const epee::net_utils::network_address& na)
{
return (std::find(m_priority_peers.begin(), m_priority_peers.end(), na) != m_priority_peers.end()) || (std::find(m_exclusive_peers.begin(), m_exclusive_peers.end(), na) != m_exclusive_peers.end());
}
@ -1765,7 +1765,7 @@ namespace nodetool
template<class t_payload_net_handler> template <class Container>
bool node_server<t_payload_net_handler>::connect_to_peerlist(const Container& peers)
{
for(const net_address& na: peers)
for(const epee::net_utils::network_address& na: peers)
{
if(m_net_server.is_stop_signal_sent())
return false;
@ -1786,11 +1786,10 @@ namespace nodetool
for(const std::string& pr_str: perrs)
{
nodetool::net_address na = AUTO_VAL_INIT(na);
bool r = parse_peer_from_string(na, pr_str);
epee::net_utils::network_address na = AUTO_VAL_INIT(na);
const uint16_t default_port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT;
bool r = parse_peer_from_string(na, pr_str, default_port);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
if (na.port == 0)
na.port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT;
container.push_back(na);
}
@ -1884,14 +1883,14 @@ namespace nodetool
}
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::has_too_many_connections(const uint32_t ip)
bool node_server<t_payload_net_handler>::has_too_many_connections(const epee::net_utils::network_address &address)
{
const uint8_t max_connections = 1;
uint8_t count = 0;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if (cntxt.m_is_income && cntxt.m_remote_ip == ip) {
if (cntxt.m_is_income && cntxt.m_remote_address.is_same_host(address)) {
count++;
if (count > max_connections) {
@ -1919,14 +1918,14 @@ namespace nodetool
if (!success) {
m_peerlist.remove_from_peer_gray(pe);
LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id);
LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << std::hex << pe.id);
return true;
}
m_peerlist.set_peer_just_seen(pe.id, pe.adr);
LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id);
LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << std::hex << pe.id);
return true;
}

View file

@ -51,10 +51,10 @@ namespace nodetool
virtual void request_callback(const epee::net_utils::connection_context_base& context)=0;
virtual uint64_t get_connections_count()=0;
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
virtual bool block_ip(uint32_t adress, time_t seconds = 0)=0;
virtual bool unblock_ip(uint32_t adress)=0;
virtual std::map<uint32_t, time_t> get_blocked_ips()=0;
virtual bool add_ip_fail(uint32_t adress)=0;
virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds = 0)=0;
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
virtual bool add_host_fail(const epee::net_utils::network_address &address)=0;
};
template<class t_connection_context>
@ -93,19 +93,19 @@ namespace nodetool
{
return false;
}
virtual bool block_ip(uint32_t adress, time_t seconds)
virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds)
{
return true;
}
virtual bool unblock_ip(uint32_t adress)
virtual bool unblock_host(const epee::net_utils::network_address &address)
{
return true;
}
virtual std::map<uint32_t, time_t> get_blocked_ips()
virtual std::map<std::string, time_t> get_blocked_hosts()
{
return std::map<uint32_t, time_t>();
return std::map<std::string, time_t>();
}
virtual bool add_ip_fail(uint32_t adress)
virtual bool add_host_fail(const epee::net_utils::network_address &address)
{
return true;
}

View file

@ -54,7 +54,7 @@
#include "net_peerlist_boost_serialization.h"
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 5
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 6
namespace nodetool
{
@ -78,14 +78,13 @@ namespace nodetool
bool append_with_peer_white(const peerlist_entry& pr);
bool append_with_peer_gray(const peerlist_entry& pr);
bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr);
bool set_peer_unreachable(const peerlist_entry& pr);
bool is_ip_allowed(uint32_t ip);
bool is_host_allowed(const epee::net_utils::network_address &address);
bool get_random_gray_peer(peerlist_entry& pe);
bool remove_from_peer_gray(const peerlist_entry& pe);
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
bool remove_from_peer_anchor(const net_address& addr);
bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
private:
struct by_time{};
@ -130,7 +129,7 @@ namespace nodetool
peerlist_entry,
boost::multi_index::indexed_by<
// access by peerlist_entry::net_adress
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >,
// sort by peerlist_entry::last_seen<
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
>
@ -142,7 +141,7 @@ namespace nodetool
// access by peerlist_entry::id<
boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >,
// access by peerlist_entry::net_adress
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >,
// sort by peerlist_entry::last_seen<
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
>
@ -152,16 +151,45 @@ namespace nodetool
anchor_peerlist_entry,
boost::multi_index::indexed_by<
// access by anchor_peerlist_entry::net_adress
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,net_address,&anchor_peerlist_entry::adr> >,
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,epee::net_utils::network_address,&anchor_peerlist_entry::adr> >,
// sort by anchor_peerlist_entry::first_seen
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> >
>
> anchor_peers_indexed;
public:
template <class Archive, class List, class Element, class t_version_type>
void serialize_peers(Archive &a, List &list, Element ple, const t_version_type ver)
{
if (typename Archive::is_saving())
{
uint64_t size = list.size();
a & size;
for (auto p: list)
{
a & p;
}
}
else
{
uint64_t size;
a & size;
list.clear();
while (size--)
{
a & ple;
list.insert(ple);
}
}
}
template <class Archive, class t_version_type>
void serialize(Archive &a, const t_version_type ver)
{
// at v6, we drop existing peerlists, because annoying change
if (ver < 6)
return;
if(ver < 3)
return;
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -174,14 +202,25 @@ namespace nodetool
return;
}
#if 0
// trouble loading more than one peer, can't find why
a & m_peers_white;
a & m_peers_gray;
#else
serialize_peers(a, m_peers_white, peerlist_entry(), ver);
serialize_peers(a, m_peers_gray, peerlist_entry(), ver);
#endif
if(ver < 5) {
return;
}
#if 0
// trouble loading more than one peer, can't find why
a & m_peers_anchor;
#else
serialize_peers(a, m_peers_anchor, anchor_peerlist_entry(), ver);
#endif
}
private:
@ -284,13 +323,13 @@ namespace nodetool
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::is_ip_allowed(uint32_t ip)
bool peerlist_manager::is_host_allowed(const epee::net_utils::network_address &address)
{
//never allow loopback ip
if(epee::net_utils::is_ip_loopback(ip))
if(address.is_loopback())
return false;
if(!m_allow_local_ip && epee::net_utils::is_ip_local(ip))
if(!m_allow_local_ip && address.is_local())
return false;
return true;
@ -336,16 +375,7 @@ namespace nodetool
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port)
{
net_address addr;
addr.ip = ip;
addr.port = port;
return set_peer_just_seen(peer, addr);
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::set_peer_just_seen(peerid_type peer, const net_address& addr)
bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr)
{
TRY_ENTRY();
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -362,7 +392,7 @@ namespace nodetool
bool peerlist_manager::append_with_peer_white(const peerlist_entry& ple)
{
TRY_ENTRY();
if(!is_ip_allowed(ple.adr.ip))
if(!is_host_allowed(ple.adr))
return true;
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -392,7 +422,7 @@ namespace nodetool
bool peerlist_manager::append_with_peer_gray(const peerlist_entry& ple)
{
TRY_ENTRY();
if(!is_ip_allowed(ple.adr.ip))
if(!is_host_allowed(ple.adr))
return true;
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -496,7 +526,7 @@ namespace nodetool
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::remove_from_peer_anchor(const net_address& addr)
bool peerlist_manager::remove_from_peer_anchor(const epee::net_utils::network_address& addr)
{
TRY_ENTRY();

View file

@ -30,16 +30,43 @@
#pragma once
#include "net/net_utils_base.h"
namespace boost
{
namespace serialization
{
//BOOST_CLASS_VERSION(odetool::net_adress, 1)
template <class Archive, class ver_type>
inline void serialize(Archive &a, nodetool::net_address& na, const ver_type ver)
enum { sertype_ipv4_address };
static inline uint8_t get_type(const epee::net_utils::network_address &na)
{
a & na.ip;
a & na.port;
if (na.type() == typeid(epee::net_utils::ipv4_network_address))
return sertype_ipv4_address;
throw std::runtime_error("Unsupported network address type");
return 0;
}
template <class Archive, class ver_type>
inline void serialize(Archive &a, epee::net_utils::network_address& na, const ver_type ver)
{
uint8_t type;
if (typename Archive::is_saving())
type = get_type(na);
a & type;
switch (type)
{
case sertype_ipv4_address:
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;
default:
throw std::runtime_error("Unsupported network address type");
}
}
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;
}

View file

@ -32,6 +32,7 @@
#include <boost/uuid/uuid.hpp>
#include "serialization/keyvalue_serialization.h"
#include "net/net_utils_base.h"
#include "misc_language.h"
#include "cryptonote_config.h"
#include "crypto/crypto.h"
@ -43,46 +44,64 @@ namespace nodetool
#pragma pack (push, 1)
struct net_address
struct network_address_old
{
uint32_t ip;
uint32_t port;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(ip)
KV_SERIALIZE(port)
END_KV_SERIALIZE_MAP()
};
struct peerlist_entry
template<typename AddressType>
struct peerlist_entry_base
{
net_address adr;
AddressType adr;
peerid_type id;
int64_t last_seen;
};
struct anchor_peerlist_entry
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(adr)
KV_SERIALIZE(id)
KV_SERIALIZE(last_seen)
END_KV_SERIALIZE_MAP()
};
typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
template<typename AddressType>
struct anchor_peerlist_entry_base
{
net_address adr;
AddressType adr;
peerid_type id;
int64_t first_seen;
};
struct connection_entry
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(adr)
KV_SERIALIZE(id)
KV_SERIALIZE(first_seen)
END_KV_SERIALIZE_MAP()
};
typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
template<typename AddressType>
struct connection_entry_base
{
net_address adr;
AddressType adr;
peerid_type id;
bool is_income;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(adr)
KV_SERIALIZE(id)
KV_SERIALIZE(is_income)
END_KV_SERIALIZE_MAP()
};
typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
#pragma pack(pop)
inline
bool operator < (const net_address& a, const net_address& b)
{
return epee::misc_utils::is_less_as_pod(a, b);
}
inline
bool operator == (const net_address& a, const net_address& b)
{
return memcmp(&a, &b, sizeof(a)) == 0;
}
inline
std::string print_peerlist_to_string(const std::list<peerlist_entry>& pl)
{
@ -92,7 +111,7 @@ namespace nodetool
ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
for(const peerlist_entry& pe: pl)
{
ss << pe.id << "\t" << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port) << " \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();
}
@ -157,12 +176,40 @@ namespace nodetool
{
basic_node_data node_data;
t_playload_type payload_data;
std::list<peerlist_entry> local_peerlist;
std::list<peerlist_entry> local_peerlist_new;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(node_data)
KV_SERIALIZE(payload_data)
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist)
if (is_store)
{
// saving: save both, so old and new peers can understand it
KV_SERIALIZE(local_peerlist_new)
std::list<peerlist_entry_base<network_address_old>> local_peerlist;
for (const auto &p: this_ref.local_peerlist_new)
{
if (p.adr.type() == typeid(epee::net_utils::ipv4_network_address))
{
const epee::net_utils::network_address &na = p.adr;
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
}
else
MDEBUG("Not including in legacy peer list: " << p.adr.str());
}
epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
}
else
{
// loading: load old list only if there is no new one
if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
{
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}));
}
}
END_KV_SERIALIZE_MAP()
};
};
@ -188,12 +235,40 @@ namespace nodetool
{
uint64_t local_time;
t_playload_type payload_data;
std::list<peerlist_entry> local_peerlist;
std::list<peerlist_entry> local_peerlist_new;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(local_time)
KV_SERIALIZE(payload_data)
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist)
if (is_store)
{
// saving: save both, so old and new peers can understand it
KV_SERIALIZE(local_peerlist_new)
std::list<peerlist_entry_base<network_address_old>> local_peerlist;
for (const auto &p: this_ref.local_peerlist_new)
{
if (p.adr.type() == typeid(epee::net_utils::ipv4_network_address))
{
const epee::net_utils::network_address &na = p.adr;
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
}
else
MDEBUG("Not including in legacy peer list: " << p.adr.str());
}
epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
}
else
{
// loading: load old list only if there is no new one
if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
{
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}));
}
}
END_KV_SERIALIZE_MAP()
};
};

View file

@ -736,12 +736,20 @@ namespace cryptonote
for (auto & entry : white_list)
{
res.white_list.emplace_back(entry.id, entry.adr.ip, entry.adr.port, entry.last_seen);
if (entry.adr.type() == typeid(epee::net_utils::ipv4_network_address))
res.white_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen);
else
res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen);
}
for (auto & entry : gray_list)
{
res.gray_list.emplace_back(entry.id, entry.adr.ip, entry.adr.port, entry.last_seen);
if (entry.adr.type() == typeid(epee::net_utils::ipv4_network_address))
res.gray_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen);
else
res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen);
}
res.status = CORE_RPC_STATUS_OK;
@ -1300,12 +1308,16 @@ namespace cryptonote
}
auto now = time(nullptr);
std::map<uint32_t, time_t> blocked_ips = m_p2p.get_blocked_ips();
for (std::map<uint32_t, time_t>::const_iterator i = blocked_ips.begin(); i != blocked_ips.end(); ++i)
std::map<std::string, time_t> blocked_hosts = m_p2p.get_blocked_hosts();
for (std::map<std::string, time_t>::const_iterator i = blocked_hosts.begin(); i != blocked_hosts.end(); ++i)
{
if (i->second > now) {
COMMAND_RPC_GETBANS::ban b;
b.ip = i->first;
b.host = i->first;
b.ip = 0;
uint32_t ip;
if (epee::string_tools::get_ip_int32_from_string(ip, i->first))
b.ip = ip;
b.seconds = i->second - now;
res.bans.push_back(b);
}
@ -1326,10 +1338,24 @@ namespace cryptonote
for (auto i = req.bans.begin(); i != req.bans.end(); ++i)
{
if (i->ban)
m_p2p.block_ip(i->ip, i->seconds);
epee::net_utils::network_address na;
if (!i->host.empty())
{
if (!epee::net_utils::create_network_address(na, i->host))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Unsupported host type";
return false;
}
}
else
m_p2p.unblock_ip(i->ip);
{
na.reset(new epee::net_utils::ipv4_network_address(i->ip, 0));
}
if (i->ban)
m_p2p.block_host(na, i->seconds);
else
m_p2p.unblock_host(na);
}
res.status = CORE_RPC_STATUS_OK;

View file

@ -49,7 +49,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 1
#define CORE_RPC_VERSION_MINOR 10
#define CORE_RPC_VERSION_MINOR 11
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@ -861,18 +861,23 @@ namespace cryptonote
struct peer {
uint64_t id;
std::string host;
uint32_t ip;
uint16_t port;
uint64_t last_seen;
peer() = default;
peer(uint64_t id, const std::string &host, uint64_t last_seen)
: id(id), host(host), ip(0), port(0), last_seen(last_seen)
{}
peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen)
: id(id), ip(ip), port(port), last_seen(last_seen)
: id(id), host(std::to_string(ip)), ip(ip), port(port), last_seen(last_seen)
{}
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id)
KV_SERIALIZE(host)
KV_SERIALIZE(ip)
KV_SERIALIZE(port)
KV_SERIALIZE(last_seen)
@ -1226,10 +1231,12 @@ namespace cryptonote
{
struct ban
{
std::string host;
uint32_t ip;
uint32_t seconds;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(host)
KV_SERIALIZE(ip)
KV_SERIALIZE(seconds)
END_KV_SERIALIZE_MAP()
@ -1257,11 +1264,13 @@ namespace cryptonote
{
struct ban
{
std::string host;
uint32_t ip;
bool ban;
uint32_t seconds;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(host)
KV_SERIALIZE(ip)
KV_SERIALIZE(ban)
KV_SERIALIZE(seconds)