diff --git a/contrib/src/msgpack/rules.mak b/contrib/src/msgpack/rules.mak
new file mode 100644
index 0000000000000000000000000000000000000000..ee0d901a97c6c71a5193988b8bc9dc205d44718f
--- /dev/null
+++ b/contrib/src/msgpack/rules.mak
@@ -0,0 +1,27 @@
+# MSGPACK
+MSGPACK_VERSION := 294aa52c3ad8392ea54331d0ed89299f6a32a798
+MSGPACK_URL := https://github.com/msgpack/msgpack-c/archive/$(MSGPACK_VERSION).tar.gz
+
+PKGS += msgpack
+ifeq ($(call need_pkg,"msgpack >= 1.1"),)
+PKGS_FOUND += msgpack
+endif
+
+MSGPACK_CMAKECONF := -DMSGPACK_CXX11=ON \
+                     -DMSGPACK_BUILD_EXAMPLES=OFF
+
+$(TARBALLS)/msgpack-c-$(MSGPACK_VERSION).tar.gz:
+	$(call download,$(MSGPACK_URL))
+
+.sum-msgpack: msgpack-c-$(MSGPACK_VERSION).tar.gz
+	$(warning $@ not implemented)
+	touch $@
+
+msgpack: msgpack-c-$(MSGPACK_VERSION).tar.gz .sum-msgpack
+	$(UNPACK)
+	$(MOVE)
+
+.msgpack: msgpack toolchain.cmake
+	cd $< && $(HOSTVARS) $(CMAKE) . $(MSGPACK_CMAKECONF)
+	cd $< && $(MAKE) install
+	touch $@
diff --git a/contrib/src/opendht/rules.mak b/contrib/src/opendht/rules.mak
index 04dc067c5f9720d532d01a3afb19b811a42412e4..ddc79b5646f3e2d8121e8a7f9839bb6b3beebceb 100644
--- a/contrib/src/opendht/rules.mak
+++ b/contrib/src/opendht/rules.mak
@@ -1,5 +1,5 @@
 # OPENDHT
-OPENDHT_VERSION := d2be36b615161c2961b89fb4b969cd72aeb2c789
+OPENDHT_VERSION := 27738e5992fdef4ee12df85682df098a7f57f5f9
 OPENDHT_URL := https://github.com/savoirfairelinux/opendht/archive/$(OPENDHT_VERSION).tar.gz
 
 PKGS += opendht
@@ -8,8 +8,11 @@ PKGS_FOUND += opendht
 endif
 
 # Avoid building distro-provided dependencies in case opendht was built manually
+ifneq ($(call need_pkg,"msgpack >= 1.1"),)
+DEPS_opendht += msgpack
+endif
 ifneq ($(call need_pkg,"gnutls >= 3.3.0"),)
-DEPS_opendht = gnutls $(DEPS_gnutls)
+DEPS_opendht += gnutls $(DEPS_gnutls)
 endif
 
 $(TARBALLS)/opendht-$(OPENDHT_VERSION).tar.gz:
diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h
index d85bfc60ee3f47f9d566546a9b8177bec6af6680..5d7d3c69972a68b4c831221d103c5e95f0e79e7b 100644
--- a/src/dring/configurationmanager_interface.h
+++ b/src/dring/configurationmanager_interface.h
@@ -117,7 +117,7 @@ std::map<std::string, std::string> getIp2IpDetails();
 std::vector<std::map<std::string, std::string>> getCredentials(const std::string& accountID);
 void setCredentials(const std::string& accountID, const std::vector<std::map<std::string, std::string>>& details);
 
-std::string getAddrFromInterfaceName(const std::string& interface);
+std::string getAddrFromInterfaceName(const std::string& iface);
 
 std::vector<std::string> getAllIpInterface();
 std::vector<std::string> getAllIpInterfaceByName();
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index f16959104458991f51d763dc00d6fee7060cd565..c2692aac2fbf8d01cdc59dac64e0f23ac0ed5290 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -193,7 +193,7 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
     setCertificateStatus(toUri, tls::TrustStore::Status::ALLOWED);
 
     std::weak_ptr<SIPCall> weak_call = call;
