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);