diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index 0b2c8f6bd538b63f5ddb86321d211c76c98def36..b991b6f974dd4fcb08efcdfce0023373ae2b0ac6 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -38,6 +38,7 @@
                         <li>REALM</li>
                         <li>CONFIG_ACCOUNT_MAILBOX: Number to dial to access the voicemail box</li>
                         <li>CONFIG_ACCOUNT_REGISTRATION_EXPIRE: SIP header expiration value (Default: 1600)</li>
+                        <li>BIND_ADDRESS: Custom bind SIP ip address</li>
                         <li>LOCAL_INTERFACE: The network interface (Default: eth0)</li>
                         <li>PUBLISHED_SAMEAS_LOCAL: If False, the published address equals the local address. This is the default.</li>
                         <li>PUBLISHED_ADDRESS: The SIP published address</li>
diff --git a/src/account_schema.h b/src/account_schema.h
index 8641361fd74af55304d0ef1e8e5846079eae097a..f6b71e899b900515eefb96adee8b8ff75c8bd30f 100644
--- a/src/account_schema.h
+++ b/src/account_schema.h
@@ -60,6 +60,7 @@ static const char *const CONFIG_ACCOUNT_AUDIO_PORT_MAX          = "Account.audio
 static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MIN          = "Account.videoPortMin";
 static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MAX          = "Account.videoPortMax";
 
+static const char *const CONFIG_BIND_ADDRESS                    = "Account.bindAddress";
 static const char *const CONFIG_LOCAL_INTERFACE                 = "Account.localInterface";
 static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL          = "Account.publishedSameAsLocal";
 static const char *const CONFIG_LOCAL_PORT                      = "Account.localPort";
diff --git a/src/dring/account_const.h b/src/dring/account_const.h
index 81e18131f5ab8f55e6ced3e7ce7002a3233c08b7..4030f901f8c6b26c2923538dcd167baeb7dc5c68 100644
--- a/src/dring/account_const.h
+++ b/src/dring/account_const.h
@@ -118,6 +118,7 @@ constexpr static const char AUTOANSWER              [] = "Account.autoAnswer";
 constexpr static const char ACTIVE_CALL_LIMIT       [] = "Account.activeCallLimit";
 constexpr static const char HOSTNAME                [] = "Account.hostname";
 constexpr static const char USERNAME                [] = "Account.username";
+constexpr static const char BIND_ADDRESS            [] = "Account.bindAddress";
 constexpr static const char ROUTE                   [] = "Account.routeset";
 constexpr static const char PASSWORD                [] = "Account.password";
 constexpr static const char REALM                   [] = "Account.realm";
diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp
index 34687411c89c65f2497cc2858862052b196784c0..62debcd1df849831e67c310da45cf3c947fb1c27 100644
--- a/src/sip/sipaccount.cpp
+++ b/src/sip/sipaccount.cpp
@@ -404,6 +404,7 @@ void SIPAccount::serialize(YAML::Emitter &out) const
     out << YAML::BeginMap;
     SIPAccountBase::serialize(out);
 
+    out << YAML::Key << Conf::BIND_ADDRESS_KEY << YAML::Value << bindAddress_;
     out << YAML::Key << Conf::PORT_KEY << YAML::Value << localPort_;
 
     out << YAML::Key << USERNAME_KEY << YAML::Value << username_;
@@ -479,6 +480,8 @@ void SIPAccount::unserialize(const YAML::Node &node)
     if (not publishedSameasLocal_)
         usePublishedAddressPortInVIA();
 
+    parseValue(node, Conf::BIND_ADDRESS_KEY, bindAddress_);
+
     int port = sip_utils::DEFAULT_SIP_PORT;
     parseValue(node, Conf::PORT_KEY, port);
     localPort_ = port;
@@ -562,6 +565,7 @@ void SIPAccount::setAccountDetails(const std::map<std::string, std::string> &det
     parseString(details, Conf::CONFIG_TLS_PASSWORD, tlsPassword_);
 
     // SIP specific account settings
+    parseString(details, Conf::CONFIG_BIND_ADDRESS, bindAddress_);
     parseString(details, Conf::CONFIG_ACCOUNT_ROUTESET, serviceRoute_);
 
     if (not publishedSameasLocal_)
@@ -629,6 +633,7 @@ SIPAccount::getAccountDetails() const
     }
     a.emplace(Conf::CONFIG_ACCOUNT_PASSWORD,                std::move(password));
 
