diff --git a/extras/packaging/gnu-linux/debian/postinst b/extras/packaging/gnu-linux/debian/postinst index 39ad146ec20fa8eca45a8232e9d49edf1dceb9ee..d716e78168e986fd59d41ed1dc69f785233e4283 100644 --- a/extras/packaging/gnu-linux/debian/postinst +++ b/extras/packaging/gnu-linux/debian/postinst @@ -60,6 +60,9 @@ configure_yaml() { echo "# When verbose is set to true, the server logs all incoming connections" echo "verbose: false" echo "" + echo "# If true, will send request to use UPNP if available" + echo "enable_upnp: true" + echo "" echo "# On server, identities are saved in /etc/dhtnet/id/" echo "certificate: \"/etc/dhtnet/id/id-server.crt\"" echo "privateKey: \"/etc/dhtnet/id/id-server.pem\"" diff --git a/tools/common.cpp b/tools/common.cpp index 7b10bfd817cb77cc31e6fd9341fda3e7674d94bb..06b92080254251457559b7fbe4981d5f6d057439 100644 --- a/tools/common.cpp +++ b/tools/common.cpp @@ -53,7 +53,8 @@ connectionManagerConfig(dht::crypto::Identity identity, const std::string& turn_host, const std::string& turn_user, const std::string& turn_pass, - const std::string& turn_realm) + const std::string& turn_realm, + const bool enable_upnp) { // DHT node creation: To make a connection manager at first a DHT node should be created dht::DhtRunner::Config dhtConfig; @@ -93,6 +94,15 @@ connectionManagerConfig(dht::crypto::Identity identity, config->turnServerPwd = turn_pass; config->turnServerRealm = turn_realm; } + + if (enable_upnp) { + // UPnP configuration + auto upnpContext = std::make_shared<dhtnet::upnp::UPnPContext>(ioContext, logger); + auto controller = std::make_shared<dhtnet::upnp::Controller>(upnpContext); + config->upnpEnabled = true; + config->upnpCtrl = controller; + } + return std::move(config); } template<typename T> diff --git a/tools/common.h b/tools/common.h index 97c44c9ace3e396a3429ab58e76f6b369a16cff6..dbd72c3cffe1d1430fda6942d31fa3b9cdcaeb73 100644 --- a/tools/common.h +++ b/tools/common.h @@ -21,6 +21,9 @@ #include "ice_transport_factory.h" #include "certstore.h" +#include "upnp/upnp_control.h" +#include "upnp/upnp_context.h" + namespace dhtnet { #define Log(...) do { fmt::print(__VA_ARGS__); std::fflush(stdout); } while (0) @@ -40,7 +43,8 @@ std::unique_ptr<ConnectionManager::Config> connectionManagerConfig( const std::string& turn_host ="", const std::string& turn_user="", const std::string& turn_pass="", - const std::string& turn_realm=""); + const std::string& turn_realm="", + const bool enable_upnp=true); // add ioContext to readFromStdin template<typename T> diff --git a/tools/dhtnet_crtmgr/main.cpp b/tools/dhtnet_crtmgr/main.cpp index 70e551e811f27c22780e7a66a2f75b9d130e121a..4705e94492be65111a9ea51adf6effcfb14ec6ad 100644 --- a/tools/dhtnet_crtmgr/main.cpp +++ b/tools/dhtnet_crtmgr/main.cpp @@ -122,6 +122,9 @@ int create_yaml_config(std::filesystem::path file, std::filesystem::path certifi yaml_file << "\n# When verbose is set to true, the server logs all incoming connections\n"; yaml_file << "verbose: false\n"; + yaml_file << "\n# If true, will send request to use UPNP if available\n"; + yaml_file << "enable_upnp: true\n"; + yaml_file << "\n# On server, identities are saved in /etc/dhtnet/id/\n"; yaml_file << "# On client, they are generaly saved in ~/.dnc/\n"; yaml_file << "certificate: " << certificate << "\n"; diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp index 18860ae783f64ef456358cd2772de6bea4522342..27cf3b4afee0ea099a6ba85fe3e531abd0b93f6f 100644 --- a/tools/dnc/dnc.cpp +++ b/tools/dnc/dnc.cpp @@ -61,7 +61,8 @@ Dnc::Dnc(dht::crypto::Identity identity, const std::string& turn_realm, const bool anonymous, const bool verbose, - const std::map<std::string, std::vector<int>> authorized_services) + const std::map<std::string, std::vector<int>> authorized_services, + const bool enable_upnp) :logger(verbose ? dht::log::getStdLogger() : nullptr), ioContext(std::make_shared<asio::io_context>()), iceFactory(std::make_shared<IceTransportFactory>(logger)) @@ -91,7 +92,8 @@ Dnc::Dnc(dht::crypto::Identity identity, turn_host, turn_user, turn_pass, - turn_realm); + turn_realm, + enable_upnp); // create a connection manager connectionManager = std::make_unique<ConnectionManager>(std::move(config)); @@ -206,8 +208,9 @@ Dnc::Dnc(dht::crypto::Identity identity, const std::string& turn_user, const std::string& turn_pass, const std::string& turn_realm, - const bool verbose) - : Dnc(identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm, true, verbose, {}) + const bool verbose, + const bool enable_upnp) + : Dnc(identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm, true, verbose, {}, enable_upnp) { std::condition_variable cv; auto name = fmt::format("nc://{:s}:{:d}", remote_host, remote_port); diff --git a/tools/dnc/dnc.h b/tools/dnc/dnc.h index 6e5537dfa63c602423c0e4c4606845284842332d..7d03cc97ca224b621354aa59d772a19a27fe3f9b 100644 --- a/tools/dnc/dnc.h +++ b/tools/dnc/dnc.h @@ -41,7 +41,8 @@ public: const std::string& turn_realm, const bool anonymous, const bool verbose, - const std::map<std::string, std::vector<int>> authorized_services); + const std::map<std::string, std::vector<int>> authorized_services, + const bool enable_upnp); // Build a client Dnc( dht::crypto::Identity identity, @@ -53,7 +54,8 @@ public: const std::string& turn_user, const std::string& turn_pass, const std::string& turn_realm, - const bool verbose); + const bool verbose, + const bool enable_upnp); ~Dnc(); void run(); diff --git a/tools/dnc/dnc.yaml b/tools/dnc/dnc.yaml index f1b06ea28ea825d090bce3092509864c6e7ae5c5..649a9be511b9f4aa2b82d41568046443b85d1cd5 100644 --- a/tools/dnc/dnc.yaml +++ b/tools/dnc/dnc.yaml @@ -16,6 +16,9 @@ turn_realm: "ring" # When verbose is set to true, the server logs all incoming connections verbose: false +# If true, will send request to use UPNP if available +enable_upnp: true + # On server, identities are saved in /etc/dhtnet/id/ # On client, identities are saved in ~/.dnc/ #certificate: "to/your/certificate.crt" diff --git a/tools/dnc/main.cpp b/tools/dnc/main.cpp index 2e4d1bf1a622cf32e304fb4ff2780c128cf6f4ff..f759ff5087c369c6b688d4e04f505b6b572070dc 100644 --- a/tools/dnc/main.cpp +++ b/tools/dnc/main.cpp @@ -51,6 +51,7 @@ struct dhtnc_params bool anonymous_cnx {false}; bool verbose {false}; std::map<std::string, std::vector<int>> authorizedServices {}; + bool enable_upnp {true}; }; static const constexpr struct option long_options[] @@ -201,6 +202,9 @@ parse_args(int argc, char** argv) params.authorizedServices[ip].push_back(port); } } + if (config["enable_upnp"]) { + params.enable_upnp = config["enable_upnp"].as<bool>(); + } } } return params; @@ -272,7 +276,8 @@ main(int argc, char** argv) params.turn_realm, params.anonymous_cnx, params.verbose, - params.authorizedServices); + params.authorizedServices, + params.enable_upnp); } else { dhtnc = std::make_unique<dhtnet::Dnc>(identity, params.bootstrap, @@ -283,7 +288,8 @@ main(int argc, char** argv) params.turn_user, params.turn_pass, params.turn_realm, - params.verbose); + params.verbose, + params.enable_upnp); } dhtnc->run(); return EXIT_SUCCESS;