diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 012290398cdfc89cd8889fd044bb7187dfa3631f..fcf77df4e296a2e445e23b2c7071919a3d41de64 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -376,6 +376,13 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
 #endif
 }
 
+void SIPAccount::usePublishedAddressPortInVIA()
+{
+    via_addr_.host.ptr = (char *) publishedIpAddress_.c_str();
+    via_addr_.host.slen = publishedIpAddress_.size();
+    via_addr_.port = publishedPort_;
+}
+
 void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
 {
     using namespace Conf;
@@ -446,6 +453,9 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
     publishedPort_ = port;
     mapNode.getValue(SAME_AS_LOCAL_KEY, &publishedSameasLocal_);
 
+    if (not publishedSameasLocal_)
+        usePublishedAddressPortInVIA();
+
     if (not isIP2IP()) mapNode.getValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled_);
 
     std::string dtmfType;
@@ -579,6 +589,9 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     localPort_ = atoi(details[CONFIG_LOCAL_PORT].c_str());
     publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
 
+    if (not publishedSameasLocal_)
+        usePublishedAddressPortInVIA();
+
     if (stunServer_ != details[CONFIG_STUN_SERVER]) {
         link_->sipTransport.destroyStunResolver(stunServer_);
         // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
@@ -1120,15 +1133,22 @@ std::string SIPAccount::getContactHeader() const
 
     link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
 
-    if (!receivedParameter_.empty()) {
-        address = receivedParameter_;
-        DEBUG("Using received address %s", address.c_str());
-    }
-
-    if (rPort_ != -1 and rPort_ != 0) {
-        portstr << rPort_;
+    if (not publishedSameasLocal_) {
+        address = publishedIpAddress_;
+        portstr << publishedPort_;
         port = portstr.str();
-        DEBUG("Using received port %s", port.c_str());
+        DEBUG("Using published address %s and port %s", address.c_str(), port.c_str());
+    } else {
+        if (!receivedParameter_.empty()) {
+            address = receivedParameter_;
+            DEBUG("Using received address %s", address.c_str());
+        }
+
+        if (rPort_ != -1 and rPort_ != 0) {
+            portstr << rPort_;
+            port = portstr.str();
+            DEBUG("Using received port %s", port.c_str());
+        }
     }
 
     // UDP does not require the transport specification
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index 02b64690a2b7cae1ec0e927def083f98dcf3e1b9..9ec84818ca4d07feb25b8a4495dea1b620d75b31 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -547,6 +547,7 @@ class SIPAccount : public Account {
     private:
         NON_COPYABLE(SIPAccount);
 
+        void usePublishedAddressPortInVIA();
         bool fullMatch(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
         bool userMatch(const std::string &username) const;
         bool hostnameMatch(const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 8f83797f1efef32b669664c4c0bea8e774aafeab..778b630de5b363ac641acdd582760375983e91dd 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -300,7 +300,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     // May use the published address as well
     std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
-    std::string addrSdp = account->isStunEnabled()
+    std::string addrSdp = account->isStunEnabled() or (not account->getPublishedSameasLocal())
                           ? account->getPublishedAddress()
                           : addrToUse;
 
@@ -727,7 +727,7 @@ void SIPVoIPLink::sendRegister(Account *a)
             DEBUG("Setting VIA sent-by to %s:%u", account->transport_->local_name.host.ptr, account->transport_->local_name.port);
             if (pjsip_regc_set_via_sent_by(regc, &account->transport_->local_name, account->transport_) != PJ_SUCCESS)
                 throw VoipLinkException("Unable to set the \"sent-by\" field");
-        } else if (not received.empty() and received != account->getPublishedAddress()) {
+        } else if (not account->getPublishedSameasLocal() or (not received.empty() and received != account->getPublishedAddress())) {
             DEBUG("Setting VIA sent-by to %s:%d", received.c_str(), account->getRPort());
             if (pjsip_regc_set_via_sent_by(regc, account->getViaAddr(), account->transport_) != PJ_SUCCESS)
                 throw VoipLinkException("Unable to set the \"sent-by\" field");
@@ -912,7 +912,10 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
 
     // Building the local SDP offer
     Sdp *localSDP = call->getLocalSDP();
-    localSDP->setPublishedIP(localAddress);
+    if (account->getPublishedSameasLocal())
+        localSDP->setPublishedIP(localAddress);
+    else
+        localSDP->setPublishedIP(account->getPublishedAddress());
     const bool created = localSDP->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
 
     if (not created or not SIPStartCall(call)) {
@@ -948,7 +951,7 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
     setCallMediaLocal(call, localAddr);
 
     // May use the published address as well
-    std::string addrSdp = account->isStunEnabled() ?
+    std::string addrSdp = account->isStunEnabled() or (not account->getPublishedSameasLocal()) ?
     account->getPublishedAddress() :
     SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
 
@@ -1772,10 +1775,15 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
     if (!account)
         return;
 
-    std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
-    std::string addrSdp(localAddress);
+    std::string address;
+    if (account->getPublishedSameasLocal())
+        address = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
+    else
+        address = account->getPublishedAddress();
 
-    setCallMediaLocal(call, localAddress);
+    const std::string addrSdp(address);
+
+    setCallMediaLocal(call, address);
 
     Sdp *localSDP = call->getLocalSDP();
     localSDP->setPublishedIP(addrSdp);