diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 52d78fe6870ab59ea1658da9290e98c4d4968d14..c68fb27ccd23883917735c033ba5375fdb5c2da3 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -345,6 +345,8 @@ RingAccount::SIPStartCall(const std::shared_ptr<SIPCall>& call, IpAddr target)
         return PJ_FALSE;
     }
 
+    pjsip_dlg_inc_lock(inv->dlg);
+    inv->mod_data[link_->getModId()] = call.get();
     call->inv.reset(inv);
 
 /*
@@ -352,7 +354,6 @@ RingAccount::SIPStartCall(const std::shared_ptr<SIPCall>& call, IpAddr target)
     if (hasServiceRoute())
         pjsip_dlg_set_route_set(dialog, sip_utils::createRouteSet(getServiceRoute(), call->inv->pool));
 */
-    call->inv->mod_data[link_->getModId()] = (void*)call.get();
 
     pjsip_tx_data *tdata;
 
@@ -369,7 +370,6 @@ RingAccount::SIPStartCall(const std::shared_ptr<SIPCall>& call, IpAddr target)
     }
 
     if (pjsip_inv_send_msg(call->inv.get(), tdata) != PJ_SUCCESS) {
-        call->inv.reset();
         RING_ERR("Unable to send invite message for this call");
         return false;
     }
diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp
index 16d9904ac2ae596b3bc61eb91c4ac7a0808a3780..0485aeee15ee8e1a16e3ac742f1aaede46a8ac7c 100644
--- a/src/sip/sipaccount.cpp
+++ b/src/sip/sipaccount.cpp
@@ -375,6 +375,8 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
         return PJ_FALSE;
     }
 
+    pjsip_dlg_inc_lock(inv->dlg);
+    inv->mod_data[link_->getModId()] = call.get();
     call->inv.reset(inv);
 
     updateDialogViaSentBy(dialog);
@@ -387,8 +389,6 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
         return false;
     }
 
-    call->inv->mod_data[link_->getModId()] = call.get();
-
     pjsip_tx_data *tdata;
 
     if (pjsip_inv_invite(call->inv.get(), &tdata) != PJ_SUCCESS) {
@@ -403,7 +403,6 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
     }
 
     if (pjsip_inv_send_msg(call->inv.get(), tdata) != PJ_SUCCESS) {
-        call->inv.reset();
         RING_ERR("Unable to send invite message for this call");
         return false;
     }
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 77ef419fee081e3692d10c3047ef41535153a977..740e0652b762fb3132a93f2e979e527b04880c4f 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -1008,6 +1008,7 @@ SIPCall::InvSessionDeleter::operator ()(pjsip_inv_session* inv) const noexcept
     // prevent this from getting accessed in callbacks
     // RING_WARN: this is not thread-safe!
     inv->mod_data[getSIPVoIPLink()->getModId()] = nullptr;
+    pjsip_dlg_dec_lock(inv->dlg);
 }
 
 } // namespace ring
diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp
index 3774bf0dc2782906be3d53c17c6b43683858455e..686d12994ce0aa63544264188c0cc190693721d6 100644
--- a/src/sip/sipvoiplink.cpp
+++ b/src/sip/sipvoiplink.cpp
@@ -379,6 +379,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
         return PJ_FALSE;
     }
 
+    pjsip_dlg_inc_lock(inv->dlg);
     inv->mod_data[mod_ua_.id] = call.get();
     call->inv.reset(inv);
 
@@ -411,7 +412,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
         // Always answer the new INVITE with 200 if the replaced call is in early or confirmed state.
         if (pjsip_inv_answer(call->inv.get(), PJSIP_SC_OK, NULL, NULL, &response) == PJ_SUCCESS) {
             if (pjsip_inv_send_msg(call->inv.get(), response) != PJ_SUCCESS)
-                call->inv.reset();
+                call->inv.reset(); // FIXME: not sure if we need to continue
         }
 
         // Get the INVITE session associated with the replaced dialog.
@@ -419,8 +420,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
 
         // Disconnect the "replaced" INVITE session.
         if (pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS && tdata) {
-            if (pjsip_inv_send_msg(replaced_inv, tdata))
-                call->inv.reset();
+            pjsip_inv_send_msg(replaced_inv, tdata);
         }
     } else { // Proceed with normal call flow
         if (pjsip_inv_initial_answer(call->inv.get(), rdata, PJSIP_SC_TRYING, NULL, NULL, &tdata) != PJ_SUCCESS) {
@@ -430,7 +430,6 @@ transaction_request_cb(pjsip_rx_data *rdata)
 
         if (pjsip_inv_send_msg(call->inv.get(), tdata) != PJ_SUCCESS) {
             RING_ERR("Could not send msg for invite");
-            call->inv.reset();
             return PJ_FALSE;
         }
 
@@ -447,7 +446,6 @@ transaction_request_cb(pjsip_rx_data *rdata)
 
         if (pjsip_inv_send_msg(call->inv.get(), tdata) != PJ_SUCCESS) {
             RING_ERR("Could not send msg for invite");
-            call->inv.reset();
             return PJ_FALSE;
         }