diff --git a/include/opendht/callbacks.h b/include/opendht/callbacks.h
index 683755aad28b6dc1f4a2efa63a402194561afaf9..25a8f4574a45e63badd1f29d1a95a61344592d7e 100644
--- a/include/opendht/callbacks.h
+++ b/include/opendht/callbacks.h
@@ -106,6 +106,12 @@ struct OPENDHT_PUBLIC Config {
 
     /** If set, the dht will load its state from this file on start and save its state in this file on shutdown */
     std::string persist_path {};
+
+    /** If non-0, overrides the default global rate-limit.-1 means no limit. */
+    ssize_t max_req_per_sec {0};
+
+    /** If non-0, overrides the default per-IP address rate-limit. -1 means no limit. */
+    ssize_t max_peer_req_per_sec {0};
 };
 
 /**
diff --git a/include/opendht/network_engine.h b/include/opendht/network_engine.h
index f4b0eeec2ae4b1ce84396f3cf29381182edecfa8..f4b034c300810e4b7c4db5aa5f289642ead4bb6a 100644
--- a/include/opendht/network_engine.h
+++ b/include/opendht/network_engine.h
@@ -48,6 +48,12 @@ struct TransId;
 #define MSG_CONFIRM 0
 #endif
 
+struct NetworkConfig {
+    NetId network {0};
+    ssize_t max_req_per_sec {0};
+    ssize_t max_peer_req_per_sec {0};
+};
+
 class DhtProtocolException : public DhtException {
 public:
     // sent to another peer (http-like).
@@ -207,7 +213,12 @@ public:
     using RequestExpiredCb = std::function<void(const Request&, bool)>;
 
     NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock);
-    NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
+    NetworkEngine(
+            InfoHash& myid,
+            NetworkConfig config,
+            std::unique_ptr<DatagramSocket>&& sock,
+            Logger& log,
+            Scheduler& scheduler,
             decltype(NetworkEngine::onError)&& onError,
             decltype(NetworkEngine::onNewNode)&& onNewNode,
             decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
@@ -425,7 +436,6 @@ private:
     /***************
      *  Constants  *
      ***************/
-    static constexpr size_t MAX_REQUESTS_PER_SEC {1600};
     /* the length of a node info buffer in ipv4 format */
     static const constexpr size_t NODE4_INFO_BUF_LEN {HASH_LEN + sizeof(in_addr) + sizeof(in_port_t)};
     /* the length of a node info buffer in ipv6 format */
@@ -513,17 +523,17 @@ private:
 
     /* DHT info */
     const InfoHash& myid;
-    const NetId network {0};
+    const NetworkConfig config {};
     const std::unique_ptr<DatagramSocket> dht_socket;
     const Logger& DHT_LOG;
 
     NodeCache cache {};
 
     // global limiting should be triggered by at least 8 different IPs
-    using IpLimiter = RateLimiter<MAX_REQUESTS_PER_SEC/8>;
+    using IpLimiter = RateLimiter;
     using IpLimiterMap = std::map<SockAddr, IpLimiter, SockAddr::ipCmp>;
-    IpLimiterMap address_rate_limiter {};
-    RateLimiter<MAX_REQUESTS_PER_SEC> rate_limiter {};
+    IpLimiterMap address_rate_limiter;
+    RateLimiter rate_limiter;
     size_t limiter_maintenance {0};
 
     // requests handling
