tools/dnc: cleanup

Change-Id: I18214484a3ce7e8be87a37f2ca97ca114fa12348
diff --git a/tools/common.cpp b/tools/common.cpp
index 35f971c..af6207c 100644
--- a/tools/common.cpp
+++ b/tools/common.cpp
@@ -31,53 +31,44 @@
 namespace dhtnet {
 
 dht::crypto::Identity
-loadIdentity(bool isServer)
+loadIdentity(const std::filesystem::path& path)
 {
-    std::string idDir = std::string(getenv("HOME")) + "/.dhtnetTools";
-    if (isServer){
-
-        if (!std::filesystem::exists(idDir)) {
-            std::filesystem::create_directory(idDir);
-        }
-
-        try {
-            std::filesystem::directory_iterator endIter;
-            for (std::filesystem::directory_iterator iter(idDir); iter != endIter; ++iter) {
-                if (iter->path().extension() == ".pem") {
-                    auto privateKey = std::make_unique<dht::crypto::PrivateKey>(
-                        fileutils::loadFile(std::filesystem::path(iter->path())));
-                    // Generate certificate
-                    auto certificate = std::make_unique<dht::crypto::Certificate>(
-                        dht::crypto::Certificate::generate(*privateKey, "dhtnc"));
-                    // return
-                    return dht::crypto::Identity(std::move(privateKey), std::move(certificate));
-                }
-            }
-        } catch (const std::exception& e) {
-            fmt::print(stderr, "Error loadind key from .dhtnetTools: {}\n", e.what());
-        }
+    if (!std::filesystem::exists(path)) {
+        std::filesystem::create_directory(path);
     }
+    try {
+        for (const auto& path: std::filesystem::directory_iterator(path)) {
+            auto p = path.path();
+            if (p.extension() == ".pem") {
+                auto privateKey = std::make_unique<dht::crypto::PrivateKey>(
+                    fileutils::loadFile(p));
+                auto certificate = std::make_unique<dht::crypto::Certificate>(
+                    fileutils::loadFile(p.replace_extension(".crt")));
+                return dht::crypto::Identity(std::move(privateKey), std::move(certificate));
+            }
+        }
+    } catch (const std::exception& e) {
+        fmt::print(stderr, "Error loadind key from .dhtnetTools: {}\n", e.what());
+    }
+
     auto ca = dht::crypto::generateIdentity("ca");
     auto id = dht::crypto::generateIdentity("dhtnc", ca);
-    idDir += "/id";
-    if (isServer)
-        dht::crypto::saveIdentity(id, idDir);
+    dht::crypto::saveIdentity(id, path / "id");
     return id;
 }
 
 std::unique_ptr<ConnectionManager::Config>
-connectionManagerConfig(dht::crypto::Identity identity,
-                  const std::string& bootstrap_ip_add,
-                  const std::string& bootstrap_port,
+connectionManagerConfig(const std::filesystem::path& path,
+                  dht::crypto::Identity identity,
+                  const std::string& bootstrap,
                   std::shared_ptr<Logger> logger,
                   tls::CertificateStore& certStore,
                   std::shared_ptr<asio::io_context> ioContext,
                   IceTransportFactory& iceFactory)
 {
-    std::filesystem::create_directories(std::string(getenv("HOME")) + "/.dhtnetTools/certstore");
+    std::filesystem::create_directories(path / "certstore");
 
     // DHT node creation: To make a connection manager at first a DHT node should be created
-
     dht::DhtRunner::Config dhtConfig;
     dhtConfig.dht_config.id = identity;
     dhtConfig.threaded = true;
@@ -96,7 +87,7 @@
     };
     auto runner = std::make_shared<dht::DhtRunner>();
     runner->run(dhtConfig, std::move(dhtContext));
-    runner->bootstrap(bootstrap_ip_add, bootstrap_port);
+    runner->bootstrap(bootstrap);
 
     // DHT node creation end:
     // ConnectionManager creation:
@@ -106,7 +97,8 @@
     config->ioContext = ioContext;
     config->certStore = &certStore;
     config->factory = &iceFactory;
-    config->cachePath = std::string(getenv("HOME")) + "/.dhtnetTools";
+    config->cachePath = path;
+    config->logger = logger;
 
     return std::move(config);
 }
diff --git a/tools/common.h b/tools/common.h
index 19b7771..1181ee0 100644
--- a/tools/common.h
+++ b/tools/common.h
@@ -26,12 +26,11 @@
  * certification.
  * @return dht::crypto::Identity
  */
-
-dht::crypto::Identity loadIdentity(bool isServer);
+dht::crypto::Identity loadIdentity(const std::filesystem::path& path);
 // add certstore to the config
-std::unique_ptr<ConnectionManager::Config> connectionManagerConfig(dht::crypto::Identity identity,
-                                                      const std::string& bootstrap_ip_add,
-                                                      const std::string& bootstrap_port,
+std::unique_ptr<ConnectionManager::Config> connectionManagerConfig(const std::filesystem::path& path,
+                                                      dht::crypto::Identity identity,
+                                                      const std::string& bootstrap,
                                                       std::shared_ptr<Logger> logger,
                                                       tls::CertificateStore& certStore,
                                                       std::shared_ptr<asio::io_context> ioContext,
diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp
index 9430cfc..d059f22 100644
--- a/tools/dnc/dnc.cpp
+++ b/tools/dnc/dnc.cpp
@@ -55,11 +55,11 @@
 
 
 // Build a server
-Dnc::Dnc(dht::crypto::Identity identity,
-         const std::string& bootstrap_ip_add,
-         const std::string& bootstrap_port)
+Dnc::Dnc(const std::filesystem::path& path,
+         dht::crypto::Identity identity,
+         const std::string& bootstrap)
     : logger(dht::log::getStdLogger())
-    , certStore(std::string(getenv("HOME")) + "/.dhtnetTools/certstore", logger)
+    , certStore(path / "certstore", logger)
 
 {
     ioContext = std::make_shared<asio::io_context>();
@@ -73,7 +73,7 @@
         }
     });
 
-    auto config = connectionManagerConfig(identity, bootstrap_ip_add, bootstrap_port, logger, certStore, ioContext, iceFactory);
+    auto config = connectionManagerConfig(path, identity, bootstrap, logger, certStore, ioContext, iceFactory);
     // create a connection manager
     connectionManager = std::make_unique<ConnectionManager>(std::move(config));
 
@@ -91,7 +91,7 @@
         [&](const std::shared_ptr<dht::crypto::Certificate>&, const std::string& name) {
             // handle channel request
             if (logger)
-                logger->debug("Channel request received");
+                logger->debug("Channel request received: {}", name);
             return true;
         });
 
@@ -104,6 +104,9 @@
         }
         try {
             auto parsedName = parseName(name);
+            if (logger)
+                logger->debug("Connecting to {}:{}", parsedName.first, parsedName.second);
+
             asio::ip::tcp::resolver resolver(*ioContext);
             asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(parsedName.first,
                                                                                parsedName.second);
@@ -140,6 +143,7 @@
                     } else {
                         if (logger)
                             logger->error("Connection error: {}", error.message());
+                        mtlxSocket->shutdown();
                     }
                 });
 
