* UPnP enabled unless an external address is set
If an external_port is configured map the peering port to it, otherwise use 1 to 1 mapping
wrap external_address as ipv6 before inserting into peers
better logging around upnp

* formatting
This commit is contained in:
Russel Waters 2019-10-11 09:58:16 -04:00 committed by GitHub
commit 0c35652f9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 9 deletions

View file

@ -101,7 +101,9 @@ void nano::network::send_keepalive_self (std::shared_ptr<nano::transport::channe
if (external_address.address () != boost::asio::ip::address_v4::any ())
{
message.peers[0] = nano::endpoint (boost::asio::ip::address_v6{}, endpoint ().port ());
message.peers[1] = external_address;
boost::system::error_code ec;
auto external_v6 = boost::asio::ip::address_v6::from_string (external_address.address ().to_string (), ec);
message.peers[1] = nano::endpoint (external_v6, external_address.port ());
}
else
{

View file

@ -677,7 +677,7 @@ void nano::node::start ()
this_l->bootstrap_wallet ();
});
}
if (config.external_address != boost::asio::ip::address_v6{} && config.external_port != 0)
if (config.external_address == boost::asio::ip::address_v6{}.any ())
{
port_mapping.start ();
}

View file

@ -2,6 +2,7 @@
#include <nano/node/portmapping.hpp>
#include <upnpcommands.h>
#include <upnperrors.h>
nano::port_mapping::port_mapping (nano::node & node_a) :
node (node_a),
@ -69,24 +70,25 @@ void nano::port_mapping::refresh_mapping ()
{
nano::lock_guard<std::mutex> lock (mutex);
auto node_port (std::to_string (node.network.endpoint ().port ()));
auto config_port (node.config.external_port != 0 ? std::to_string (node.config.external_port) : node_port);
// We don't map the RPC port because, unless RPC authentication was added, this would almost always be a security risk
for (auto & protocol : protocols)
{
std::array<char, 6> actual_external_port;
actual_external_port.fill (0);
auto add_port_mapping_error (UPNP_AddAnyPortMapping (urls.controlURL, data.first.servicetype, node_port.c_str (), node_port.c_str (), address.to_string ().c_str (), nullptr, protocol.name, nullptr, std::to_string (network_params.portmapping.mapping_timeout).c_str (), actual_external_port.data ()));
auto add_port_mapping_error (UPNP_AddPortMapping (urls.controlURL, data.first.servicetype, config_port.c_str (), node_port.c_str (), address.to_string ().c_str (), nullptr, protocol.name, nullptr, nullptr));
if (check_count % 15 == 0)
{
node.logger.always_log (boost::str (boost::format ("UPnP %1% port mapping response: %2%, actual external port %3%") % protocol.name % add_port_mapping_error % actual_external_port.data ()));
node.logger.always_log (boost::str (boost::format ("UPnP %1% port mapping response: %2%") % protocol.name % add_port_mapping_error));
}
if (add_port_mapping_error == UPNPCOMMAND_SUCCESS)
{
protocol.external_port = static_cast<uint16_t> (std::atoi (actual_external_port.data ()));
node.logger.always_log (boost::str (boost::format ("%1% mapped to %2%") % config_port % node_port));
protocol.external_port = static_cast<uint16_t> (std::atoi (config_port.data ()));
}
else
{
protocol.external_port = 0;
node.logger.always_log (boost::str (boost::format ("UPnP failed %1%: %2%") % add_port_mapping_error % strupnperror (add_port_mapping_error)));
}
}
}
@ -100,20 +102,22 @@ int nano::port_mapping::check_mapping ()
// Long discovery time and fast setup/teardown make this impractical for testing
nano::lock_guard<std::mutex> lock (mutex);
auto node_port (std::to_string (node.network.endpoint ().port ()));
auto config_port (node.config.external_port != 0 ? std::to_string (node.config.external_port) : node_port);
for (auto & protocol : protocols)
{
std::array<char, 64> int_client;
std::array<char, 6> int_port;
std::array<char, 16> remaining_mapping_duration;
remaining_mapping_duration.fill (0);
auto verify_port_mapping_error (UPNP_GetSpecificPortMappingEntry (urls.controlURL, data.first.servicetype, node_port.c_str (), protocol.name, nullptr, int_client.data (), int_port.data (), nullptr, nullptr, remaining_mapping_duration.data ()));
auto verify_port_mapping_error (UPNP_GetSpecificPortMappingEntry (urls.controlURL, data.first.servicetype, config_port.c_str (), protocol.name, nullptr, int_client.data (), int_port.data (), nullptr, nullptr, remaining_mapping_duration.data ()));
if (verify_port_mapping_error == UPNPCOMMAND_SUCCESS)
{
protocol.remaining = result;
protocol.remaining = std::atoi (remaining_mapping_duration.data ());
}
else
{
protocol.remaining = 0;
node.logger.always_log (boost::str (boost::format ("UPNP_GetSpecificPortMappingEntry failed %1%: %2%") % verify_port_mapping_error % strupnperror (verify_port_mapping_error)));
}
result = std::min (result, protocol.remaining);
std::array<char, 64> external_address;
@ -127,6 +131,7 @@ int nano::port_mapping::check_mapping ()
else
{
protocol.external_address = boost::asio::ip::address_v4::any ();
node.logger.always_log (boost::str (boost::format ("UPNP_GetExternalIPAddress failed %1%: %2%") % verify_port_mapping_error % strupnperror (verify_port_mapping_error)));
}
if (check_count % 15 == 0)
{