diff --git a/tools/dhtchat.cpp b/tools/dhtchat.cpp
index 5c7e72c17a2e0400a0201e26b947bafa4a13604a..a07548e8cd0abea213d3dcf804d20354eff5a3f2 100644
--- a/tools/dhtchat.cpp
+++ b/tools/dhtchat.cpp
@@ -62,41 +62,8 @@ main(int argc, char **argv)
 
     DhtRunner dht;
     try {
-        if (not params.id.first) {
-            auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA"));
-            params.id = dht::crypto::generateIdentity("DHT Chat Node", *node_ca);
-            if (not params.save_identity.empty()) {
-                dht::crypto::saveIdentity(*node_ca, params.save_identity + "_ca", params.privkey_pwd);
-                dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd);
-            }
-        }
-
-        dht::DhtRunner::Config config {};
-        config.dht_config.node_config.network = params.network;
-        config.dht_config.node_config.maintain_storage = false;
-        config.dht_config.node_config.persist_path = params.persist_path;
-        config.dht_config.id = params.id;
-        config.threaded = true;
-        config.proxy_server = params.proxyclient;
-        config.push_node_id = "dhtnode";
-        config.push_token = params.devicekey;
-        config.peer_discovery = params.peer_discovery;
-        config.peer_publish = params.peer_discovery;
-        if (params.no_rate_limit) {
-            config.dht_config.node_config.max_req_per_sec = -1;
-            config.dht_config.node_config.max_peer_req_per_sec = -1;
-        }
-
-        dht::DhtRunner::Context context {};
-        if (params.log) {
-            if (params.syslog or (params.daemonize and params.logfile.empty()))
-                context.logger = log::getSyslogLogger("dhtnode");
-            else if (not params.logfile.empty())
-                context.logger = log::getFileLogger(params.logfile);
-            else
-                context.logger = log::getStdLogger();
-        }
-        dht.run(params.port, config, std::move(context));
+        auto dhtConf = getDhtConfig(params);
+        dht.run(params.port, dhtConf.first, std::move(dhtConf.second));
 
         if (not params.bootstrap.first.empty())
             dht.bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp
index 31eca901d74b154d5c5c169e8fce1e3e9e36a343..85a6a0370bf37d7c7dc031753f830f72e684fd12 100644
--- a/tools/dhtnode.cpp
+++ b/tools/dhtnode.cpp
@@ -532,41 +532,8 @@ main(int argc, char **argv)
 
     auto node = std::make_shared<DhtRunner>();
     try {
-        if (not params.id.first and params.generate_identity) {
-            auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA"));
-            params.id = dht::crypto::generateIdentity("DHT Node", *node_ca);
-            if (not params.save_identity.empty()) {
-                dht::crypto::saveIdentity(*node_ca, params.save_identity + "_ca", params.privkey_pwd);
-                dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd);
-            }
-        }
-
-        dht::DhtRunner::Config config {};
-        config.dht_config.node_config.network = params.network;
-        config.dht_config.node_config.maintain_storage = false;
-        config.dht_config.node_config.persist_path = params.persist_path;
-        config.dht_config.id = params.id;
-        config.threaded = true;
-        config.proxy_server = params.proxyclient;
-        config.push_node_id = "dhtnode";
-        config.push_token = params.devicekey;
-        config.peer_discovery = params.peer_discovery;
-        config.peer_publish = params.peer_discovery;
-        if (params.no_rate_limit) {
-            config.dht_config.node_config.max_req_per_sec = -1;
-            config.dht_config.node_config.max_peer_req_per_sec = -1;
-        }
-
-        dht::DhtRunner::Context context {};
-        if (params.log) {
-            if (params.syslog or (params.daemonize and params.logfile.empty()))
-                context.logger = log::getSyslogLogger("dhtnode");
-            else if (not params.logfile.empty())
-                context.logger = log::getFileLogger(params.logfile);
-            else
-                context.logger = log::getStdLogger();
-        }
-        node->run(params.port, config, std::move(context));
+        auto dhtConf = getDhtConfig(params);
+        node->run(params.port, dhtConf.first, std::move(dhtConf.second));
 
         if (not params.bootstrap.first.empty()) {
             std::cout << "Bootstrap: " << params.bootstrap.first << ":" << params.bootstrap.second << std::endl;
@@ -580,13 +547,13 @@ main(int argc, char **argv)
 #ifdef OPENDHT_PROXY_SERVER
             proxies.emplace(params.proxyserverssl, std::unique_ptr<DhtProxyServer>(
                 new DhtProxyServer(params.proxy_id,
-                                   node, params.proxyserverssl, params.pushserver, context.logger)));
+                                   node, params.proxyserverssl, params.pushserver, dhtConf.second.logger)));
         }
         if (params.proxyserver) {
             proxies.emplace(params.proxyserver, std::unique_ptr<DhtProxyServer>(
                 new DhtProxyServer(
                     dht::crypto::Identity{},
-                    node, params.proxyserver, params.pushserver, context.logger)));
+                    node, params.proxyserver, params.pushserver, dhtConf.second.logger)));
 #else
             std::cerr << "DHT proxy server requested but OpenDHT built without proxy server support." << std::endl;
             exit(EXIT_FAILURE);