@@ -150,16 +154,16 @@
     });
 }
 // Build a client
-Dnc::Dnc(dht::crypto::Identity identity,
-         const std::string& bootstrap_ip_add,
-         const std::string& bootstrap_port,
+Dnc::Dnc(const std::filesystem::path& path,
+         dht::crypto::Identity identity,
+         const std::string& bootstrap,
          dht::InfoHash peer_id,
-         int port,
-         const std::string& ip_add)
-    : Dnc(identity, bootstrap_ip_add, bootstrap_port)
+        const std::string& remote_host,
+        int remote_port)
+    : Dnc(path, identity, bootstrap)
 {
     std::condition_variable cv;
-    auto name = fmt::format("nc://{:s}:{:d}", ip_add, port);
+    auto name = fmt::format("nc://{:s}:{:d}", remote_host, remote_port);
     connectionManager->connectDevice(peer_id,
                                      name,
                                      [&](std::shared_ptr<ChannelSocket> socket,
diff --git a/tools/dnc/dnc.h b/tools/dnc/dnc.h
index c3333df..620f940 100644
--- a/tools/dnc/dnc.h
+++ b/tools/dnc/dnc.h
@@ -32,16 +32,16 @@
 {
 public:
     // Build a server
-    Dnc(dht::crypto::Identity identity,
-        const std::string& bootstrap_ip_add,
-        const std::string& bootstrap_port);
+    Dnc(const std::filesystem::path& path,
+        dht::crypto::Identity identity,
+        const std::string& bootstrap);
     // Build a client
-    Dnc(dht::crypto::Identity identity,
-        const std::string& bootstrap_ip_add,
-        const std::string& bootstrap_port,
+    Dnc(const std::filesystem::path& path,
+        dht::crypto::Identity identity,
+        const std::string& bootstrap,
         dht::InfoHash peer_id,
-        int port,
-        const std::string& ip_add);
+        const std::string& remote_host,
+        int remote_port);
     ~Dnc();
     void run();
 
diff --git a/tools/dnc/main.cpp b/tools/dnc/main.cpp
index 5d550b0..929bcc1 100644
--- a/tools/dnc/main.cpp
+++ b/tools/dnc/main.cpp
@@ -22,7 +22,7 @@
 #include <iostream>
 #include <unistd.h>
 #include <getopt.h>
-
+#include <fmt/std.h>
 #include <netinet/in.h>
 
 struct dhtnc_params
@@ -30,21 +30,23 @@
     bool help {false};
     bool version {false};
     bool listen {false};
-    std::string ip_add {};
-    std::string bootstrap_ip {};
-    std::string bootstrap_port {};
-    in_port_t port {};
+    bool verbose {false};
+    std::filesystem::path path {};
+    std::string bootstrap {};
+    std::string remote_host {};
+    in_port_t remote_port {};
     dht::InfoHash peer_id {};
 };
 
 static const constexpr struct option long_options[]
     = {{"help", no_argument, nullptr, 'h'},
-       {"version", no_argument, nullptr, 'v'},
+       {"version", no_argument, nullptr, 'V'},
+       {"verbose", no_argument, nullptr, 'v'},
        {"port", required_argument, nullptr, 'p'},
        {"ip", required_argument, nullptr, 'i'},
        {"listen", no_argument, nullptr, 'l'},
-       {"bootstrap_ip", required_argument, nullptr, 'b'},
-       {"bootstrap_port", required_argument, nullptr, 'P'},
+       {"bootstrap", required_argument, nullptr, 'b'},
+       {"id_path", required_argument, nullptr, 'I'},
        {nullptr, 0, nullptr, 0}};
 
 dhtnc_params
@@ -52,28 +54,32 @@
 {
     dhtnc_params params;
     int opt;
-    while ((opt = getopt_long(argc, argv, "hvp:i:", long_options, nullptr)) != -1) {
+    while ((opt = getopt_long(argc, argv, "hvI:p:i:", long_options, nullptr)) != -1) {
+        fmt::print("opt: {} {}\n", opt, optarg);
         switch (opt) {
         case 'h':
             params.help = true;
             break;
-        case 'v':
+        case 'V':
             params.version = true;
             break;
+        case 'v':
+            params.verbose = true;
+            break;
         case 'p':
-            params.port = std::stoi(optarg);
+            params.remote_port = std::stoi(optarg);
             break;
         case 'i':
-            params.ip_add = optarg;
+            params.remote_host = optarg;
             break;
         case 'l':
             params.listen = true;
             break;
         case 'b':
-            params.bootstrap_ip = optarg;
+            params.bootstrap = optarg;
             break;
-        case 'P':
-            params.bootstrap_port = optarg;
+        case 'I':
+            params.path = optarg;
             break;
         default:
             std::cerr << "Invalid option" << std::endl;
@@ -93,14 +99,14 @@
     }
 
     // default values
-    if (params.port == 0)
-        params.port = 22;
-    if (params.ip_add.empty())
-        params.ip_add = "127.0.0.1";
-    if (params.bootstrap_ip.empty())
-        params.bootstrap_ip = "bootstrap.jami.net";
-    if (params.bootstrap_port.empty())
-        params.bootstrap_port = "4222";
+    if (params.remote_port == 0)
+        params.remote_port = 2000;
+    if (params.remote_host.empty())
+        params.remote_host = "127.0.0.1";
+    if (params.bootstrap.empty())
+        params.bootstrap = "bootstrap.jami.net";
+    if (params.path.empty())
+        params.path = std::filesystem::path(getenv("HOME")) / ".dhtnet";
     return params;
 }
 
@@ -126,26 +132,23 @@
 int
 main(int argc, char** argv)
 {
+    fmt::print("dnc 1.0\n");
     setSipLogLevel();
     auto params = parse_args(argc, argv);
+    auto identity = dhtnet::loadIdentity(params.path);
+    fmt::print("Loaded identity: {} from {}\n", identity.second->getId(), params.path);
 
     std::unique_ptr<dhtnet::Dnc> dhtnc;
     if (params.listen) {
-        auto identity = dhtnet::loadIdentity(true);
         // create dnc instance
-        dhtnc = std::make_unique<dhtnet::Dnc>(identity, params.bootstrap_ip, params.bootstrap_port);
-        fmt::print("DhtNC 1.1\n");
-        fmt::print("Loaded identity: {}\n", identity.second->getId());
+        dhtnc = std::make_unique<dhtnet::Dnc>(params.path, identity, params.bootstrap);
     } else {
-        auto identity = dhtnet::loadIdentity(false);
-        dhtnc = std::make_unique<dhtnet::Dnc>(identity,
-                                              params.bootstrap_ip,
-                                              params.bootstrap_port,
+        dhtnc = std::make_unique<dhtnet::Dnc>(params.path,
+                                              identity,
+                                              params.bootstrap,
                                               params.peer_id,
-                                              params.port,
-                                              params.ip_add);
-        fmt::print("DhtNC 1.0\n");
-        fmt::print("Loaded identity: {}\n", identity.second->getId());
+                                              params.remote_host,
+                                              params.remote_port);
     }
     dhtnc->run();
 }