tools: add upnp

dnc: upnp can be disabled via dnc.yaml only
dsh and dvpn : upnp cannot be disabled

Change-Id: Ic1a53b049eace145ebdc7ac186ab92a4a0df3635
diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp
index 18860ae..27cf3b4 100644
--- a/tools/dnc/dnc.cpp
+++ b/tools/dnc/dnc.cpp
@@ -61,7 +61,8 @@
          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 @@
                                           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 @@
          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 6e5537d..7d03cc9 100644
--- a/tools/dnc/dnc.h
+++ b/tools/dnc/dnc.h
@@ -41,7 +41,8 @@
         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 @@
         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 f1b06ea..649a9be 100644
--- a/tools/dnc/dnc.yaml
+++ b/tools/dnc/dnc.yaml
@@ -16,6 +16,9 @@
 # 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 2e4d1bf..f759ff5 100644
--- a/tools/dnc/main.cpp
+++ b/tools/dnc/main.cpp
@@ -51,6 +51,7 @@
     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 @@
                     params.authorizedServices[ip].push_back(port);
                 }
             }
+            if (config["enable_upnp"]) {
+                params.enable_upnp = config["enable_upnp"].as<bool>();
+            }
         }
     }
     return params;
@@ -272,7 +276,8 @@
                                               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 @@
                                               params.turn_user,
                                               params.turn_pass,
                                               params.turn_realm,
-                                              params.verbose);
+                                              params.verbose,
+                                              params.enable_upnp);
     }
     dhtnc->run();
     return EXIT_SUCCESS;