diff --git a/tools/common.cpp b/tools/common.cpp index 35f971cc9302154f3a09e874a32973ae41a0f614..af6207ce1aece00acfab17e7a0542306a930f287 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)); - } + 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()); } + } 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 @@ connectionManagerConfig(dht::crypto::Identity identity, }; 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 @@ connectionManagerConfig(dht::crypto::Identity identity, 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 19b7771edf5d949de9a838744d63a293f540d3a5..1181ee0fe01e47fcf23bc178d2c29157ed3b3d94 100644 --- a/tools/common.h +++ b/tools/common.h @@ -26,12 +26,11 @@ using Buffer = std::shared_ptr<std::vector<uint8_t>>; * 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 9430cfca9f49c356f870ce77010f0611d119216d..d059f22d1fdb12f69d4d0f3299b24de94fa5066f 100644 --- a/tools/dnc/dnc.cpp +++ b/tools/dnc/dnc.cpp @@ -55,11 +55,11 @@ Dnc::parseName(const std::string_view name) // 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 @@ Dnc::Dnc(dht::crypto::Identity identity, } }); - 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 @@ Dnc::Dnc(dht::crypto::Identity identity, [&](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 @@ Dnc::Dnc(dht::crypto::Identity identity, } 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 @@ Dnc::Dnc(dht::crypto::Identity identity, } else { if (logger) logger->error("Connection error: {}", error.message()); + mtlxSocket->shutdown(); } }); @@ -150,16 +154,16 @@ Dnc::Dnc(dht::crypto::Identity identity, }); } // 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 c3333df8ac5732b74ffa7257146d4dd2d71a98c3..620f940cb0be53163553cac60ce88524f5ddf80f 100644 --- a/tools/dnc/dnc.h +++ b/tools/dnc/dnc.h @@ -32,16 +32,16 @@ class Dnc { 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 5d550b0a757f2ed95715b2149311f7d645aac269..929bcc196af51f2bdd0f5a1074986fc1efe19e27 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 @@ struct dhtnc_params 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 @@ parse_args(int argc, char** argv) { 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 @@ parse_args(int argc, char** argv) } // 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 @@ setSipLogLevel() 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(); }