diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index f11e08d33676b25b36cb05dea314c1fc4fe5f7fe..f66fcde9e7f87488e9864fec22ce1a644e211621 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -72,24 +72,42 @@ SipTransportDescr::toString() const
     return ss.str();
 }
 
-SipTransport::SipTransport(pjsip_transport* t, const std::shared_ptr<TlsListener>& l) :
-transport(t), tlsListener(l)
+void
+SipTransport::deleteTransport(pjsip_transport* t)
+{
+    pjsip_transport_shutdown(t);
+    pjsip_transport_dec_ref(t);
+}
+
+SipTransport::SipTransport(pjsip_transport* t)
+    : transport_(nullptr, deleteTransport)
+{
+    if (not t or pjsip_transport_add_ref(t) != PJ_SUCCESS)
+        throw std::runtime_error("invalid transport");
+
+    // Set pointer here, right after the successful pjsip_transport_add_ref
+    transport_.reset(t);
+
+    RING_DBG("SipTransport@%p {tr=%p {rc=%u}}",
+             this, transport_.get(), pj_atomic_get(transport_->ref_cnt));
+}
+
+SipTransport::SipTransport(pjsip_transport* t,
+                           const std::shared_ptr<TlsListener>& l)
+    : SipTransport(t)
 {
-    pjsip_transport_add_ref(transport);
+    tlsListener_ = l;
 }
 
 SipTransport::~SipTransport()
 {
-    if (transport) {
-        pjsip_transport_shutdown(transport);
-        pjsip_transport_dec_ref(transport); // ??
-        RING_DBG("Destroying transport (refcount: %u)",  pj_atomic_get(transport->ref_cnt));
-        transport = nullptr;
-    }
+    RING_DBG("~SipTransport@%p {tr=%p {rc=%u}}",
+             this, transport_.get(), pj_atomic_get(transport_->ref_cnt));
 }
 
 bool
-SipTransport::isAlive(UNUSED const std::shared_ptr<SipTransport>& t, pjsip_transport_state state)
+SipTransport::isAlive(UNUSED const std::shared_ptr<SipTransport>& t,
+                      pjsip_transport_state state)
 {
     return state != PJSIP_TP_STATE_DISCONNECTED
 #if PJ_VERSION_NUM > (2 << 24 | 1 << 16)
@@ -110,13 +128,14 @@ SipTransport::stateToStr(pjsip_transport_state state)
 }
 
 void
-SipTransport::stateCallback(pjsip_transport_state state, const pjsip_transport_state_info *info)
+SipTransport::stateCallback(pjsip_transport_state state,
+                            const pjsip_transport_state_info *info)
 {
-    std::vector<SipTransportStateCallback> cbs {};
+    std::vector<SipTransportStateCallback> cbs;
     {
         std::lock_guard<std::mutex> lock(stateListenersMutex_);
-        cbs.reserve(stateListeners.size());
-        for (auto& l : stateListeners)
+        cbs.reserve(stateListeners_.size());
+        for (auto& l : stateListeners_)
             cbs.push_back(l.second);
     }
     for (auto& cb : cbs)
@@ -127,16 +146,18 @@ void
 SipTransport::addStateListener(uintptr_t lid, SipTransportStateCallback cb)
 {
     std::lock_guard<std::mutex> lock(stateListenersMutex_);
-    stateListeners[lid] = cb;
+    auto pair = stateListeners_.insert(std::make_pair(lid, cb));
+    if (not pair.second)
+        pair.first->second = cb;
 }
 
 bool
 SipTransport::removeStateListener(uintptr_t lid)
 {
     std::lock_guard<std::mutex> lock(stateListenersMutex_);
-    auto it = stateListeners.find(lid);
-    if (it != stateListeners.end()) {
-        stateListeners.erase(it);
+    auto it = stateListeners_.find(lid);
+    if (it != stateListeners_.end()) {
+        stateListeners_.erase(it);
         return true;
     }
     return false;
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index 9034a76e6704d57e2f596f7b1f9517c9be64f126..803222e1c5221ea2e3908b682bbc0cabd6b3ca6e 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -103,37 +103,41 @@ private:
     pjsip_tpfactory* listener {nullptr};
 };
 
-typedef std::function<void(pjsip_transport_state, const pjsip_transport_state_info*)> SipTransportStateCallback;
+using SipTransportStateCallback = std::function<void(pjsip_transport_state, const pjsip_transport_state_info*)>;
 
 /**
  * SIP transport wraps pjsip_transport.
  */
-struct SipTransport
+class SipTransport
 {
-    SipTransport() {}
-    SipTransport(pjsip_transport*, const std::shared_ptr<TlsListener>& l = {});
+    public:
+        SipTransport(pjsip_transport*);
+        SipTransport(pjsip_transport*, const std::shared_ptr<TlsListener>&);
 
-    virtual ~SipTransport();
+        ~SipTransport();
 
-    static const char* stateToStr(pjsip_transport_state state);
+        static const char* stateToStr(pjsip_transport_state state);
 
-    void stateCallback(pjsip_transport_state state, const pjsip_transport_state_info *info);
+        void stateCallback(pjsip_transport_state state, const pjsip_transport_state_info *info);
 
-    pjsip_transport* get() {
-        return transport;
-    }
+        pjsip_transport* get() {
+            return transport_.get();
+        }
 
-    void addStateListener(uintptr_t lid, SipTransportStateCallback cb);
-    bool removeStateListener(uintptr_t lid);
+        void addStateListener(uintptr_t lid, SipTransportStateCallback cb);
+        bool removeStateListener(uintptr_t lid);
 
-    static bool isAlive(const std::shared_ptr<SipTransport>&, pjsip_transport_state state);
+        static bool isAlive(const std::shared_ptr<SipTransport>&, pjsip_transport_state state);
 
-private:
-    NON_COPYABLE(SipTransport);
-    pjsip_transport* transport {nullptr};
-    std::shared_ptr<TlsListener> tlsListener {};
-    std::map<uintptr_t, SipTransportStateCallback> stateListeners {};
-    std::mutex stateListenersMutex_ {};
+    private:
+        NON_COPYABLE(SipTransport);
+
+        static void deleteTransport(pjsip_transport* t);
+
+        std::unique_ptr<pjsip_transport, decltype(deleteTransport)&> transport_;
+        std::shared_ptr<TlsListener> tlsListener_;
+        std::map<uintptr_t, SipTransportStateCallback> stateListeners_;
+        std::mutex stateListenersMutex_;
 };
 
 class IpAddr;