aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-05-27 11:35:54 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-05-27 11:35:54 +0100
commit072102cfd23c47d36f4d51875026339a767f22ae (patch)
tree3005737650989527f71b2c742696e6dfb0a2a7f6 /src
parentMerge pull request #2015 (diff)
downloadmonero-072102cfd23c47d36f4d51875026339a767f22ae.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_defs.h4
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl51
-rw-r--r--src/p2p/net_node.h42
-rw-r--r--src/p2p/net_node.inl215
-rw-r--r--src/p2p/net_node_common.h18
-rw-r--r--src/p2p/net_peerlist.h78
-rw-r--r--src/p2p/net_peerlist_boost_serialization.h35
-rw-r--r--src/p2p/p2p_protocol_defs.h121
-rw-r--r--src/rpc/core_rpc_server.cpp40
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h13
10 files changed, 386 insertions, 231 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h
index fd5b980b8..6f6c1a803 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_defs.h
+++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h
@@ -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)
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 79578a34e..dbb8af445 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -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;
}
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 13cd3f5b0..8798a52e0 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -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;
};
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 5c903b1f5..47582cb96 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -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;
}
diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h
index 6aba7aa24..42de2655d 100644
--- a/src/p2p/net_node_common.h
+++ b/src/p2p/net_node_common.h
@@ -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;
}
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index de0f51cc3..a30a05422 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -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();
diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h
index 6891ac80c..0a21895cf 100644
--- a/src/p2p/net_peerlist_boost_serialization.h
+++ b/src/p2p/net_peerlist_boost_serialization.h
@@ -30,16 +30,43 @@
#pragma once
+#include "net/net_utils_base.h"
+
namespace boost
{
namespace serialization
{
- //BOOST_CLASS_VERSION(odetool::net_adress, 1)
+ enum { sertype_ipv4_address };
+ static inline uint8_t get_type(const epee::net_utils::network_address &na)
+ {
+ 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, nodetool::net_address& na, const ver_type ver)
+ inline void serialize(Archive &a, epee::net_utils::ipv4_network_address& na, const ver_type ver)
{
- a & na.ip;
- a & na.port;
+ a & na.m_ip;
+ a & na.m_port;
}
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index 5ec012714..d60990f8a 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -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;
+
+ 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;
- struct anchor_peerlist_entry
+ template<typename AddressType>
+ struct anchor_peerlist_entry_base
{
- net_address adr;
+ AddressType adr;
peerid_type id;
int64_t first_seen;
+
+ 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;
- struct connection_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()
};
};
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 76a69fbf6..640c53522 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -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)
{
+ 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
+ {
+ na.reset(new epee::net_utils::ipv4_network_address(i->ip, 0));
+ }
if (i->ban)
- m_p2p.block_ip(i->ip, i->seconds);
+ m_p2p.block_host(na, i->seconds);
else
- m_p2p.unblock_ip(i->ip);
+ m_p2p.unblock_host(na);
}
res.status = CORE_RPC_STATUS_OK;
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 9bdadf0d1..28be288c4 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -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)