-    manager.addTask([=] {
+    runOnMainThread([=] {
         static std::uniform_int_distribution<dht::Value::Id> udist;
         auto call = weak_call.lock();
 
@@ -212,7 +212,6 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
 
         /* Next step: sent the ICE data to peer through DHT */
         const dht::Value::Id callvid  = udist(shared_this->rand_);
-        const dht::Value::Id replyvid = callvid + 1;
         const auto toH = dht::InfoHash(toUri);
         const auto callkey = dht::InfoHash::get("callto:" + toUri);
 
@@ -220,8 +219,7 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
         shared_this->dht_.putEncrypted(
             callkey, toH,
             dht::Value {
-                dht::IceCandidates(ice->getLocalAttributesAndCandidates()),
-                callvid
+                dht::IceCandidates(callvid, ice->getLocalAttributesAndCandidates())
             },
             [=](bool ok) { // Put complete callback
                 if (!ok) {
@@ -237,7 +235,7 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
         auto listenKey = shared_this->dht_.listen<dht::IceCandidates>(
             callkey,
             [=] (dht::IceCandidates&& msg) {
-                if (msg.id != replyvid)
+                if (msg.id != callvid or msg.from != toH)
                     return true;
                 RING_WARN("ICE request replied from DHT peer %s\n%s", toH.toString().c_str(),
                           std::string(msg.ice_data.cbegin(), msg.ice_data.cend()).c_str());
@@ -254,7 +252,6 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
             std::move(listenKey),
             callkey, toH
         });
-        return false;
     });
 
     return call;
@@ -811,7 +808,7 @@ RingAccount::doRegister_()
                     this_.findCertificate(
                         msg.from,
                         [shared, msg](const std::shared_ptr<dht::crypto::Certificate> cert) mutable {
-                            if (!cert) {
+                            if (!cert or cert->getId() != msg.from) {
                                 RING_WARN("Can't find certificate of %s for incoming call.",
                                           msg.from.toString().c_str());
                                 return;
@@ -820,7 +817,7 @@ RingAccount::doRegister_()
                             tls::CertificateStore::instance().pinCertificate(cert);
 
                             auto& this_ = *shared;
-                            if (!this_.trust_.isTrusted(*cert) or cert->getId() != msg.from) {
+                            if (!this_.trust_.isTrusted(*cert)) {
                                 RING_WARN("Discarding incoming DHT call from untrusted peer %s.",
                                           msg.from.toString().c_str());
                                 return;
@@ -882,30 +879,23 @@ void
 RingAccount::incomingCall(dht::IceCandidates&& msg)
 {
     auto from = msg.from.toString();
-    auto reply_vid = msg.id+1;
-    RING_WARN("ICE incoming from DHT peer %s\n%s", from.c_str(),
+    RING_WARN("ICE incoming (id %lu) from DHT peer %s\n%s", msg.id, from.c_str(),
               std::string(msg.ice_data.cbegin(), msg.ice_data.cend()).c_str());
     auto call = Manager::instance().callFactory.newCall<SIPCall, RingAccount>(*this, Manager::instance().getNewCallID(), Call::CallType::INCOMING);
     auto ice = createIceTransport(("sip:"+call->getCallId()).c_str(), ICE_COMPONENTS, false, getIceOptions());
 
     std::weak_ptr<SIPCall> weak_call = call;
-    auto shared = std::static_pointer_cast<RingAccount>(shared_from_this());
     dht_.putEncrypted(
         callKey_,
         msg.from,
-        dht::Value {
-            dht::IceCandidates(ice->getLocalAttributesAndCandidates()),
-            reply_vid
-        },
-        [weak_call,shared,reply_vid](bool ok) {
-            auto& this_ = *shared.get();
+        { dht::IceCandidates(msg.id, ice->getLocalAttributesAndCandidates()) },
+        [weak_call](bool ok) {
             if (!ok) {
                 RING_WARN("Can't put ICE descriptor reply on DHT");
                 if (auto call = weak_call.lock())
                     call->onFailure();
             } else
                 RING_DBG("Successfully put ICE descriptor reply on DHT");
-            this_.dht_.cancelPut(this_.callKey_, reply_vid);
         }
     );
     ice->start(msg.ice_data);
diff --git a/src/ringdht/sips_transport_ice.cpp b/src/ringdht/sips_transport_ice.cpp
index 95e86d69c2ccc6a430073d5761498d60f5dc00d7..a738b94ffad1574d24b64a113af345e1a7bcaac4 100644
--- a/src/ringdht/sips_transport_ice.cpp
+++ b/src/ringdht/sips_transport_ice.cpp
@@ -393,7 +393,7 @@ SipsIceTransport::certGetInfo(pj_pool_t* pool, pj_ssl_cert_info* ci,
 
     pj_assert(pool && ci && crt_raw);
 
-    dht::crypto::Certificate crt(Blob(crt_raw[0].data, crt_raw[0].data + crt_raw[0].size));
+    dht::crypto::Certificate crt(crt_raw[0].data, crt_raw[0].size);
 
     /* Get issuer */
     gnutls_x509_crt_get_issuer_dn(crt.cert, buf, &bufsize);