diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp
index 8bb3578edb0eab86b99db6e46464e42e24fe304c..f88c889f7d553adff84d4cb77d95de058eed64ad 100644
--- a/daemon/src/iax/iaxaccount.cpp
+++ b/daemon/src/iax/iaxaccount.cpp
@@ -140,7 +140,7 @@ void IAXAccount::registerVoIPLink()
 {
     try {
         link_.init();
-        link_.sendRegister(this);
+        link_.sendRegister(*this);
     } catch (const VoipLinkException &e) {
         ERROR("IAXAccount: %s", e.what());
     }
@@ -150,7 +150,7 @@ void
 IAXAccount::unregisterVoIPLink()
 {
     try {
-        link_.sendUnregister(this);
+        link_.sendUnregister(*this);
         link_.terminate();
     } catch (const VoipLinkException &e) {
         ERROR("IAXAccount: %s", e.what());
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 990de886a21e890b6f3249ce1cf32d5a234b44d5..0b3dad5d11b263225841ba64a082455731decf41 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -155,8 +155,11 @@ IAXVoIPLink::getEvent()
         }
     }
 
-    if (nextRefreshStamp_ and nextRefreshStamp_ < time(NULL))
-        sendRegister(Manager::instance().getIaxAccount(accountID_));
+    if (nextRefreshStamp_ and nextRefreshStamp_ < time(NULL)) {
+        auto account = Manager::instance().getIaxAccount(accountID_);
+        if (account)
+            sendRegister(*account);
+    }
 
     sendAudioFromMic();
 
@@ -175,6 +178,17 @@ IAXVoIPLink::getCallIDs()
     return v;
 }
 
+std::vector<Call*>
+IAXVoIPLink::getCalls(const std::string &account_id) const
+{
+    std::vector<Call*> calls;
+    for (const auto & item : iaxCallMap_) {
+        if (item.second->getAccountId() == account_id)
+            calls.push_back(item.second);
+    }
+    return calls;
+}
+
 void
 IAXVoIPLink::sendAudioFromMic()
 {
@@ -239,21 +253,18 @@ IAXVoIPLink::getIAXCall(const std::string& id)
 }
 
 void