diff --git a/include/opendht/rate_limiter.h b/include/opendht/rate_limiter.h
index f9626700e5801996c76b94fb2b92fc6f101e8cdc..97abfea2dcb431f99ab5bb534ee3bebd79d0a93f 100644
--- a/include/opendht/rate_limiter.h
+++ b/include/opendht/rate_limiter.h
@@ -23,19 +23,23 @@
 
 namespace dht {
 
-template<size_t Quota, unsigned long Period=1>
 class RateLimiter {
 public:
+    RateLimiter() = delete;
+    RateLimiter(size_t quota) : quota_(quota) {}
+
     /** Clear outdated records and return current quota usage */
     size_t maintain(const time_point& now) {
-        auto limit = now - std::chrono::seconds(Period);
+        auto limit = now - std::chrono::seconds(1);
         while (not records.empty() and records.front() < limit)
             records.pop();
         return records.size();
     }
     /** Return false if quota is reached, insert record and return true otherwise. */
     bool limit(const time_point& now) {
-        if (maintain(now) >= Quota)
+        if (quota_ == (size_t)-1)
+            return true;
+        if (maintain(now) >= quota_)
             return false;
         records.emplace(now);
         return true;
@@ -43,7 +47,11 @@ public:
     bool empty() const {
         return records.empty();
     }
+    size_t quota() const {
+        return quota_;
+    }
 private:
+    const size_t quota_;
     std::queue<time_point> records {};
 };
 
diff --git a/python/opendht.pyx b/python/opendht.pyx
index c0cc8d53e2a0625b847756cae9eb5e6bed5792fe..c888c0fc187fbee013b29c6efc0a80ab1d7fa508 100644
--- a/python/opendht.pyx
+++ b/python/opendht.pyx
@@ -458,6 +458,9 @@ cdef class DhtConfig(object):
         self._config.dht_config.node_config.network = netid
     def setMaintainStorage(self, bool maintain_storage):
         self._config.dht_config.node_config.maintain_storage = maintain_storage
+    def setRateLimit(self, ssize_t max_req_per_sec, ssize_t max_peer_req_per_sec):
+        self._config.dht_config.node_config.max_req_per_sec = max_req_per_sec
+        self._config.dht_config.node_config.max_peer_req_per_sec = max_peer_req_per_sec
 
 cdef class DhtRunner(_WithID):
     cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
diff --git a/python/opendht_cpp.pxd b/python/opendht_cpp.pxd
index 34843eb1fc68862b08dd65ff8dbb13997322ceec..1bc866a0faf480aef893111491a0773d0bf5c568 100644
--- a/python/opendht_cpp.pxd
+++ b/python/opendht_cpp.pxd
@@ -211,6 +211,9 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
         uint32_t network
         bool is_bootstrap
         bool maintain_storage
+        string persist_path
+        size_t max_req_per_sec
+        size_t max_peer_req_per_sec
     cppclass SecureDhtConfig:
         Config node_config
         Identity id
diff --git a/python/tools/pingpong.py b/python/tools/pingpong.py
index 23b5b1454f44b4cf6b21d10859c60680b624c2b1..71bd9f31268e49661c2964630aabb56d84616b12 100755
--- a/python/tools/pingpong.py
+++ b/python/tools/pingpong.py
@@ -19,13 +19,16 @@ import opendht as dht
 import time
 import asyncio
 
+config = dht.DhtConfig()
+config.setRateLimit(-1, -1)
+
 ping_node = dht.DhtRunner()
-ping_node.run()
+ping_node.run(config=config)
 #ping_node.enableLogging()
 #ping_node.bootstrap("bootstrap.ring.cx", "4222")
 
 pong_node = dht.DhtRunner()
-pong_node.run()
+pong_node.run(config=config)
 #pong_node.enableLogging()
 pong_node.ping(ping_node.getBound())
 
@@ -42,7 +45,6 @@ def done(h, ok):
 
 def ping(node, h):
 	global i
-	time.sleep(0.0075)
 	i += 1
 	if i < MAX:
 		node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
diff --git a/src/dht.cpp b/src/dht.cpp
index 1ac6ddd7702a9e4e3cf37a2f1d96c8e4a4e07512..16312e98739fa8c49b39a00fbe1ed2b5cdee21bc 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -39,6 +39,7 @@ constexpr std::chrono::minutes Dht::MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
 constexpr std::chrono::minutes Dht::SEARCH_EXPIRE_TIME;
 constexpr std::chrono::seconds Dht::LISTEN_EXPIRE_TIME;
 constexpr std::chrono::seconds Dht::REANNOUNCE_MARGIN;
+static constexpr size_t MAX_REQUESTS_PER_SEC {1600};
 
 NodeStatus
 Dht::getStatus(sa_family_t af) const
@@ -1688,11 +1689,21 @@ Dht::~Dht()
         s.second->clear();
 }
 
+net::NetworkConfig
+fromDhtConfig(const Config& config)
+{
+    net::NetworkConfig netConf;
+    netConf.network = config.network;
+    netConf.max_req_per_sec = config.max_req_per_sec ? config.max_req_per_sec : MAX_REQUESTS_PER_SEC;
+    netConf.max_peer_req_per_sec = config.max_peer_req_per_sec ? config.max_peer_req_per_sec : MAX_REQUESTS_PER_SEC/8;
+    return netConf;
+}
+
 Dht::Dht() : store(), network_engine(DHT_LOG, scheduler, {}) {}
 
 Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l)
     : DhtInterface(l), myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
