mirror of
https://github.com/monero-project/monero.git
synced 2024-10-01 11:49:47 -04:00
Merge pull request #2052
072102cf
abstracted nework addresses (moneromooo-monero)
This commit is contained in:
commit
a237f90c5b
@ -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;
|
||||
|
@ -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(){}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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)) \
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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(':');
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
@ -990,7 +975,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;
|
||||
}
|
||||
@ -998,7 +983,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;
|
||||
}
|
||||
@ -1150,7 +1135,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;
|
||||
}
|
||||
|
||||
@ -1159,7 +1144,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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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()
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
@ -1308,12 +1316,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);
|
||||
}
|
||||
@ -1334,10 +1346,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;
|
||||
|
@ -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)
|
||||
@ -1271,10 +1276,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()
|
||||
@ -1302,11 +1309,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)
|
||||
|
Loading…
Reference in New Issue
Block a user