aboutsummaryrefslogtreecommitdiff
path: root/src/p2p
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2019-04-10 18:34:30 -0400
committerThomas Winget <tewinget@gmail.com>2019-07-31 20:04:57 -0400
commit155475d9719694c838297cb3fbc94a2782329d46 (patch)
tree0a8ac9cfc80c123f456fc2416b60752a42ae4f9b /src/p2p
parentMerge pull request #5635 (diff)
downloadmonero-155475d9719694c838297cb3fbc94a2782329d46.tar.xz
Add IPv6 support
new cli options (RPC ones also apply to wallet): --p2p-bind-ipv6-address (default = "::") --p2p-bind-port-ipv6 (default same as ipv4 port for given nettype) --rpc-bind-ipv6-address (default = "::1") --p2p-use-ipv6 (default false) --rpc-use-ipv6 (default false) --p2p-require-ipv4 (default true, if ipv4 bind fails and this is true, will not continue even if ipv6 bind successful) --rpc-require-ipv4 (default true, description as above) ipv6 addresses are to be specified as "[xx:xx:xx::xx:xx]:port" except in the cases of the cli args for bind address. For those the square braces can be omitted.
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/net_node.cpp21
-rw-r--r--src/p2p/net_node.h21
-rw-r--r--src/p2p/net_node.inl192
-rw-r--r--src/p2p/net_peerlist_boost_serialization.h31
4 files changed, 231 insertions, 34 deletions
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index a44297c17..bb51be242 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -108,10 +108,11 @@ namespace
namespace nodetool
{
- const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
+ const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol (IPv4)", "0.0.0.0"};
+ const command_line::arg_descriptor<std::string> arg_p2p_bind_ipv6_address = {"p2p-bind-ipv6-address", "Interface for p2p network protocol (IPv6)", "::"};
const command_line::arg_descriptor<std::string, false, true, 2> arg_p2p_bind_port = {
"p2p-bind-port"
- , "Port for p2p network protocol"
+ , "Port for p2p network protocol (IPv4)"
, std::to_string(config::P2P_DEFAULT_PORT)
, {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }}
, [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string {
@@ -122,6 +123,20 @@ namespace nodetool
return val;
}
};
+ const command_line::arg_descriptor<std::string, false, true, 2> arg_p2p_bind_port_ipv6 = {
+ "p2p-bind-port-ipv6"
+ , "Port for p2p network protocol (IPv6)"
+ , std::to_string(config::P2P_DEFAULT_PORT)
+ , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }}
+ , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string {
+ if (testnet_stagenet[0] && defaulted)
+ return std::to_string(config::testnet::P2P_DEFAULT_PORT);
+ else if (testnet_stagenet[1] && defaulted)
+ return std::to_string(config::stagenet::P2P_DEFAULT_PORT);
+ return val;
+ }
+ };
+
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
@@ -136,6 +151,8 @@ namespace nodetool
const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"};
const command_line::arg_descriptor<std::string> arg_igd = {"igd", "UPnP port mapping (disabled, enabled, delayed)", "delayed"};
+ const command_line::arg_descriptor<bool> arg_p2p_use_ipv6 = {"p2p-use-ipv6", "Enable IPv6 for p2p", false};
+ const command_line::arg_descriptor<bool> arg_p2p_require_ipv4 = {"p2p-require-ipv4", "Require successful IPv4 bind for p2p", true};
const command_line::arg_descriptor<int64_t> arg_out_peers = {"out-peers", "set max number of out peers", -1};
const command_line::arg_descriptor<int64_t> arg_in_peers = {"in-peers", "set max number of in peers", -1};
const command_line::arg_descriptor<int> arg_tos_flag = {"tos-flag", "set TOS flag", -1};
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 0d95ceb99..cf6b2c67b 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -151,7 +151,9 @@ namespace nodetool
: m_connect(nullptr),
m_net_server(epee::net_utils::e_connection_type_P2P),
m_bind_ip(),
+ m_bind_ipv6_address(),
m_port(),
+ m_port_ipv6(),
m_our_address(),
m_peerlist(),
m_config{},
@@ -167,7 +169,9 @@ namespace nodetool
: m_connect(nullptr),
m_net_server(public_service, epee::net_utils::e_connection_type_P2P),
m_bind_ip(),
+ m_bind_ipv6_address(),
m_port(),
+ m_port_ipv6(),
m_our_address(),
m_peerlist(),
m_config{},
@@ -182,7 +186,9 @@ namespace nodetool
connect_func* m_connect;
net_server m_net_server;
std::string m_bind_ip;
+ std::string m_bind_ipv6_address;
std::string m_port;
+ std::string m_port_ipv6;
epee::net_utils::network_address m_our_address; // in anonymity networks
peerlist_manager m_peerlist;
config m_config;
@@ -357,7 +363,13 @@ namespace nodetool
bool is_peer_used(const peerlist_entry& peer);
bool is_peer_used(const anchor_peerlist_entry& peer);
bool is_addr_connected(const epee::net_utils::network_address& peer);
- void add_upnp_port_mapping(uint32_t port);
+ void add_upnp_port_mapping_impl(uint32_t port, bool ipv6=false);
+ void add_upnp_port_mapping_v4(uint32_t port);
+ void add_upnp_port_mapping_v6(uint32_t port);
+ void add_upnp_port_mapping(uint32_t port, bool ipv4=true, bool ipv6=false);
+ void delete_upnp_port_mapping_impl(uint32_t port, bool ipv6=false);
+ void delete_upnp_port_mapping_v4(uint32_t port);
+ void delete_upnp_port_mapping_v6(uint32_t port);
void delete_upnp_port_mapping(uint32_t port);
template<class t_callback>
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, const t_callback &cb);
@@ -419,12 +431,15 @@ namespace nodetool
bool m_have_address;
bool m_first_connection_maker_call;
uint32_t m_listening_port;
+ uint32_t m_listening_port_ipv6;
uint32_t m_external_port;
uint16_t m_rpc_port;
bool m_allow_local_ip;
bool m_hide_my_port;
igd_t m_igd;
bool m_offline;
+ bool m_use_ipv6;
+ bool m_require_ipv4;
std::atomic<bool> is_closing;
std::unique_ptr<boost::thread> mPeersLoggerThread;
//critical_section m_connections_lock;
@@ -485,7 +500,11 @@ namespace nodetool
const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s
const int64_t default_limit_down = P2P_DEFAULT_LIMIT_RATE_DOWN; // kB/s
extern const command_line::arg_descriptor<std::string> arg_p2p_bind_ip;
+ extern const command_line::arg_descriptor<std::string> arg_p2p_bind_ipv6_address;
extern const command_line::arg_descriptor<std::string, false, true, 2> arg_p2p_bind_port;
+ extern const command_line::arg_descriptor<std::string, false, true, 2> arg_p2p_bind_port_ipv6;
+ extern const command_line::arg_descriptor<bool> arg_p2p_use_ipv6;
+ extern const command_line::arg_descriptor<bool> arg_p2p_require_ipv4;
extern const command_line::arg_descriptor<uint32_t> arg_p2p_external_port;
extern const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip;
extern const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer;
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 98484fe78..426767365 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -93,7 +93,11 @@ namespace nodetool
void node_server<t_payload_net_handler>::init_options(boost::program_options::options_description& desc)
{
command_line::add_arg(desc, arg_p2p_bind_ip);
+ command_line::add_arg(desc, arg_p2p_bind_ipv6_address);
command_line::add_arg(desc, arg_p2p_bind_port, false);
+ command_line::add_arg(desc, arg_p2p_bind_port_ipv6, false);
+ command_line::add_arg(desc, arg_p2p_use_ipv6);
+ command_line::add_arg(desc, arg_p2p_require_ipv4);
command_line::add_arg(desc, arg_p2p_external_port);
command_line::add_arg(desc, arg_p2p_allow_local_ip);
command_line::add_arg(desc, arg_p2p_add_peer);
@@ -341,7 +345,9 @@ namespace nodetool
network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_];
public_zone.m_connect = &public_connect;
public_zone.m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip);
+ public_zone.m_bind_ipv6_address = command_line::get_arg(vm, arg_p2p_bind_ipv6_address);
public_zone.m_port = command_line::get_arg(vm, arg_p2p_bind_port);
+ public_zone.m_port_ipv6 = command_line::get_arg(vm, arg_p2p_bind_port_ipv6);
public_zone.m_can_pingback = true;
m_external_port = command_line::get_arg(vm, arg_p2p_external_port);
m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip);
@@ -375,6 +381,8 @@ namespace nodetool
return false;
}
m_offline = command_line::get_arg(vm, cryptonote::arg_offline);
+ m_use_ipv6 = command_line::get_arg(vm, arg_p2p_use_ipv6);
+ m_require_ipv4 = command_line::get_arg(vm, arg_p2p_require_ipv4);
if (command_line::has_arg(vm, arg_p2p_add_peer))
{
@@ -518,12 +526,17 @@ namespace nodetool
std::string host = addr;
std::string port = std::to_string(default_port);
- size_t pos = addr.find_last_of(':');
- if (std::string::npos != pos)
+ size_t colon_pos = addr.find_last_of(':');
+ size_t dot_pos = addr.find_last_of('.');
+ size_t square_brace_pos = addr.find('[');
+
+ // IPv6 will have colons regardless. IPv6 and IPv4 address:port will have a colon but also either a . or a [
+ // as IPv6 addresses specified as address:port are to be specified as "[addr:addr:...:addr]:port"
+ // One may also specify an IPv6 address as simply "[addr:addr:...:addr]" without the port; in that case
+ // the square braces will be stripped here.
+ if ((std::string::npos != colon_pos && std::string::npos != dot_pos) || std::string::npos != square_brace_pos)
{
- CHECK_AND_ASSERT_MES(addr.length() - 1 != pos && 0 != pos, false, "Failed to parse seed address from string: '" << addr << '\'');
- host = addr.substr(0, pos);
- port = addr.substr(pos + 1);
+ net::get_network_address_host_and_port(addr, host, port);
}
MINFO("Resolving node address: host=" << host << ", port=" << port);
@@ -546,7 +559,9 @@ namespace nodetool
}
else
{
- MWARNING("IPv6 unsupported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
+ epee::net_utils::network_address na{epee::net_utils::ipv6_network_address{endpoint.address().to_v6(), endpoint.port()}};
+ seed_nodes.push_back(na);
+ MINFO("Added node: " << na.str());
}
}
return true;
@@ -780,21 +795,40 @@ namespace nodetool
if (!zone.second.m_bind_ip.empty())
{
+ std::string ipv6_addr = "";
+ std::string ipv6_port = "";
zone.second.m_net_server.set_connection_filter(this);
- MINFO("Binding on " << zone.second.m_bind_ip << ":" << zone.second.m_port);
- res = zone.second.m_net_server.init_server(zone.second.m_port, zone.second.m_bind_ip, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
+ MINFO("Binding (IPv4) on " << zone.second.m_bind_ip << ":" << zone.second.m_port);
+ if (!zone.second.m_bind_ipv6_address.empty() && m_use_ipv6)
+ {
+ ipv6_addr = zone.second.m_bind_ipv6_address;
+ ipv6_port = zone.second.m_port_ipv6;
+ MINFO("Binding (IPv6) on " << zone.second.m_bind_ipv6_address << ":" << zone.second.m_port_ipv6);
+ }
+ res = zone.second.m_net_server.init_server(zone.second.m_port, zone.second.m_bind_ip, ipv6_port, ipv6_addr, m_use_ipv6, m_require_ipv4, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
CHECK_AND_ASSERT_MES(res, false, "Failed to bind server");
}
}
m_listening_port = public_zone.m_net_server.get_binded_port();
- MLOG_GREEN(el::Level::Info, "Net service bound to " << public_zone.m_bind_ip << ":" << m_listening_port);
+ MLOG_GREEN(el::Level::Info, "Net service bound (IPv4) to " << public_zone.m_bind_ip << ":" << m_listening_port);
+ if (m_use_ipv6)
+ {
+ m_listening_port_ipv6 = public_zone.m_net_server.get_binded_port_ipv6();
+ MLOG_GREEN(el::Level::Info, "Net service bound (IPv6) to " << public_zone.m_bind_ipv6_address << ":" << m_listening_port_ipv6);
+ }
if(m_external_port)
MDEBUG("External port defined as " << m_external_port);
// add UPnP port mapping
if(m_igd == igd)
- add_upnp_port_mapping(m_listening_port);
+ {
+ add_upnp_port_mapping_v4(m_listening_port);
+ if (m_use_ipv6)
+ {
+ add_upnp_port_mapping_v6(m_listening_port_ipv6);
+ }
+ }
return res;
}
@@ -1997,19 +2031,43 @@ namespace nodetool
if(!node_data.my_port)
return false;
- CHECK_AND_ASSERT_MES(context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), false,
- "Only IPv4 addresses are supported here");
+ bool address_ok = (context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id() || context.m_remote_address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id());
+ CHECK_AND_ASSERT_MES(address_ok, false,
+ "Only IPv4 or IPv6 addresses are supported here");
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();
+ std::string ip;
+ uint32_t ipv4_addr;
+ boost::asio::ip::address_v6 ipv6_addr;
+ bool is_ipv4;
+ if (na.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
+ {
+ ipv4_addr = na.as<const epee::net_utils::ipv4_network_address>().ip();
+ ip = epee::string_tools::get_ip_string_from_int32(ipv4_addr);
+ is_ipv4 = true;
+ }
+ else
+ {
+ ipv6_addr = na.as<const epee::net_utils::ipv6_network_address>().ip();
+ ip = ipv6_addr.to_string();
+ is_ipv4 = false;
+ }
network_zone& zone = m_network_zones.at(na.get_zone());
if(!zone.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{epee::net_utils::ipv4_network_address(actual_ip, node_data.my_port)};
+
+ epee::net_utils::network_address address;
+ if (is_ipv4)
+ {
+ address = epee::net_utils::network_address{epee::net_utils::ipv4_network_address(ipv4_addr, node_data.my_port)};
+ }
+ else
+ {
+ address = epee::net_utils::network_address{epee::net_utils::ipv6_network_address(ipv6_addr, node_data.my_port)};
+ }
peerid_type pr = node_data.peer_id;
bool r = zone.m_net_server.connect_async(ip, port, zone.m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ address, pr, this](
const typename net_server::t_connection_context& ping_context,
@@ -2193,12 +2251,19 @@ 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.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), void(),
- "Only IPv4 addresses are supported here");
+ CHECK_AND_ASSERT_MES((context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id() || context.m_remote_address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id()), void(),
+ "Only IPv4 or IPv6 addresses are supported here");
//called only(!) if success pinged, update local peerlist
peerlist_entry pe;
const epee::net_utils::network_address na = context.m_remote_address;
- pe.adr = epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l);
+ if (context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
+ {
+ pe.adr = epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l);
+ }
+ else
+ {
+ pe.adr = epee::net_utils::ipv6_network_address(na.as<epee::net_utils::ipv6_network_address>().ip(), port_l);
+ }
time_t last_seen;
time(&last_seen);
pe.last_seen = static_cast<int64_t>(last_seen);
@@ -2565,16 +2630,19 @@ namespace nodetool
}
template<class t_payload_net_handler>
- void node_server<t_payload_net_handler>::add_upnp_port_mapping(uint32_t port)
+ void node_server<t_payload_net_handler>::add_upnp_port_mapping_impl(uint32_t port, bool ipv6) // if ipv6 false, do ipv4
{
- MDEBUG("Attempting to add IGD port mapping.");
+ std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)";
+ MDEBUG("Attempting to add IGD port mapping " << ipversion << ".");
int result;
+ const int ipv6_arg = ipv6 ? 1 : 0;
+
#if MINIUPNPC_API_VERSION > 13
// default according to miniupnpc.h
unsigned char ttl = 2;
- UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, 0, ttl, &result);
+ UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, ttl, &result);
#else
- UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, 0, &result);
+ UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, &result);
#endif
UPNPUrls urls;
IGDdatas igdData;
@@ -2611,16 +2679,38 @@ namespace nodetool
}
template<class t_payload_net_handler>
- void node_server<t_payload_net_handler>::delete_upnp_port_mapping(uint32_t port)
+ void node_server<t_payload_net_handler>::add_upnp_port_mapping_v4(uint32_t port)
+ {
+ add_upnp_port_mapping_impl(port, false);
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::add_upnp_port_mapping_v6(uint32_t port)
+ {
+ add_upnp_port_mapping_impl(port, true);
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::add_upnp_port_mapping(uint32_t port, bool ipv4, bool ipv6)
+ {
+ if (ipv4) add_upnp_port_mapping_v4(port);
+ if (ipv6) add_upnp_port_mapping_v6(port);
+ }
+
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::delete_upnp_port_mapping_impl(uint32_t port, bool ipv6)
{
- MDEBUG("Attempting to delete IGD port mapping.");
+ std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)";
+ MDEBUG("Attempting to delete IGD port mapping " << ipversion << ".");
int result;
+ const int ipv6_arg = ipv6 ? 1 : 0;
#if MINIUPNPC_API_VERSION > 13
// default according to miniupnpc.h
unsigned char ttl = 2;
- UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, 0, ttl, &result);
+ UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, ttl, &result);
#else
- UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, 0, &result);
+ UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, &result);
#endif
UPNPUrls urls;
IGDdatas igdData;
@@ -2653,6 +2743,25 @@ namespace nodetool
}
}
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::delete_upnp_port_mapping_v4(uint32_t port)
+ {
+ delete_upnp_port_mapping_impl(port, false);
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::delete_upnp_port_mapping_v6(uint32_t port)
+ {
+ delete_upnp_port_mapping_impl(port, true);
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::delete_upnp_port_mapping(uint32_t port)
+ {
+ delete_upnp_port_mapping_v4(port);
+ delete_upnp_port_mapping_v6(port);
+ }
+
template<typename t_payload_net_handler>
boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>>
node_server<t_payload_net_handler>::socks_connect(network_zone& zone, const epee::net_utils::network_address& remote, epee::net_utils::ssl_support_t ssl_support)
@@ -2671,13 +2780,34 @@ namespace nodetool
boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>>
node_server<t_payload_net_handler>::public_connect(network_zone& zone, epee::net_utils::network_address const& na, epee::net_utils::ssl_support_t ssl_support)
{
- CHECK_AND_ASSERT_MES(na.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), boost::none,
- "Only IPv4 addresses are supported here");
- const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
+ bool is_ipv4 = na.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id();
+ bool is_ipv6 = na.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id();
+ CHECK_AND_ASSERT_MES(is_ipv4 || is_ipv6, boost::none,
+ "Only IPv4 or IPv6 addresses are supported here");
+
+ std::string address;
+ std::string port;
+
+ if (is_ipv4)
+ {
+ const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
+ address = epee::string_tools::get_ip_string_from_int32(ipv4.ip());
+ port = epee::string_tools::num_to_string_fast(ipv4.port());
+ }
+ else if (is_ipv6)
+ {
+ const epee::net_utils::ipv6_network_address &ipv6 = na.as<const epee::net_utils::ipv6_network_address>();
+ address = ipv6.ip().to_string();
+ port = epee::string_tools::num_to_string_fast(ipv6.port());
+ }
+ else
+ {
+ LOG_ERROR("Only IPv4 or IPv6 addresses are supported here");
+ return boost::none;
+ }
typename net_server::t_connection_context con{};
- const bool res = zone.m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
- epee::string_tools::num_to_string_fast(ipv4.port()),
+ const bool res = zone.m_net_server.connect(address, port,
zone.m_config.m_net_config.connection_timeout,
con, "0.0.0.0", ssl_support);
diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h
index 32f30adca..05eb36e65 100644
--- a/src/p2p/net_peerlist_boost_serialization.h
+++ b/src/p2p/net_peerlist_boost_serialization.h
@@ -76,6 +76,9 @@ namespace boost
case epee::net_utils::ipv4_network_address::get_type_id():
do_serialize<epee::net_utils::ipv4_network_address>(is_saving, a, na);
break;
+ case epee::net_utils::ipv6_network_address::get_type_id():
+ do_serialize<epee::net_utils::ipv6_network_address>(is_saving, a, na);
+ break;
case net::tor_address::get_type_id():
do_serialize<net::tor_address>(is_saving, a, na);
break;
@@ -99,6 +102,34 @@ namespace boost
}
template <class Archive, class ver_type>
+ inline void serialize(Archive &a, boost::asio::ip::address_v6& v6, const ver_type ver)
+ {
+ if (typename Archive::is_saving())
+ {
+ auto bytes = v6.to_bytes();
+ for (auto &e: bytes) a & e;
+ }
+ else
+ {
+ boost::asio::ip::address_v6::bytes_type bytes;
+ for (auto &e: bytes) a & e;
+ v6 = boost::asio::ip::address_v6(bytes);
+ }
+ }
+
+ template <class Archive, class ver_type>
+ inline void serialize(Archive &a, epee::net_utils::ipv6_network_address& na, const ver_type ver)
+ {
+ boost::asio::ip::address_v6 ip{na.ip()};
+ uint16_t port{na.port()};
+ a & ip;
+ a & port;
+ if (!typename Archive::is_saving())
+ na = epee::net_utils::ipv6_network_address{ip, port};
+ }
+
+
+ template <class Archive, class ver_type>
inline void save(Archive& a, const net::tor_address& na, const ver_type)
{
const size_t length = std::strlen(na.host_str());