diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index 799b47c00b38ceeecf9bbded4bf4df64922d0c2f..4b028d91e1577d5a1ca0b21d10e05924ace51acd 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -337,6 +337,18 @@ void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
         pjmedia_sdp_attr_add(&med->attr_count, med->attr, attr);
 }
 
+void
+Sdp::setPublishedIP(const std::string &ip_addr)
+{
+    publishedIpAddr_ = ip_addr;
+    if (localSession_) {
+        localSession_->origin.addr = pj_str((char*) publishedIpAddr_.c_str());
+        localSession_->conn->addr = localSession_->origin.addr;
+        if (not pjmedia_sdp_validate(localSession_))
+            ERROR("Could not validate SDP");
+    }
+}
+
 void
 Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
 {
@@ -344,6 +356,20 @@ Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
     localAudioControlPort_  = pj_ntohs(sockets[1].sin_port);
     localVideoDataPort_     = pj_ntohs(sockets[2].sin_port);
     localVideoControlPort_  = pj_ntohs(sockets[3].sin_port);
+
+    if (localSession_) {
+        if (localSession_->media[0]) {
+            localSession_->media[0]->desc.port = localAudioDataPort_;
+            // update RTCP attribute
+            if (pjmedia_sdp_media_remove_all_attr(localSession_->media[0], "rtcp"))
+                addRTCPAttribute(localSession_->media[0]);
+        }
+        if (localSession_->media[1])
+            localSession_->media[1]->desc.port = localVideoDataPort_;
+
+        if (not pjmedia_sdp_validate(localSession_))
+            ERROR("Could not validate SDP");
+    }
 }
 
 
diff --git a/daemon/src/sip/sdp.h b/daemon/src/sip/sdp.h
index a731c14d528b7447ec08896e6af91cfebaddf938..f6c74f03e51d078e514f2bbb4db7aee887898493 100644
--- a/daemon/src/sip/sdp.h
+++ b/daemon/src/sip/sdp.h
@@ -153,9 +153,7 @@ class Sdp {
         /*
          * Write accessor. Set the local IP address that will be used in the sdp session
          */
-        void setPublishedIP(const std::string &ip_addr) {
-            publishedIpAddr_ = ip_addr;
-        }
+        void setPublishedIP(const std::string &ip_addr);
 
         /*
          * Read accessor. Get the local IP address
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index c12b55f3df852d1e05651ab28faa330cd0b411be..a616b4e2eb22369fd115c5841d327fee764dbe3f 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -226,8 +226,9 @@ void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &t
         stunPorts.resize(4);
 
         account.setPublishedAddress(pj_inet_ntoa(stunPorts[0].sin_addr));
-        call.getLocalSDP()->updatePorts(stunPorts);
+        // published IP MUST be updated first, since RTCP depends on it
         call.getLocalSDP()->setPublishedIP(account.getPublishedAddress());
+        call.getLocalSDP()->updatePorts(stunPorts);
     } catch (const std::runtime_error &e) {
         ERROR("%s", e.what());
     }