diff --git a/tools/dhtscanner.cpp b/tools/dhtscanner.cpp
index 93337f851ffc37dc472c28f0f9bcb3ed011fd243..befca4819c3f3da5eecd3dc88dd99c1ee8ca425c 100644
--- a/tools/dhtscanner.cpp
+++ b/tools/dhtscanner.cpp
@@ -85,16 +85,8 @@ main(int argc, char **argv)
 
     DhtRunner dht;
     try {
-        dht.run(params.port, {}, true, params.network);
-
-        if (params.log) {
-            if (params.syslog)
-                log::enableSyslog(dht, "dhtnode");
-            else if (not params.logfile.empty())
-                log::enableFileLogging(dht, params.logfile);
-            else
-                log::enableLogging(dht);
-        }
+        auto dhtConf = getDhtConfig(params);
+        dht.run(params.port, dhtConf.first, std::move(dhtConf.second));
 
         if (not params.bootstrap.first.empty())
             dht.bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
diff --git a/tools/tools_common.h b/tools/tools_common.h
index f368afdabd79d34c0c0bfb4a0f77c88694b0d8f9..ac3aad7f2ddec200736c525a80f1dd2b51e9792b 100644
--- a/tools/tools_common.h
+++ b/tools/tools_common.h
@@ -134,6 +134,46 @@ struct dht_params {
     bool no_rate_limit {false};
 };
 
+std::pair<dht::DhtRunner::Config, dht::DhtRunner::Context>
+getDhtConfig(dht_params& params)
+{
+    if (not params.id.first and params.generate_identity) {
+        auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA"));
+        params.id = dht::crypto::generateIdentity("DHT Node", *node_ca);
+        if (not params.save_identity.empty()) {
+            dht::crypto::saveIdentity(*node_ca, params.save_identity + "_ca", params.privkey_pwd);
+            dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd);
+        }
+    }
+
+    dht::DhtRunner::Config config {};
+    config.dht_config.node_config.network = params.network;
+    config.dht_config.node_config.maintain_storage = false;
+    config.dht_config.node_config.persist_path = params.persist_path;
+    config.dht_config.id = params.id;
+    config.threaded = true;
+    config.proxy_server = params.proxyclient;
+    config.push_node_id = "dhtnode";
+    config.push_token = params.devicekey;
+    config.peer_discovery = params.peer_discovery;
+    config.peer_publish = params.peer_discovery;
+    if (params.no_rate_limit) {
+        config.dht_config.node_config.max_req_per_sec = -1;
+        config.dht_config.node_config.max_peer_req_per_sec = -1;
+    }
+
+    dht::DhtRunner::Context context {};
+    if (params.log) {
+        if (params.syslog or (params.daemonize and params.logfile.empty()))
+            context.logger = dht::log::getSyslogLogger("dhtnode");
+        else if (not params.logfile.empty())
+            context.logger = dht::log::getFileLogger(params.logfile);
+        else
+            context.logger = dht::log::getStdLogger();
+    }
+    return {std::move(config), std::move(context)};
+}
+
 static const constexpr struct option long_options[] = {
     {"help",                    no_argument      , nullptr, 'h'},
     {"port",                    required_argument, nullptr, 'p'},