diff --git a/include/opendht/dhtrunner.h b/include/opendht/dhtrunner.h
index 0478d2c3b109c04416796f55d7536bda0d9f8858..5acf67943fe4a2d7e60caf2da837f430791a20e5 100644
--- a/include/opendht/dhtrunner.h
+++ b/include/opendht/dhtrunner.h
@@ -273,13 +273,13 @@ public:
      * Usefull to restart a node and get things running fast without putting load on the network.
      */
     void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple cb={});
-    void bootstrap(const SockAddr& addr, DoneCallbackSimple cb={});
+    void bootstrap(SockAddr addr, DoneCallbackSimple cb={});
 
     /**
      * Insert known nodes to the routing table, without necessarly ping them.
      * Usefull to restart a node and get things running fast without putting load on the network.
      */
-    void bootstrap(const std::vector<NodeExport>& nodes);
+    void bootstrap(std::vector<NodeExport> nodes);
 
     /**
      * Add host:service to bootstrap nodes, and ping this node.
diff --git a/include/opendht/network_engine.h b/include/opendht/network_engine.h
index cf5332f2f32d9af0c8d62096efe464b42df96b1e..4204060b7b76cc19f9f8269b0d098139dd0f373a 100644
--- a/include/opendht/network_engine.h
+++ b/include/opendht/network_engine.h
@@ -252,12 +252,12 @@ public:
      * @param values      The values to send.
      * @param version     If version = 1, a request will be used to answer to the listener
      */