-    network_engine(myid, config.network, std::move(sock), DHT_LOG, scheduler,
+    network_engine(myid, fromDhtConfig(config), std::move(sock), DHT_LOG, scheduler,
             std::bind(&Dht::onError, this, _1, _2),
             std::bind(&Dht::onNewNode, this, _1, _2),
             std::bind(&Dht::onReportedAddr, this, _1, _2),
diff --git a/src/network_engine.cpp b/src/network_engine.cpp
index b7736d3d3b8fa2dddb5af86c413549fa245a2e62..3530a12be83274d813cc615acf08029c85216d9d 100644
--- a/src/network_engine.cpp
+++ b/src/network_engine.cpp
@@ -41,7 +41,6 @@ constexpr std::chrono::seconds NetworkEngine::RX_MAX_PACKET_TIME;
 constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
 
 const std::string NetworkEngine::my_v {"RNG1"};
-constexpr size_t NetworkEngine::MAX_REQUESTS_PER_SEC;
 
 static constexpr uint8_t v4prefix[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
 
@@ -100,10 +99,10 @@ RequestAnswer::RequestAnswer(ParsedMessage&& msg)
 {}
 
 NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock)
-    : myid(zeroes), dht_socket(std::move(sock)), DHT_LOG(log), scheduler(scheduler)
+    : myid(zeroes), dht_socket(std::move(sock)), DHT_LOG(log), rate_limiter((size_t)-1), scheduler(scheduler)
 {}
 
-NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
+NetworkEngine::NetworkEngine(InfoHash& myid, NetworkConfig c, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
         decltype(NetworkEngine::onError)&& onError,
         decltype(NetworkEngine::onNewNode)&& onNewNode,
         decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
@@ -122,7 +121,9 @@ NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<Datagram
     onListen(std::move(onListen)),
     onAnnounce(std::move(onAnnounce)),
     onRefresh(std::move(onRefresh)),
-    myid(myid), network(net), dht_socket(std::move(sock)), DHT_LOG(log), scheduler(scheduler)
+    myid(myid), config(c), dht_socket(std::move(sock)), DHT_LOG(log),
+    rate_limiter(config.max_req_per_sec),
+    scheduler(scheduler)
 {}
 
 NetworkEngine::~NetworkEngine() {
@@ -148,7 +149,7 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
 {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_U);
     pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
@@ -165,8 +166,8 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
     pk.pack(KEY_TID); pk.pack(socket_id);
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     // send response
@@ -178,7 +179,7 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
 {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_U);
     pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
@@ -195,8 +196,8 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
     pk.pack(KEY_TID); pk.pack(socket_id);
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     // send response
@@ -300,7 +301,7 @@ NetworkEngine::rateLimit(const SockAddr& addr)
     const auto& now = scheduler.time();
 
     // occasional IP limiter maintenance (a few times every second at max rate)
-    if (limiter_maintenance++ == MAX_REQUESTS_PER_SEC/8) {
+    if (limiter_maintenance++ == config.max_peer_req_per_sec) {
         for (auto it = address_rate_limiter.begin(); it != address_rate_limiter.end();) {
             if (it->second.maintain(now) == 0)
                 address_rate_limiter.erase(it++);
@@ -311,7 +312,11 @@ NetworkEngine::rateLimit(const SockAddr& addr)
     }
 
     // invoke per IP, then global rate limiter
-    return address_rate_limiter[addr].limit(now) and rate_limiter.limit(now);
+    return (config.max_peer_req_per_sec < 0
+            or address_rate_limiter
+                .emplace(addr, config.max_peer_req_per_sec).first->second
+                .limit(now))
+            and rate_limiter.limit(now);
 }
 
 bool
@@ -380,8 +385,8 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
         return;
     }
 
-    if (msg->network != network) {
-        DHT_LOG.d("Received message from other network %u", msg->network);
+    if (msg->network != config.network) {
+        DHT_LOG.d("Received message from other config.network %u", msg->network);
         return;
     }
 
@@ -619,7 +624,7 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o
     TransId tid (node->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     pk.pack(KEY_A); pk.pack_map(1);
      pk.pack(KEY_REQ_ID); pk.pack(myid);
@@ -629,8 +634,8 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o
                               pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y); pk.pack(KEY_Q);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::Ping, tid.toInt(), node,
@@ -656,7 +661,7 @@ void
 NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_R); pk.pack_map(2);
       pk.pack(KEY_REQ_ID); pk.pack(myid);
@@ -667,8 +672,8 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
                                pk.pack_bin_body((const char*)t.data(), t.size());
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     send(addr, buffer.data(), buffer.size());
@@ -680,7 +685,7 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
     TransId tid (n->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     pk.pack(KEY_A); pk.pack_map(2 + (want>0?1:0));
       pk.pack(KEY_REQ_ID);     pk.pack(myid);
@@ -697,8 +702,8 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
                                pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y); pk.pack(KEY_Q);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::FindNode, tid.toInt(), n,
@@ -726,7 +731,7 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query&
     TransId tid (n->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     pk.pack(KEY_A);  pk.pack_map(2 +
                                 (query.where.getFilter() or not query.select.getSelection().empty() ? 1:0) +
@@ -746,8 +751,8 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query&
                                pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y); pk.pack(KEY_Q);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::GetValues, tid.toInt(), n,
@@ -861,9 +866,9 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals
             end = std::min(start + MTU, v.size());
             buffer.clear();
             msgpack::packer<msgpack::sbuffer> pk(&buffer);
-            pk.pack_map(3+(network?1:0));
-            if (network) {
-                pk.pack(KEY_NETID); pk.pack(network);
+            pk.pack_map(3+(config.network?1:0));
+            if (config.network) {
+                pk.pack(KEY_NETID); pk.pack(config.network);
             }
             pk.pack(KEY_Y); pk.pack(KEY_V);
             pk.pack(KEY_TID); pk.pack_bin(tid.size());
@@ -886,7 +891,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
 {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_R);
     pk.pack_map(2 + (not st.empty()?1:0) + (nodes.size()>0?1:0) + (nodes6.size()>0?1:0) + (not token.empty()?1:0));
@@ -927,8 +932,8 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
                       pk.pack_bin_body((const char*)t.data(), t.size());
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     // send response
@@ -1017,7 +1022,7 @@ NetworkEngine::sendListen(Sp<Node> n,
 
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     auto has_query = query.where.getFilter() or not query.select.getSelection().empty();
     pk.pack(KEY_A); pk.pack_map(4 + has_query);
@@ -1035,8 +1040,8 @@ NetworkEngine::sendListen(Sp<Node> n,
                                pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y); pk.pack(KEY_Q);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::Listen, tid.toInt(), n,
@@ -1060,7 +1065,7 @@ void
 NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_R); pk.pack_map(2);
       pk.pack(KEY_REQ_ID); pk.pack(myid);
@@ -1071,8 +1076,8 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
                                pk.pack_bin_body((const char*)t.data(), t.size());
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     send(addr, buffer.data(), buffer.size());
@@ -1090,7 +1095,7 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
     TransId tid (n->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     pk.pack(KEY_A); pk.pack_map((created < scheduler.time() ? 5 : 4));
       pk.pack(KEY_REQ_ID);     pk.pack(myid);
@@ -1107,8 +1112,8 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
                       pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y);   pk.pack(KEY_Q);
     pk.pack(KEY_UA);  pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::AnnounceValue, tid.toInt(), n,
@@ -1148,7 +1153,7 @@ NetworkEngine::sendRefreshValue(Sp<Node> n,
     TransId tid (n->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(5+(network?1:0));
+    pk.pack_map(5+(config.network?1:0));
 
     pk.pack(KEY_A); pk.pack_map(4);
       pk.pack(KEY_REQ_ID);       pk.pack(myid);
@@ -1161,8 +1166,8 @@ NetworkEngine::sendRefreshValue(Sp<Node> n,
                                pk.pack_bin_body((const char*)tid.data(), tid.size());
     pk.pack(KEY_Y); pk.pack(KEY_Q);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     auto req = std::make_shared<Request>(MessageType::Refresh, tid.toInt(), n,
@@ -1193,7 +1198,7 @@ void
 NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid) {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
-    pk.pack_map(4+(network?1:0));
+    pk.pack_map(4+(config.network?1:0));
 
     pk.pack(KEY_R); pk.pack_map(3);
       pk.pack(KEY_REQ_ID);  pk.pack(myid);
@@ -1205,8 +1210,8 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid)
                                pk.pack_bin_body((const char*)t.data(), t.size());
     pk.pack(KEY_Y); pk.pack(KEY_R);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     send(addr, buffer.data(), buffer.size());
@@ -1237,8 +1242,8 @@ NetworkEngine::sendError(const SockAddr& addr,
                                pk.pack_bin_body((const char*)t.data(), t.size());
     pk.pack(KEY_Y); pk.pack(KEY_E);
     pk.pack(KEY_UA); pk.pack(my_v);
-    if (network) {
-        pk.pack(KEY_NETID); pk.pack(network);
+    if (config.network) {
+        pk.pack(KEY_NETID); pk.pack(config.network);
     }
 
     send(addr, buffer.data(), buffer.size());