diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp index b55003d75..a44297c17 100644 --- a/src/p2p/net_node.cpp +++ b/src/p2p/net_node.cpp @@ -135,6 +135,7 @@ namespace nodetool const command_line::arg_descriptor arg_no_sync = {"no-sync", "Don't synchronize the blockchain with other peers", false}; const command_line::arg_descriptor arg_no_igd = {"no-igd", "Disable UPnP port mapping"}; + const command_line::arg_descriptor arg_igd = {"igd", "UPnP port mapping (disabled, enabled, delayed)", "delayed"}; const command_line::arg_descriptor arg_out_peers = {"out-peers", "set max number of out peers", -1}; const command_line::arg_descriptor arg_in_peers = {"in-peers", "set max number of in peers", -1}; const command_line::arg_descriptor arg_tos_flag = {"tos-flag", "set TOS flag", -1}; diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 5d9e19d5d..0d95ceb99 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -205,6 +205,13 @@ namespace nodetool } }; + enum igd_t + { + no_igd, + igd, + delayed_igd, + }; + public: typedef t_payload_net_handler payload_net_handler; @@ -214,7 +221,7 @@ namespace nodetool m_rpc_port(0), m_allow_local_ip(false), m_hide_my_port(false), - m_no_igd(false), + m_igd(no_igd), m_offline(false), is_closing(false), m_network_id() @@ -416,7 +423,7 @@ namespace nodetool uint16_t m_rpc_port; bool m_allow_local_ip; bool m_hide_my_port; - bool m_no_igd; + igd_t m_igd; bool m_offline; std::atomic is_closing; std::unique_ptr mPeersLoggerThread; @@ -491,6 +498,7 @@ namespace nodetool extern const command_line::arg_descriptor arg_no_sync; extern const command_line::arg_descriptor arg_no_igd; + extern const command_line::arg_descriptor arg_igd; extern const command_line::arg_descriptor arg_offline; extern const command_line::arg_descriptor arg_out_peers; extern const command_line::arg_descriptor arg_in_peers; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index ba7326286..98484fe78 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -105,6 +105,7 @@ namespace nodetool command_line::add_arg(desc, arg_p2p_hide_my_port); command_line::add_arg(desc, arg_no_sync); command_line::add_arg(desc, arg_no_igd); + command_line::add_arg(desc, arg_igd); command_line::add_arg(desc, arg_out_peers); command_line::add_arg(desc, arg_in_peers); command_line::add_arg(desc, arg_tos_flag); @@ -344,7 +345,35 @@ namespace nodetool 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); - m_no_igd = command_line::get_arg(vm, arg_no_igd); + const bool has_no_igd = command_line::get_arg(vm, arg_no_igd); + const std::string sigd = command_line::get_arg(vm, arg_igd); + if (sigd == "enabled") + { + if (has_no_igd) + { + MFATAL("Cannot have both --" << arg_no_igd.name << " and --" << arg_igd.name << " enabled"); + return false; + } + m_igd = igd; + } + else if (sigd == "disabled") + { + m_igd = no_igd; + } + else if (sigd == "delayed") + { + if (has_no_igd && !command_line::is_arg_defaulted(vm, arg_igd)) + { + MFATAL("Cannot have both --" << arg_no_igd.name << " and --" << arg_igd.name << " delayed"); + return false; + } + m_igd = has_no_igd ? no_igd : delayed_igd; + } + else + { + MFATAL("Invalid value for --" << arg_igd.name << ", expected enabled, disabled or delayed"); + return false; + } m_offline = command_line::get_arg(vm, cryptonote::arg_offline); if (command_line::has_arg(vm, arg_p2p_add_peer)) @@ -764,7 +793,7 @@ namespace nodetool MDEBUG("External port defined as " << m_external_port); // add UPnP port mapping - if(!m_no_igd) + if(m_igd == igd) add_upnp_port_mapping(m_listening_port); return res; @@ -858,7 +887,7 @@ namespace nodetool for(auto& zone : m_network_zones) zone.second.m_net_server.deinit_server(); // remove UPnP port mapping - if(!m_no_igd) + if(m_igd == igd) delete_upnp_port_mapping(m_listening_port); } return store_config(); @@ -1701,8 +1730,17 @@ namespace nodetool } else { - const el::Level level = el::Level::Warning; - MCLOG_RED(level, "global", "No incoming connections - check firewalls/routers allow port " << get_this_peer_port()); + if (m_igd == delayed_igd) + { + MWARNING("No incoming connections, trying to setup IGD"); + add_upnp_port_mapping(m_listening_port); + m_igd = igd; + } + else + { + const el::Level level = el::Level::Warning; + MCLOG_RED(level, "global", "No incoming connections - check firewalls/routers allow port " << get_this_peer_port()); + } } } return true;