-    void tellListener(Sp<Node> n, Tid socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
+    void tellListener(const Sp<Node>& n, Tid socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
             std::vector<Sp<Node>>&& nodes, std::vector<Sp<Node>>&& nodes6,
             std::vector<Sp<Value>>&& values, const Query& q, int version);
 
-    void tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
-    void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
+    void tellListenerRefreshed(const Sp<Node>& n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
+    void tellListenerExpired(const Sp<Node>& n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
 
     bool isRunning(sa_family_t af) const;
     inline want_t want () const { return dht_socket->hasIPv4() and dht_socket->hasIPv6() ? (WANT4 | WANT6) : -1; }
@@ -278,7 +278,7 @@ public:
      * @return the request with information concerning its success.
      */
     Sp<Request>
-    sendPing(Sp<Node> n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
+    sendPing(const Sp<Node>& n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
 
     /**
      * Send a "ping" request to a given node.
@@ -309,7 +309,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendFindNode(Sp<Node> n,
+    Sp<Request> sendFindNode(const Sp<Node>& n,
                              const InfoHash& hash,
                              want_t want = -1,
                              RequestCb&& on_done = {},
@@ -328,7 +328,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendGetValues(Sp<Node> n,
+    Sp<Request> sendGetValues(const Sp<Node>& n,
                               const InfoHash& hash,
                               const Query& query,
                               want_t want,
@@ -357,7 +357,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendListen(Sp<Node> n,
+    Sp<Request> sendListen(const Sp<Node>& n,
                            const InfoHash& hash,
                            const Query& query,
                            const Blob& token,
@@ -377,7 +377,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendAnnounceValue(Sp<Node> n,
+    Sp<Request> sendAnnounceValue(const Sp<Node>& n,
                                   const InfoHash& hash,
                                   const Sp<Value>& v,
                                   time_point created,
@@ -397,7 +397,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendRefreshValue(Sp<Node> n,
+    Sp<Request> sendRefreshValue(const Sp<Node>& n,
                                  const InfoHash& hash,
                                  const Value::Id& vid,
                                  const Blob& token,
@@ -416,7 +416,7 @@ public:
      *
      * @return the request with information concerning its success.
      */
-    Sp<Request> sendUpdateValues(Sp<Node> n,
+    Sp<Request> sendUpdateValues(const Sp<Node>& n,
                                  const InfoHash& infohash,
                                  const std::vector<Sp<Value>>& values,
                                  time_point created,
diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp
index e323eb7727bc4febdef9466bfadee822d31a41b8..006be20c7fec24e31ea8e4bd825cb0aa7b264990 100644
--- a/src/dhtrunner.cpp
+++ b/src/dhtrunner.cpp
@@ -817,6 +817,9 @@ void
 DhtRunner::cancelListen(InfoHash h, size_t token)
 {
     std::lock_guard<std::mutex> lck(storage_mtx);
+    if (running != State::Running)
+        return;
+    ongoing_ops++;
 #ifdef OPENDHT_PROXY_CLIENT
     pending_ops.emplace([=](SecureDht&) {
         auto it = listeners_.find(token);
@@ -826,10 +829,12 @@ DhtRunner::cancelListen(InfoHash h, size_t token)
         if (it->second.tokenProxyDht and dht_via_proxy_)
             dht_via_proxy_->cancelListen(h, it->second.tokenProxyDht);
         listeners_.erase(it);
+        opEnded();
     });
 #else
     pending_ops.emplace([=](SecureDht& dht) {
         dht.cancelListen(h, token);
+        opEnded();
     });
 #endif // OPENDHT_PROXY_CLIENT
     cv.notify_all();
@@ -839,8 +844,11 @@ void
 DhtRunner::cancelListen(InfoHash h, std::shared_future<size_t> ftoken)
 {
     std::lock_guard<std::mutex> lck(storage_mtx);
+    if (running != State::Running)
+        return;
+    ongoing_ops++;
 #ifdef OPENDHT_PROXY_CLIENT
-    pending_ops.emplace([=](SecureDht&) {
+    pending_ops.emplace([this, h, ftoken = std::move(ftoken)](SecureDht&) {
         auto it = listeners_.find(ftoken.get());
         if (it == listeners_.end()) return;
         if (it->second.tokenClassicDht)
@@ -848,10 +856,12 @@ DhtRunner::cancelListen(InfoHash h, std::shared_future<size_t> ftoken)
         if (it->second.tokenProxyDht and dht_via_proxy_)
             dht_via_proxy_->cancelListen(h, it->second.tokenProxyDht);
         listeners_.erase(it);
+        opEnded();
     });
 #else
-    pending_ops.emplace([=](SecureDht& dht) {
+    pending_ops.emplace([this, h, ftoken = std::move(ftoken)](SecureDht& dht) {
         dht.cancelListen(h, ftoken.get());
+        opEnded();
     });
 #endif // OPENDHT_PROXY_CLIENT
     cv.notify_all();
@@ -886,7 +896,7 @@ DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb, tim
         return;
     }
     ongoing_ops++;
-    pending_ops.emplace([=, cb = std::move(cb)](SecureDht& dht) mutable {
+    pending_ops.emplace([=, value = std::move(value), cb = std::move(cb)](SecureDht& dht) mutable {
         dht.put(hash, value, bindOpDoneCallback(std::move(cb)), created, permanent);
     });
     cv.notify_all();
@@ -1066,7 +1076,7 @@ DhtRunner::bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple cb)
 }
 
 void
-DhtRunner::bootstrap(const SockAddr& addr, DoneCallbackSimple cb)
+DhtRunner::bootstrap(SockAddr addr, DoneCallbackSimple cb)
 {
     std::unique_lock<std::mutex> lck(storage_mtx);
     if (running != State::Running) {
@@ -1075,7 +1085,7 @@ DhtRunner::bootstrap(const SockAddr& addr, DoneCallbackSimple cb)
         return;
     }
     ongoing_ops++;
-    pending_ops_prio.emplace([addr, cb = bindOpDoneCallback(std::move(cb))](SecureDht& dht) mutable {
+    pending_ops_prio.emplace([addr = std::move(addr), cb = bindOpDoneCallback(std::move(cb))](SecureDht& dht) mutable {
         dht.pingNode(std::move(addr), std::move(cb));
     });
     cv.notify_all();
@@ -1094,12 +1104,12 @@ DhtRunner::bootstrap(const InfoHash& id, const SockAddr& address)
 }
 
 void
-DhtRunner::bootstrap(const std::vector<NodeExport>& nodes)
+DhtRunner::bootstrap(std::vector<NodeExport> nodes)
 {
     std::lock_guard<std::mutex> lck(storage_mtx);
     if (running != State::Running)
         return;
-    pending_ops_prio.emplace([=](SecureDht& dht) {
+    pending_ops_prio.emplace([nodes = std::move(nodes)](SecureDht& dht) {
         for (auto& node : nodes)
             dht.insertNode(node);
     });
diff --git a/src/network_engine.cpp b/src/network_engine.cpp
index fcc6436a36fb6a8788c308a2128730aa26974b4d..c37abaee6dac3ba80e6b2c26821abbbdc09351a3 100644
--- a/src/network_engine.cpp
+++ b/src/network_engine.cpp
@@ -116,7 +116,7 @@ NetworkEngine::~NetworkEngine() {
 }
 
 void
-NetworkEngine::tellListener(Sp<Node> node, Tid socket_id, const InfoHash& hash, want_t want,
+NetworkEngine::tellListener(const Sp<Node>& node, Tid socket_id, const InfoHash& hash, want_t want,
         const Blob& ntoken, std::vector<Sp<Node>>&& nodes,
         std::vector<Sp<Node>>&& nodes6, std::vector<Sp<Value>>&& values,
         const Query& query, int version)
@@ -135,7 +135,7 @@ NetworkEngine::tellListener(Sp<Node> node, Tid socket_id, const InfoHash& hash,
 }
 
 void
-NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&, const Blob& token, const std::vector<Value::Id>& values, int version)
+NetworkEngine::tellListenerRefreshed(const Sp<Node>& n, Tid socket_id, const InfoHash&, const Blob& token, const std::vector<Value::Id>& values, int version)
 {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -186,7 +186,7 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
 }
 
 void
-NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, const Blob& token, const std::vector<Value::Id>& values, int version)
+NetworkEngine::tellListenerExpired(const Sp<Node>& n, Tid socket_id, const InfoHash&, const Blob& token, const std::vector<Value::Id>& values, int version)
 {
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -699,7 +699,7 @@ NetworkEngine::send(const SockAddr& addr, const char *buf, size_t len, bool conf
 }
 
 Sp<Request>
-NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
+NetworkEngine::sendPing(const Sp<Node>& node, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
     Tid tid (node->getNewTid());
     msgpack::sbuffer buffer;
     msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -757,7 +757,7 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
 }
 
 Sp<Request>
-NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
+NetworkEngine::sendFindNode(const Sp<Node>& n, const InfoHash& target, want_t want,
         RequestCb&& on_done, RequestExpiredCb&& on_expired) {
     Tid tid (n->getNewTid());
     msgpack::sbuffer buffer;
@@ -802,7 +802,7 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
 
 
 Sp<Request>
-NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query& query, want_t want,
+NetworkEngine::sendGetValues(const Sp<Node>& n, const InfoHash& info_hash, const Query& query, want_t want,
         RequestCb&& on_done, RequestExpiredCb&& on_expired) {
     Tid tid (n->getNewTid());
     msgpack::sbuffer buffer;
@@ -1073,7 +1073,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
 }
 
 Sp<Request>
-NetworkEngine::sendListen(Sp<Node> n,
+NetworkEngine::sendListen(const Sp<Node>& n,
         const InfoHash& hash,
         const Query& query,
         const Blob& token,
@@ -1142,7 +1142,7 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
 }
 
 Sp<Request>
-NetworkEngine::sendAnnounceValue(Sp<Node> n,
+NetworkEngine::sendAnnounceValue(const Sp<Node>& n,
         const InfoHash& infohash,
         const Sp<Value>& value,
         time_point created,
@@ -1200,7 +1200,7 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
 }
 
 Sp<Request>
-NetworkEngine::sendUpdateValues(Sp<Node> n,
+NetworkEngine::sendUpdateValues(const Sp<Node>& n,
                                 const InfoHash& infohash,
                                 const std::vector<Sp<Value>>& values,
                                 time_point created,
@@ -1246,7 +1246,7 @@ NetworkEngine::sendUpdateValues(Sp<Node> n,
 }
 
 Sp<Request>
-NetworkEngine::sendRefreshValue(Sp<Node> n,
+NetworkEngine::sendRefreshValue(const Sp<Node>& n,
                 const InfoHash& infohash,
                 const Value::Id& vid,
                 const Blob& token,
diff --git a/src/op_cache.h b/src/op_cache.h
index d4e51d1fce037629783f6c2da6b737022a8d3bb7..a32751fea7faf69464079e4faac43548c0012e89 100644
--- a/src/op_cache.h
+++ b/src/op_cache.h
@@ -28,7 +28,7 @@ struct OpCacheValueStorage
     Sp<Value> data {};
     unsigned refCount {1};
     system_clock::time_point updated {system_clock::time_point::min()};
-    explicit OpCacheValueStorage(Sp<Value> val) : data(val) {}
+    explicit OpCacheValueStorage(Sp<Value> val) : data(std::move(val)) {}
 };
 
 class OpValueCache {
diff --git a/src/request.h b/src/request.h
index 734024aa1d9e526a7849c902423ed7182c6ffc90..318d120a05ceadf90c61a1ca0e762319de4b8e28 100644
--- a/src/request.h
+++ b/src/request.h
@@ -74,14 +74,14 @@ struct Request {
             Blob&& msg,
             std::function<void(const Request&, ParsedMessage&&)> on_done,
             std::function<void(const Request&, bool)> on_expired) :
-        node(node), tid(tid), type(type), on_done(on_done), on_expired(on_expired), msg(std::move(msg)) { }
+        node(std::move(node)), tid(tid), type(type), on_done(std::move(on_done)), on_expired(std::move(on_expired)), msg(std::move(msg)) { }
     Request(MessageType type, Tid tid,
             Sp<Node> node,
             Blob&& msg,
             std::function<void(const Request&, ParsedMessage&&)> on_done,
             std::function<bool(const Request&, DhtProtocolException&&)> on_error,
             std::function<void(const Request&, bool)> on_expired) :
-        node(node), tid(tid), type(type), on_done(on_done), on_error(on_error), on_expired(on_expired), msg(std::move(msg)) { }
+        node(std::move(node)), tid(tid), type(type), on_done(std::move(on_done)), on_error(std::move(on_error)), on_expired(std::move(on_expired)), msg(std::move(msg)) { }
 
     Tid getTid() const { return tid; }
     MessageType getType() const { return type; }
diff --git a/src/value_cache.h b/src/value_cache.h
index eb72d1119e0da3fca865abc8a118d675c506efb8..93265eed15d05c94cd888e02620c2ec5e8ea4e61 100644
--- a/src/value_cache.h
+++ b/src/value_cache.h
@@ -53,7 +53,7 @@ public:
     CallbackQueue clear() {
         std::vector<Sp<Value>> expired_values;
         expired_values.reserve(values.size());
-        for (const auto& v : values)
+        for (auto& v : values)
             expired_values.emplace_back(std::move(v.second.data));
         values.clear();
         CallbackQueue ret;