+    a.emplace(Conf::CONFIG_BIND_ADDRESS,                    bindAddress_);
     a.emplace(Conf::CONFIG_LOCAL_PORT,                      std::to_string(localPort_));
     a.emplace(Conf::CONFIG_ACCOUNT_ROUTESET,                serviceRoute_);
     a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE,     std::to_string(registrationExpire_));
@@ -771,18 +776,22 @@ void SIPAccount::doRegister1_()
 
 void SIPAccount::doRegister2_()
 {
-    bool ipv6 = false;
-    if (isIP2IP()) {
-        JAMI_DBG("doRegister isIP2IP.");
-        ipv6 = ip_utils::getInterfaceAddr(interface_).isIpv6();
-    } else if (!hostIp_) {
+    if (not isIP2IP() and not hostIp_) {
         setRegistrationState(RegistrationState::ERROR_GENERIC, PJSIP_SC_NOT_FOUND);
         JAMI_ERR("Hostname not resolved.");
         return;
-    } else {
-        ipv6 = hostIp_.isIpv6();
     }
 
+    IpAddr bindAddress = createBindingAddress();
+    if (not bindAddress) {
+        setRegistrationState(RegistrationState::ERROR_GENERIC, PJSIP_SC_NOT_FOUND);
+        JAMI_ERR("Can't compute address to bind.");
+        return;
+    }
+
+    bool ipv6 = bindAddress.isIpv6();
+    transportType_ = tlsEnable_ ? (ipv6 ? PJSIP_TRANSPORT_TLS6 : PJSIP_TRANSPORT_TLS) : (ipv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP);
+
     // Init TLS settings if the user wants to use TLS
     if (tlsEnable_) {
         JAMI_DBG("TLS is enabled for account %s", accountID_.c_str());
@@ -790,14 +799,10 @@ void SIPAccount::doRegister2_()
         // Dropping current calls already using the transport is currently required
         // with TLS.
         freeAccount();
-
-        transportType_ = ipv6 ? PJSIP_TRANSPORT_TLS6 : PJSIP_TRANSPORT_TLS;
         initTlsConfiguration();
 
         if (!tlsListener_) {
-            tlsListener_ = link_->sipTransportBroker->getTlsListener(
-                SipTransportDescr {getTransportType(), getTlsListenerPort(), getLocalInterface()},
-                getTlsSetting());
+            tlsListener_ = link_->sipTransportBroker->getTlsListener(bindAddress, getTlsSetting());
             if (!tlsListener_) {
                 setRegistrationState(RegistrationState::ERROR_GENERIC);
                 JAMI_ERR("Error creating TLS listener.");
@@ -806,7 +811,6 @@ void SIPAccount::doRegister2_()
         }
     } else {
         tlsListener_.reset();
-        transportType_ = ipv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP;
     }
 
     // Init STUN settings for this account if the user selected it
@@ -819,10 +823,9 @@ void SIPAccount::doRegister2_()
     // no registration should be performed
     if (isIP2IP()) {
         // If we use Tls for IP2IP, transports will be created on connection.
-        if (!tlsEnable_)
-            setTransport(link_->sipTransportBroker->getUdpTransport(
-                SipTransportDescr { getTransportType(), getLocalPort(), getLocalInterface() }
-            ));
+        if (!tlsEnable_){
+            setTransport(link_->sipTransportBroker->getUdpTransport(bindAddress));
+        }
         setRegistrationState(RegistrationState::REGISTERED);
         return;
     }
@@ -833,9 +836,7 @@ void SIPAccount::doRegister2_()
         if (isTlsEnabled()) {
             setTransport(link_->sipTransportBroker->getTlsTransport(tlsListener_, hostIp_, tlsServerName_.empty() ? hostname_ : tlsServerName_));
         } else {
-            setTransport(link_->sipTransportBroker->getUdpTransport(
-                SipTransportDescr { getTransportType(), getLocalPort(), getLocalInterface() }
-            ));
+            setTransport(link_->sipTransportBroker->getUdpTransport(bindAddress));
         }
         if (!transport_)
             throw VoipLinkException("Can't create transport");
@@ -2203,4 +2204,22 @@ SIPAccount::getUserUri() const
     return getFromUri();
 }
 
+IpAddr
+SIPAccount::createBindingAddress()
+{
+    auto family = hostIp_ ? hostIp_.getFamily() : PJ_AF_INET;
+
+    IpAddr ret = bindAddress_.empty()
+        ? (interface_ ==  ip_utils::DEFAULT_INTERFACE
+            ? ip_utils::getAnyHostAddr(family)
+            : ip_utils::getInterfaceAddr(getLocalInterface(), family))
+        : IpAddr(bindAddress_, family);
+
+    if (ret.getPort() == 0) {
+        ret.setPort(tlsEnable_ ? getTlsListenerPort() : getLocalPort());
+    }
+
+    return ret;
+}
+
 } // namespace jami
diff --git a/src/sip/sipaccount.h b/src/sip/sipaccount.h
index d798599e8ffb8e45e3d0ce6b3a3d9c5086898fb5..4375f59eec88a69e4a176dd1e11c691f999be6b9 100644
--- a/src/sip/sipaccount.h
+++ b/src/sip/sipaccount.h
@@ -293,6 +293,24 @@ class SIPAccount : public SIPAccountBase {
             localPort_ = port;
         }
 
+        /**
+         * Get the bind ip address on which the account should use, or is
+         * actually using.
+         * Note: if it is NULL, this address should not be used
+         * @return std::string The bind ip address used for that account
+         */
+        std::string getBindAddress() const {
+            return bindAddress_;
+        }
+
+        /**
+         * Set the new bind ip address on which this account is bind on.
+         * @pram address The bind ip address used by this account.
+         */
+        void setBindAddress(const std::string &address) {
+            bindAddress_ = address;
+        }
+
         /**
          * @return pjsip_tls_setting structure, filled from the configuration
          * file, that can be used directly by PJSIP to initialize
@@ -509,6 +527,12 @@ class SIPAccount : public SIPAccountBase {
 
         std::string getUserUri() const override;
 
+         /**
+         * Create the Ip address that the transport uses
+         * @return IpAddr created
+         */
+        IpAddr createBindingAddress();
+
     private:
         void doRegister1_();
         void doRegister2_();
@@ -680,6 +704,11 @@ class SIPAccount : public SIPAccountBase {
          */
         pj_uint16_t localPort_ {sip_utils::DEFAULT_SIP_PORT};
 
+        /**
+         * Potential ip addresss on which this account is bound
+         */
+        std::string bindAddress_;
+
         /**
          * The TLS listener port
          */
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index df6a09e16bb45d358ad1a2de763eb5ed7069e7ae..df3c943f08e20410d98828260e2095dbb0460033 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -54,6 +54,7 @@ namespace jami {
 
 namespace Conf {
     // SIP specific configuration keys
+    const char *const BIND_ADDRESS_KEY = "bindAddress";
     const char *const INTERFACE_KEY = "interface";
     const char *const PORT_KEY = "port";
     const char *const PUBLISH_ADDR_KEY = "publishAddr";
diff --git a/src/sip/siptransport.cpp b/src/sip/siptransport.cpp
index 049fab02e8e3448361859a0a35094d3a2c126f0e..23707ec4dd69d0342cb9a4fa91abc0b6447f584d 100644
--- a/src/sip/siptransport.cpp
+++ b/src/sip/siptransport.cpp
@@ -55,14 +55,6 @@ constexpr const char* TRANSPORT_STATE_STR[] = {
 };
 constexpr const size_t TRANSPORT_STATE_SZ = arraySize(TRANSPORT_STATE_STR);
 
-std::string
-SipTransportDescr::toString() const
-{
-    std::stringstream ss;
-    ss << "{" << pjsip_transport_get_type_desc(type) << " on " << interface << ":" << listenerPort  << "}";
-    return ss.str();
-}
-
 void
 SipTransport::deleteTransport(pjsip_transport* t)
 {
@@ -253,7 +245,7 @@ SipTransportBroker::transportStateChanged(pjsip_transport* tp,
             if (type == PJSIP_TRANSPORT_UDP or type == PJSIP_TRANSPORT_UDP6) {
                 const auto updKey = std::find_if(
                     udpTransports_.cbegin(), udpTransports_.cend(),
-                    [tp](const std::pair<SipTransportDescr, pjsip_transport*>& pair) {
+                    [tp](const std::pair<IpAddr, pjsip_transport*>& pair) {
                         return pair.second == tp;
                     });
                 if (updKey != udpTransports_.cend())
@@ -303,79 +295,66 @@ SipTransportBroker::shutdown()
 }
 
 std::shared_ptr<SipTransport>
-SipTransportBroker::getUdpTransport(const SipTransportDescr& descr)
+SipTransportBroker::getUdpTransport(const IpAddr& ipAddress)
 {
     std::lock_guard<std::mutex> lock(transportMapMutex_);
-    auto itp = udpTransports_.find(descr);
+    auto itp = udpTransports_.find(ipAddress);
     if (itp != udpTransports_.end()) {
         auto it = transports_.find(itp->second);
         if (it != transports_.end()) {
             if (auto spt = it->second.lock()) {
-                JAMI_DBG("Reusing transport %s", descr.toString().c_str());
+                JAMI_DBG("Reusing transport %s", ipAddress.toString().c_str());
                 return spt;
             }
             else {
                 // Transport still exists but have not been destroyed yet.
-                JAMI_WARN("Recycling transport %s", descr.toString().c_str());
+                JAMI_WARN("Recycling transport %s", ipAddress.toString().c_str());
                 auto ret = std::make_shared<SipTransport>(itp->second);
                 it->second = ret;
                 return ret;
             }
         } else {
-            JAMI_WARN("Cleaning up UDP transport %s", descr.toString().c_str());
+            JAMI_WARN("Cleaning up UDP transport %s", ipAddress.toString().c_str());
             udpTransports_.erase(itp);
         }
     }
-    auto ret = createUdpTransport(descr);
+    auto ret = createUdpTransport(ipAddress);
     if (ret) {
-        udpTransports_[descr] = ret->get();
+        udpTransports_[ipAddress] = ret->get();
         transports_[ret->get()] = ret;
     }
     return ret;
 }
 
 std::shared_ptr<SipTransport>
-SipTransportBroker::createUdpTransport(const SipTransportDescr& d)
+SipTransportBroker::createUdpTransport(const IpAddr& ipAddress)
 {
-    RETURN_IF_FAIL(d.listenerPort != 0, nullptr, "Could not determine port for this transport");
-    auto family = pjsip_transport_type_get_af(d.type);
-
-    IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ?
-        ip_utils::getAnyHostAddr(family) :
-        ip_utils::getInterfaceAddr(d.interface, family);
-    listeningAddress.setPort(d.listenerPort);
-    RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport");
+    RETURN_IF_FAIL(ipAddress.getPort() != 0, nullptr, "Could not determine port for this transport");
+    RETURN_IF_FAIL(ipAddress, nullptr, "Could not determine IP address for this transport");
 
     pjsip_udp_transport_cfg pj_cfg;
-    pjsip_udp_transport_cfg_default(&pj_cfg, family);
-    pj_cfg.bind_addr = listeningAddress;
+    pjsip_udp_transport_cfg_default(&pj_cfg, ipAddress.getFamily());
+    pj_cfg.bind_addr = ipAddress;
     pjsip_transport *transport = nullptr;
     if (pj_status_t status = pjsip_udp_transport_start2(endpt_, &pj_cfg, &transport)) {
         JAMI_ERR("pjsip_udp_transport_start2 failed with error %d: %s", status,
                  sip_utils::sip_strerror(status).c_str());
         JAMI_ERR("UDP IPv%s Transport did not start on %s",
-            listeningAddress.isIpv4() ? "4" : "6",
-            listeningAddress.toString(true).c_str());
+            ipAddress.isIpv4() ? "4" : "6",
+            ipAddress.toString(true).c_str());
         return nullptr;
     }
 
-    JAMI_DBG("Created UDP transport on %s : %s", d.interface.c_str(), listeningAddress.toString(true).c_str());
+    JAMI_DBG("Created UDP transport on address %s", ipAddress.toString(true).c_str());
     return std::make_shared<SipTransport>(transport);
 }
 
 std::shared_ptr<TlsListener>
-SipTransportBroker::getTlsListener(const SipTransportDescr& d, const pjsip_tls_setting* settings)
+SipTransportBroker::getTlsListener(const IpAddr& ipAddress, const pjsip_tls_setting* settings)
 {
     RETURN_IF_FAIL(settings, nullptr, "TLS settings not specified");
-    auto family = pjsip_transport_type_get_af(d.type);
-
-    IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ?
-        ip_utils::getAnyHostAddr(family) :
-        ip_utils::getInterfaceAddr(d.interface, family);
-    listeningAddress.setPort(d.listenerPort);
-
-    RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport");
-    JAMI_DBG("Creating TLS listener %s on %s...", d.toString().c_str(), listeningAddress.toString(true).c_str());
+    RETURN_IF_FAIL(ipAddress, nullptr, "Could not determine IP address for this transport");
+    JAMI_DBG("Creating TLS listener on %s...", ipAddress.toString(true).c_str());
 #if 0
     JAMI_DBG(" ca_list_file : %s", settings->ca_list_file.ptr);
     JAMI_DBG(" cert_file    : %s", settings->cert_file.ptr);
@@ -385,7 +364,7 @@ SipTransportBroker::getTlsListener(const SipTransportDescr& d, const pjsip_tls_s
 #endif
 
     pjsip_tpfactory *listener = nullptr;
-    const pj_status_t status = pjsip_tls_transport_start2(endpt_, settings, listeningAddress.pjPtr(), nullptr, 1, &listener);
+    const pj_status_t status = pjsip_tls_transport_start2(endpt_, settings, ipAddress.pjPtr(), nullptr, 1, &listener);
     if (status != PJ_SUCCESS) {
         JAMI_ERR("TLS listener did not start: %s", sip_utils::sip_strerror(status).c_str());
         return nullptr;
@@ -406,6 +385,7 @@ SipTransportBroker::getTlsTransport(const std::shared_ptr<TlsListener>& l, const
     pjsip_tpselector sel;
     sel.type = PJSIP_TPSELECTOR_LISTENER;
     sel.u.listener = l->get();
+    sel.disable_connection_reuse = PJ_FALSE;
 
     pjsip_tx_data tx_data;
     tx_data.dest_info.name = pj_str_t{(char*)remote_name.data(), (pj_ssize_t)remote_name.size()};
diff --git a/src/sip/siptransport.h b/src/sip/siptransport.h
index 3be21163eda13666e59e4d775f541056a9952b42..8f4f3fed629443a4123cb943c6ff6e538a0d1286 100644
--- a/src/sip/siptransport.h
+++ b/src/sip/siptransport.h
@@ -50,37 +50,6 @@ struct Certificate;
 
 namespace jami {
 
-struct SipTransportDescr
-{
-    SipTransportDescr() {}
-    SipTransportDescr(pjsip_transport_type_e t)
-     : type(t), listenerPort(pjsip_transport_get_default_port_for_type(t)) {}
-    SipTransportDescr(pjsip_transport_type_e t, pj_uint16_t port, const std::string& i)
-     : type(t), listenerPort(port), interface(i) {}
-
-    static inline pjsip_transport_type_e actualType(pjsip_transport_type_e t) {
-        return (t == PJSIP_TRANSPORT_START_OTHER) ? PJSIP_TRANSPORT_UDP : t;
-    }
-
-    inline bool operator==(SipTransportDescr const& o) const {
-        return actualType(type) == actualType(o.type)
-         && listenerPort == o.listenerPort
-         && interface == o.interface;
-    }
-
-    inline bool operator<(SipTransportDescr const& o) const {
-        return actualType(type) < actualType(o.type)
-         || listenerPort < o.listenerPort
-         || std::hash<std::string>()(interface) < std::hash<std::string>()(o.interface);
-    }
-
-    std::string toString() const;
-
-    pjsip_transport_type_e type {PJSIP_TRANSPORT_UNSPECIFIED};
-    pj_uint16_t listenerPort {sip_utils::DEFAULT_SIP_PORT};
-    std::string interface {"default"};
-};
-
 struct TlsListener
 {
     TlsListener() {}
@@ -175,10 +144,10 @@ public:
     SipTransportBroker(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool);
     ~SipTransportBroker();
 
-    std::shared_ptr<SipTransport> getUdpTransport(const SipTransportDescr&);
+    std::shared_ptr<SipTransport> getUdpTransport(const IpAddr&);
 
     std::shared_ptr<TlsListener>
-    getTlsListener(const SipTransportDescr&, const pjsip_tls_setting*);
+    getTlsListener(const IpAddr&, const pjsip_tls_setting*);
 
     std::shared_ptr<SipTransport>
     getTlsTransport(const std::shared_ptr<TlsListener>&, const IpAddr& remote, const std::string& remote_name = {});
@@ -205,7 +174,7 @@ private:
     * @param IP protocol version to use, can be pj_AF_INET() or pj_AF_INET6()
     * @return a pointer to the new transport
     */
-    std::shared_ptr<SipTransport> createUdpTransport(const SipTransportDescr&);
+    std::shared_ptr<SipTransport> createUdpTransport(const IpAddr&);
 
     /**
      * List of transports so we can bubble the events up.
@@ -217,7 +186,7 @@ private:
      * Transports are stored in this map in order to retrieve them in case
      * several accounts would share the same port number.
      */
-    std::map<SipTransportDescr, pjsip_transport*> udpTransports_;
+    std::map<IpAddr, pjsip_transport*> udpTransports_;
 
     /**
      * Storage for SIP/ICE transport instances.