-IAXVoIPLink::sendRegister(Account *a)
+IAXVoIPLink::sendRegister(Account& a)
 {
-    IAXAccount *account = static_cast<IAXAccount*>(a);
-
-    if (!account)
-        throw VoipLinkException("Account is NULL");
-    else if (not account->isEnabled()) {
+    IAXAccount& account = static_cast<IAXAccount&>(a);
+    if (not account.isEnabled()) {
         WARN("Account must be enabled to register, ignoring");
         return;
     }
 
-    if (account->getHostname().empty())
+    if (account.getHostname().empty())
         throw VoipLinkException("Account hostname is empty");
 
-    if (account->getUsername().empty())
+    if (account.getUsername().empty())
         throw VoipLinkException("Account username is empty");
 
     std::lock_guard<std::mutex> lock(mutexIAX_);
@@ -264,14 +275,14 @@ IAXVoIPLink::sendRegister(Account *a)
     regSession_ = iax_session_new();
 
     if (regSession_) {
-        iax_register(regSession_, account->getHostname().data(), account->getUsername().data(), account->getPassword().data(), 120);
+        iax_register(regSession_, account.getHostname().data(), account.getUsername().data(), account.getPassword().data(), 120);
         nextRefreshStamp_ = time(NULL) + 10;
-        account->setRegistrationState(RegistrationState::TRYING);
+        account.setRegistrationState(RegistrationState::TRYING);
     }
 }
 
 void
-IAXVoIPLink::sendUnregister(Account *a)
+IAXVoIPLink::sendUnregister(Account& a)
 {
     if (regSession_) {
         std::lock_guard<std::mutex> lock(mutexIAX_);
@@ -281,7 +292,7 @@ IAXVoIPLink::sendUnregister(Account *a)
 
     nextRefreshStamp_ = 0;
 
-    static_cast<IAXAccount*>(a)->setRegistrationState(RegistrationState::UNREGISTERED);
+    static_cast<IAXAccount&>(a).setRegistrationState(RegistrationState::UNREGISTERED);
 }
 
 Call*
@@ -514,7 +525,7 @@ IAXVoIPLink::getIaxCall(const std::string& id)
     if (iter != iaxCallMap_.end())
         return iter->second;
     else
-        return NULL;
+        return nullptr;
 }
 
 void
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index 4c385ff58c592ff8f98d631edc7fd04c6675629b..d0ecd06bcba29c4d8287e8051248121d52e92b2d 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -101,14 +101,14 @@ class IAXVoIPLink : public VoIPLink {
         /**
          * Send out registration
          */
-        virtual void sendRegister(Account *a);
+        virtual void sendRegister(Account& a);
 
         /**
          * Destroy registration session
          * @todo Send an IAX_COMMAND_REGREL to force unregistration upstream.
          *       Urgency: low
          */
-        virtual void sendUnregister(Account *a);
+        virtual void sendUnregister(Account& a);
 
         /**
          * Create a new outgoing call
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index b3ff73e437dbc4bbc4f4954934b09bd1f04d64ff..55c05cff4787b1763fcdf4194b6c6c39e18fc859 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -915,7 +915,7 @@ void SIPAccount::registerVoIPLink()
         return;
 
     try {
-        link_->sendRegister(this);
+        link_.sendRegister(*this);
     } catch (const VoipLinkException &e) {
         ERROR("%s", e.what());
         setRegistrationState(RegistrationState::ERROR_GENERIC);
@@ -935,7 +935,7 @@ void SIPAccount::unregisterVoIPLink()
         return;
 
     try {
-        link_->sendUnregister(this);
+        link_.sendUnregister(*this);
     } catch (const VoipLinkException &e) {
         ERROR("%s", e.what());
     }
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index fe1cc1c67a19a30bc0e0d75491171e24ffccb128..5806af50ddfab849147e52655f2633d820818eda 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -2,6 +2,7 @@
  *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
  *
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 3667186ad46c579c489644a8b4edbc09606d230a..31f11740029e99c2b15951c90846231b79fd406d 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -37,19 +37,19 @@
 #include "config.h"
 #endif
 
+#include "sdp.h"
+#include "sipcall.h"
 #include "sip_utils.h"
-#include "array_size.h"
-#include "manager.h"
-#include "map_utils.h"
-#include "logger.h"
 
-#include "sip/sdp.h"
-#include "sipcall.h"
-#include "eventthread.h"
+#include "manager.h"
 #if HAVE_SDES
 #include "sdes_negotiator.h"
 #endif
+
+#include "logger.h"
 #include "array_size.h"
+#include "map_utils.h"
+#include "ip_utils.h"
 
 #if HAVE_INSTANT_MESSAGING
 #include "im/instant_messaging.h"
@@ -66,13 +66,13 @@
 #include "client/callmanager.h"
 #include "client/configurationmanager.h"
 
-#include "pjsip/sip_endpoint.h"
-#include "pjsip/sip_uri.h"
-#include "pjnath.h"
+#include <pjsip/sip_endpoint.h>
+#include <pjsip/sip_uri.h>
+#include <pjnath.h>
 
 #ifdef SFL_PRESENCE
-#include "pjsip-simple/presence.h"
-#include "pjsip-simple/publish.h"
+#include <pjsip-simple/presence.h>
+#include <pjsip-simple/publish.h>
 #include "pres_sub_server.h"
 #endif
 
@@ -735,80 +735,84 @@ bool SIPVoIPLink::getEvent()
     return handlingEvents_;
 }
 
-void SIPVoIPLink::sendRegister(Account *a)
+std::vector<Call*>
+SIPVoIPLink::getCalls(const std::string &account_id) const
 {
-    SIPAccount *account = static_cast<SIPAccount*>(a);
+    std::vector<Call*> calls;
+    for (const auto & item : sipCallMap_) {
+        if (item.second->getAccountId() == account_id)
+            calls.push_back(item.second);
+    }
+    return calls;
+}
 
-    if (!account)
-        throw VoipLinkException("Account is NULL");
-    else if (not account->isEnabled()) {
+void
+SIPVoIPLink::sendRegister(Account& a)
+{
+    SIPAccount& account = static_cast<SIPAccount&>(a);
+    if (not account.isEnabled()) {
         WARN("Account must be enabled to register, ignoring");
         return;
     }
 
     try {
-        sipTransport->createSipTransport(*account);
+        sipTransport->createSipTransport(account);
     } catch (const std::runtime_error &e) {
         ERROR("%s", e.what());
         throw VoipLinkException("Could not create or acquire SIP transport");
     }
 
-    account->setRegister(true);
-    account->setRegistrationState(RegistrationState::TRYING);
+    account.setRegister(true);
+    account.setRegistrationState(RegistrationState::TRYING);
 
-    pjsip_regc *regc = account->getRegistrationInfo();
-
-    if (pjsip_regc_create(endpt_, (void *) account, &registration_cb, &regc) != PJ_SUCCESS)
+    pjsip_regc *regc = nullptr;
+    if (pjsip_regc_create(endpt_, (void *) &account, &registration_cb, &regc) != PJ_SUCCESS)
         throw VoipLinkException("UserAgent: Unable to create regc structure.");
 
-    std::string srvUri(account->getServerUri());
-
-    // std::string address, port;
-    // findLocalAddressFromUri(srvUri, account->transport_, address, port);
+    std::string srvUri(account.getServerUri());
     pj_str_t pjSrv = pj_str((char*) srvUri.c_str());
 
     // Generate the FROM header
-    std::string from(account->getFromUri());
+    std::string from(account.getFromUri());
     pj_str_t pjFrom = pj_str((char*) from.c_str());
 
     // Get the received header
-    std::string received(account->getReceivedParameter());
+    std::string received(account.getReceivedParameter());
 
     // Get the contact header
-    const pj_str_t pjContact(account->getContactHeader());
+    const pj_str_t pjContact(account.getContactHeader());
 
-    if (account->transport_) {
-        if (not account->getPublishedSameasLocal() or (not received.empty() and received != account->getPublishedAddress())) {
-            pjsip_host_port *via = account->getViaAddr();
+    if (account.transport_) {
+        if (not account.getPublishedSameasLocal() or (not received.empty() and received != account.getPublishedAddress())) {
+            pjsip_host_port *via = account.getViaAddr();
             DEBUG("Setting VIA sent-by to %.*s:%d", via->host.slen, via->host.ptr, via->port);
 
-            if (pjsip_regc_set_via_sent_by(regc, via, account->transport_) != PJ_SUCCESS)
+            if (pjsip_regc_set_via_sent_by(regc, via, account.transport_) != PJ_SUCCESS)
                 throw VoipLinkException("Unable to set the \"sent-by\" field");
-        } else if (account->isStunEnabled()) {
-            if (pjsip_regc_set_via_sent_by(regc, account->getViaAddr(), account->transport_) != PJ_SUCCESS)
+        } else if (account.isStunEnabled()) {
+            if (pjsip_regc_set_via_sent_by(regc, account.getViaAddr(), account.transport_) != PJ_SUCCESS)
                 throw VoipLinkException("Unable to set the \"sent-by\" field");
         }
     }
 
     //DEBUG("pjsip_regc_init from:%s, srv:%s, contact:%s", from.c_str(), srvUri.c_str(), std::string(pj_strbuf(&pjContact), pj_strlen(&pjContact)).c_str());
-    if (pjsip_regc_init(regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, account->getRegistrationExpire()) != PJ_SUCCESS)
+    if (pjsip_regc_init(regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, account.getRegistrationExpire()) != PJ_SUCCESS)
         throw VoipLinkException("Unable to initialize account registration structure");
 
-    if (account->hasServiceRoute())
-        pjsip_regc_set_route_set(regc, sip_utils::createRouteSet(account->getServiceRoute(), pool_));
+    if (account.hasServiceRoute())
+        pjsip_regc_set_route_set(regc, sip_utils::createRouteSet(account.getServiceRoute(), pool_));
 
-    pjsip_regc_set_credentials(regc, account->getCredentialCount(), account->getCredInfo());
+    pjsip_regc_set_credentials(regc, account.getCredentialCount(), account.getCredInfo());
 
     pjsip_hdr hdr_list;
     pj_list_init(&hdr_list);
-    std::string useragent(account->getUserAgentName());
+    std::string useragent(account.getUserAgentName());
     pj_str_t pJuseragent = pj_str((char*) useragent.c_str());
     const pj_str_t STR_USER_AGENT = CONST_PJ_STR("User-Agent");
 
     pjsip_generic_string_hdr *h = pjsip_generic_string_hdr_create(pool_, &STR_USER_AGENT, &pJuseragent);
     pj_list_push_back(&hdr_list, (pjsip_hdr*) h);
     pjsip_regc_add_headers(regc, &hdr_list);
-
     pjsip_tx_data *tdata;
 
     if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
@@ -830,40 +834,47 @@ void SIPVoIPLink::sendRegister(Account *a)
         throw VoipLinkException("Unable to send account registration request");
     }
 
-    account->setRegistrationInfo(regc);
+    account.setRegistrationInfo(regc);
 }
 
-void SIPVoIPLink::sendUnregister(Account *a)
+void SIPVoIPLink::sendUnregister(Account& a)
 {
-    SIPAccount *account = static_cast<SIPAccount *>(a);
+    SIPAccount& account = static_cast<SIPAccount&>(a);
 
     // This may occurs if account failed to register and is in state INVALID
-    if (!account->isRegistered()) {
-        account->setRegistrationState(RegistrationState::UNREGISTERED);
+    if (!account.isRegistered()) {
+        account.setRegistrationState(RegistrationState::UNREGISTERED);
         return;
     }
 
     // Make sure to cancel any ongoing timers before unregister
-    account->stopKeepAliveTimer();
-
-    pjsip_regc *regc = account->getRegistrationInfo();
+    account.stopKeepAliveTimer();
 
+    pjsip_regc *regc = account.getRegistrationInfo();
     if (!regc)
         throw VoipLinkException("Registration structure is NULL");
 
-    pjsip_tx_data *tdata = NULL;
-
+    pjsip_tx_data *tdata = nullptr;
     if (pjsip_regc_unregister(regc, &tdata) != PJ_SUCCESS)
         throw VoipLinkException("Unable to unregister sip account");
 
     pj_status_t status;
-
     if ((status = pjsip_regc_send(regc, tdata)) != PJ_SUCCESS) {
         sip_strerror(status);
         throw VoipLinkException("Unable to send request to unregister sip account");
     }
 
-    account->setRegister(false);
+    account.setRegister(false);
+
+    if (account.transport_) {
+        if (pj_atomic_get(account.transport_->ref_cnt) > 0)
+            pjsip_transport_dec_ref(account.transport_);
+        pjsip_regc_release_transport(regc); // FIXME: are we sure it is the same transport ?
+        DEBUG("Transport %s has count %d", account.transport_->info, pj_atomic_get(account.transport_->ref_cnt));
+        account.transport_ = nullptr;
+    }
+
+    sipTransport->cleanupTransports();
 }
 
 void SIPVoIPLink::registerKeepAliveTimer(pj_timer_entry &timer, pj_time_val &delay)
@@ -2245,14 +2256,14 @@ void checkNatAddress(pjsip_regc_cbparam &param, SIPAccount &account)
 
 void registration_cb(pjsip_regc_cbparam *param)
 {
-    if (param == NULL) {
-        ERROR("registration callback parameter is NULL");
+    if (!param) {
+        ERROR("registration callback parameter is null");
         return;
     }
 
     SIPAccount *account = static_cast<SIPAccount *>(param->token);
 
-    if (account == NULL) {
+    if (!account) {
         ERROR("account doesn't exist in registration callback");
         return;
     }
@@ -2349,7 +2360,6 @@ void registration_cb(pjsip_regc_cbparam *param)
         account->setRegistrationStateDetailed(details);
         account->setRegistrationExpire(param->expiration);
     }
-
 #undef FAILURE_MESSAGE
 }
 
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index a5ab87401eed052d578110a4c91c1e66025feea4..895df50473d6b6aa80d459ad688a4b0dcb52d16a 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -40,23 +40,24 @@
 #include "config.h"
 #endif
 
-#include <map>
-#include <mutex>
+#include "voiplink.h"
+#include "sipaccount.h"
+#include "siptransport.h"
+
+#include "eventthread.h"
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+#include <pjnath/stun_config.h>
 
-#include "pjsip.h"
-#include "pjlib.h"
-#include "pjsip_ua.h"
-#include "pjlib-util.h"
-#include "pjnath.h"
-#include "pjnath/stun_config.h"
 #ifdef SFL_VIDEO
 #include <queue>
 #endif
-
-#include "sipaccount.h"
-#include "voiplink.h"
-#include "siptransport.h"
-#include "eventthread.h"
+#include <map>
+#include <mutex>
 
 class SIPCall;
 class SIPAccount;
@@ -110,15 +111,18 @@ class SIPVoIPLink : public VoIPLink {
         AccountMap &
         getAccounts() { return sipAccountMap_; }
 
+        virtual std::vector<Call*> getCalls(const std::string &account_id) const;
+
         /**
          * Build and send SIP registration request
          */
-        virtual void sendRegister(Account *a);
+        virtual void sendRegister(Account& a);
 
         /**
          * Build and send SIP unregistration request
+         * @param destroy_transport If true, attempt to destroy the transport.
          */
-        virtual void sendUnregister(Account *a);
+        virtual void sendUnregister(Account& a);
 
         /**
          * Register a new keepalive registration timer to this endpoint
diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h
index 91cc64166318c73702200be7e540ff4987b5ffa7..cf689c7e181246e79a1f6caf89b7fcf136421deb 100644
--- a/daemon/src/voiplink.h
+++ b/daemon/src/voiplink.h
@@ -36,6 +36,7 @@
 
 #include <stdexcept>
 #include <string>
+#include <vector>
 
 class Call;
 class Account;
@@ -65,13 +66,14 @@ class VoIPLink {
          * Virtual method
          * Build and send account registration request
          */
-        virtual void sendRegister(Account *a) = 0;
+        virtual void sendRegister(Account& a) = 0;
 
         /**
          * Virtual method
          * Build and send account unregistration request
+         * Underlying ressources are released after unregistration
          */
-        virtual void sendUnregister(Account *a) = 0;
+        virtual void sendUnregister(Account& a) = 0;
 
         /**
          * Place a new call
@@ -83,6 +85,12 @@ class VoIPLink {
                                       const std::string &toUrl,
                                       const std::string &account_id) = 0;
 
+        /**
+         * Virtual method
+         * Returns calls involving this account.
+         */
+        virtual std::vector<Call*> getCalls(const std::string &account_id) const = 0;
+
         /**
          * Answer the call
          * @param c The call