diff --git a/src/call.cpp b/src/call.cpp index 892832c1a21849de3d854e13561d488b716f11f4..01b2ed5df0c5b919764df2adca357bfa919ce4c4 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -430,11 +430,8 @@ Call::onTextMessage(std::map<std::string, std::string>&& messages) #ifdef ENABLE_PLUGIN auto& pluginChatManager = Manager::instance().getJamiPluginManager().getChatServicesManager(); if (pluginChatManager.hasHandlers()) { - pluginChatManager.publishMessage(std::make_shared<JamiMessage>(getAccountId(), - getPeerNumber(), - true, - messages, - false)); + pluginChatManager.publishMessage( + std::make_shared<JamiMessage>(getAccountId(), getPeerNumber(), true, messages, false)); } #endif Manager::instance().incomingMessage(getCallId(), getPeerNumber(), messages); @@ -474,8 +471,9 @@ Call::addSubCall(Call& subcall) subcall.sendTextMessage(msg.first, msg.second); subcall.addStateListener( - [sub = subcall.weak(), - parent = weak()](Call::CallState new_state, Call::ConnectionState new_cstate, int code) { + [sub = subcall.weak(), parent = weak()](Call::CallState new_state, + Call::ConnectionState new_cstate, + int /* code */) { runOnMainThread([sub, parent, new_state, new_cstate]() { if (auto p = parent.lock()) { if (auto s = sub.lock()) { diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index e1586cd6cae2499f836b2746f9eea662ec7c1dad..1895e02a92e5da45266e21159f20e197a4ad979a 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -794,19 +794,14 @@ JamiAccount::SIPStartCall(SIPCall& call, const IpAddr& target) std::string targetStr = getToUri(target.toString(true)); pj_str_t pjTarget = sip_utils::CONST_PJ_STR(targetStr); - pj_str_t pjContact; - { - auto transport = call.getTransport(); - pjContact = getContactHeader(transport ? transport->get() : nullptr); - } + auto contact = getContactHeader(call.getTransport()); + auto pjContact = sip_utils::CONST_PJ_STR(contact); - JAMI_DBG("contact header: %.*s / %s -> %s / %.*s", - (int) pjContact.slen, - pjContact.ptr, + JAMI_DBG("contact header: %s / %s -> %s / %s", + contact.c_str(), from.c_str(), toUri.c_str(), - (int) pjTarget.slen, - pjTarget.ptr); + targetStr.c_str()); auto local_sdp = call.getSDP().getLocalSdpSession(); pjsip_dialog* dialog {nullptr}; @@ -3058,32 +3053,26 @@ JamiAccount::setMessageDisplayed(const std::string& conversationUri, return true; } -pj_str_t -JamiAccount::getContactHeader(pjsip_transport* t) +std::string +JamiAccount::getContactHeader(SipTransport* sipTransport) { std::string quotedDisplayName = "\"" + displayName_ + "\" " + (displayName_.empty() ? "" : " "); - if (t) { - auto* td = reinterpret_cast<tls::AbstractSIPTransport::TransportData*>(t); + std::ostringstream contact; + + if (auto transport = sipTransport->get()) { + auto* td = reinterpret_cast<tls::AbstractSIPTransport::TransportData*>(transport); auto address = td->self->getLocalAddress().toString(true); - bool reliable = t->flag & PJSIP_TRANSPORT_RELIABLE; - - contact_.slen = pj_ansi_snprintf(contact_.ptr, - PJSIP_MAX_URL_SIZE, - "%s<sips:%s%s%s;transport=%s>", - quotedDisplayName.c_str(), - id_.second->getId().toString().c_str(), - (address.empty() ? "" : "@"), - address.c_str(), - reliable ? "tls" : "dtls"); + bool reliable = transport->flag & PJSIP_TRANSPORT_RELIABLE; + + contact << quotedDisplayName << "<sips:" << id_.second->getId().toString() + << (address.empty() ? "" : "@") << address + << (reliable ? ";transport=tls>" : ";transport=dtls"); } else { JAMI_ERR("getContactHeader: no SIP transport provided"); - contact_.slen = pj_ansi_snprintf(contact_.ptr, - PJSIP_MAX_URL_SIZE, - "%s<sips:%s@ring.dht>", - quotedDisplayName.c_str(), - id_.second->getId().toString().c_str()); + contact << quotedDisplayName << "<sips:" << id_.second->getId().toString() << "@ring.dht>"; } - return contact_; + + return contact.str(); } /* contacts */ diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h index 5e2d50754efcadcba6c27b0a6d24309479bd68a6..0587a2a37afad5a6f5a54b0d1ed50b3896c958d3 100644 --- a/src/jamidht/jamiaccount.h +++ b/src/jamidht/jamiaccount.h @@ -251,9 +251,9 @@ public: /** * Get the contact header for - * @return pj_str_t The contact header based on account information + * @return The contact header based on account information */ - pj_str_t getContactHeader(pjsip_transport* = nullptr) override; + std::string getContactHeader(SipTransport* transport = nullptr) override; /* Returns true if the username and/or hostname match this account */ MatchRank matches(std::string_view username, std::string_view hostname) const override; @@ -804,8 +804,6 @@ private: */ pjsip_host_port via_addr_ {}; - char contactBuffer_[PJSIP_MAX_URL_SIZE] {}; - pj_str_t contact_ {contactBuffer_, 0}; pjsip_transport* via_tp_ {nullptr}; std::unique_ptr<DhtPeerConnector> dhtPeerConnector_; diff --git a/src/jamidht/sync_channel_handler.cpp b/src/jamidht/sync_channel_handler.cpp index 3cff8e4530169c9b98c39edfa51293712a751b91..6adb88073a21d45682d03f4f8211d8b54b78cfa0 100644 --- a/src/jamidht/sync_channel_handler.cpp +++ b/src/jamidht/sync_channel_handler.cpp @@ -50,7 +50,7 @@ SyncChannelHandler::connect(const DeviceId& deviceId, const std::string&, Connec } bool -SyncChannelHandler::onRequest(const DeviceId& deviceId, const std::string& name) +SyncChannelHandler::onRequest(const DeviceId& deviceId, const std::string& /* name */) { auto cert = tls::CertificateStore::instance().getCertificate(deviceId.toString()); auto acc = account_.lock(); diff --git a/src/sip/sip_utils.cpp b/src/sip/sip_utils.cpp index 5821bd346be9841979879fbcad2eda7bcaa6186f..edfed41bed70672a15e4895ad70fdf7276a26396 100644 --- a/src/sip/sip_utils.cpp +++ b/src/sip/sip_utils.cpp @@ -174,12 +174,17 @@ getHostFromUri(std::string_view uri) } void -addContactHeader(pj_str_t contact_str, pjsip_tx_data* tdata) +addContactHeader(const std::string& contactHdr, pjsip_tx_data* tdata) { + if (contactHdr.empty()) { + JAMI_WARN("Contact header won't be added (empty string)"); + return; + } + auto pjContact = sip_utils::CONST_PJ_STR(contactHdr); pjsip_contact_hdr* contact = pjsip_contact_hdr_create(tdata->pool); contact->uri = pjsip_parse_uri(tdata->pool, - contact_str.ptr, - contact_str.slen, + pjContact.ptr, + pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR); // remove old contact header (if present) pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_CONTACT, NULL); @@ -189,7 +194,7 @@ addContactHeader(pj_str_t contact_str, pjsip_tx_data* tdata) void addUserAgentHeader(const std::string& userAgent, pjsip_tx_data* tdata) { - if (tdata == nullptr) + if (tdata == nullptr or userAgent.empty()) return; auto pjUserAgent = CONST_PJ_STR(userAgent); @@ -224,8 +229,8 @@ getPeerUserAgent(const pjsip_rx_data* rdata) constexpr auto USER_AGENT_STR = CONST_PJ_STR("User-Agent"); if (auto uaHdr = (pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, - &USER_AGENT_STR, - nullptr)) { + &USER_AGENT_STR, + nullptr)) { return as_view(uaHdr->hvalue); } return {}; diff --git a/src/sip/sip_utils.h b/src/sip/sip_utils.h index 31e58ca793e943460621f5eca1fec1d3fd77dca7..9b72323fac12754fbdd1bf2c941fc40fb2276c96 100644 --- a/src/sip/sip_utils.h +++ b/src/sip/sip_utils.h @@ -96,7 +96,7 @@ std::string parseDisplayName(const pjsip_contact_hdr* header); std::string_view getHostFromUri(std::string_view sipUri); -void addContactHeader(pj_str_t contactStr, pjsip_tx_data* tdata); +void addContactHeader(const std::string& contact, pjsip_tx_data* tdata); void addUserAgentHeader(const std::string& userAgent, pjsip_tx_data* tdata); std::string_view getPeerUserAgent(const pjsip_rx_data* rdata); void logMessageHeaders(const pjsip_hdr* hdr_list); diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp index ca2750ce78ec7fe4a5cefea20038baaa6f2c2397..f501adaae6b7e1c9b90439c6218ab6f7f357bc66 100644 --- a/src/sip/sipaccount.cpp +++ b/src/sip/sipaccount.cpp @@ -146,8 +146,6 @@ SIPAccount::SIPAccount(const std::string& accountID, bool presenceEnabled) , receivedParameter_("") , rPort_(-1) , via_addr_() - , contactBuffer_() - , contact_ {contactBuffer_, 0} , contactRewriteMethod_(2) , allowIPAutoRewrite_(true) , contactOverwritten_(false) @@ -451,13 +449,10 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call) return false; } - pj_str_t pjContact = getContactHeader(transport->get()); - JAMI_DBG("contact header: %.*s / %s -> %s", - (int) pjContact.slen, - pjContact.ptr, - from.c_str(), - toUri.c_str()); + std::string contact = getContactHeader(transport); + JAMI_DBG("contact header: %s / %s -> %s", contact.c_str(), from.c_str(), toUri.c_str()); + pj_str_t pjContact = sip_utils::CONST_PJ_STR(contact); auto local_sdp = isEmptyOffersEnabled() ? nullptr : call->getSDP().getLocalSdpSession(); pjsip_dialog* dialog {nullptr}; @@ -881,8 +876,7 @@ SIPAccount::setPushNotificationToken(const std::string& pushDeviceToken) return; deviceKey_ = pushDeviceToken; - pj_bzero(contact_.ptr, sizeof(contact_)); - contact_.slen = 0; + contact_.clear(); if (enabled_) doUnregister([&](bool /* transport_free */) { doRegister(); }); @@ -890,7 +884,7 @@ SIPAccount::setPushNotificationToken(const std::string& pushDeviceToken) void SIPAccount::pushNotificationReceived(const std::string& from, - const std::map<std::string, std::string>& data) + const std::map<std::string, std::string>&) { JAMI_WARN("[SIP Account %s] pushNotificationReceived: %s", getAccountID().c_str(), from.c_str()); @@ -1099,7 +1093,8 @@ SIPAccount::sendRegister() const std::string& received(getReceivedParameter()); // Get the contact header - const pj_str_t pjContact(getContactHeader()); + std::string contact = getContactHeader(); + pj_str_t pjContact = sip_utils::CONST_PJ_STR(contact); JAMI_DBG("Using contact header %.*s in registration", (int) pjContact.slen, pjContact.ptr); @@ -1568,17 +1563,17 @@ SIPAccount::getServerUri() const return "<" + scheme + host + transport + ">"; } -pj_str_t -SIPAccount::getContactHeader(pjsip_transport* t) +std::string +SIPAccount::getContactHeader(SipTransport* sipTransport) { - if (contact_.slen and contactOverwritten_) + if (not contact_.empty() and contactOverwritten_) return contact_; - if (!t && transport_) - t = transport_->get(); - if (!t) { + if (not sipTransport && transport_) + sipTransport = transport_.get(); + if (not sipTransport) { JAMI_ERR("Transport not created yet"); - return {nullptr, 0}; + return {}; } // The transport type must be specified, in our case START_OTHER refers to stun transport @@ -1591,7 +1586,7 @@ SIPAccount::getContactHeader(pjsip_transport* t) std::string address; pj_uint16_t port; - link_.findLocalAddressFromTransport(t, transportType, hostname_, address, port); + link_.findLocalAddressFromTransport(sipTransport->get(), transportType, hostname_, address, port); if (getUPnPActive() and getUPnPIpAddress()) { address = getUPnPIpAddress().toString(); @@ -1603,7 +1598,11 @@ SIPAccount::getContactHeader(pjsip_transport* t) port = publishedPort_; JAMI_DBG("Using published address %s and port %d", address.c_str(), port); } else if (stunEnabled_) { - auto success = link_.findLocalAddressFromSTUN(t, &stunServerName_, stunPort_, address, port); + auto success = link_.findLocalAddressFromSTUN(sipTransport->get(), + &stunServerName_, + stunPort_, + address, + port); if (not success) emitSignal<DRing::ConfigurationSignal::StunStatusFailed>(getAccountID()); setPublishedAddress({address}); @@ -1628,55 +1627,48 @@ SIPAccount::getContactHeader(pjsip_transport* t) const char* scheme = "sip"; const char* transport = ""; - if (PJSIP_TRANSPORT_IS_SECURE(t)) { + if (PJSIP_TRANSPORT_IS_SECURE(sipTransport->get())) { scheme = "sips"; transport = ";transport=tls"; } std::string quotedDisplayName = displayName_.empty() ? "" : "\"" + displayName_ + "\" "; - contact_.slen - = printContactHeader(contact_.ptr, quotedDisplayName, scheme, address, port, transport); + contact_ = printContactHeader(quotedDisplayName, scheme, address, port, transport); return contact_; } -int -SIPAccount::printContactHeader(char* data, - const std::string& displayName, +std::string +SIPAccount::printContactHeader(const std::string& displayName, const char* scheme, const std::string& address, pj_uint16_t port, const char* transport) { - if (deviceKey_.empty()) { - return pj_ansi_snprintf(data, - PJSIP_MAX_URL_SIZE, - CONTACT_HEADER_WITHOUT_PN, - displayName.c_str(), - scheme, - username_.c_str(), - (username_.empty() ? "" : "@"), - address.c_str(), - port, - transport); - } else { - return pj_ansi_snprintf(data, - PJSIP_MAX_URL_SIZE, - CONTACT_HEADER_WITH_PN, - displayName.c_str(), - scheme, - username_.c_str(), - (username_.empty() ? "" : "@"), - address.c_str(), - port, - transport, + // This method generates SIP contact header field, with push + // notification parameters if any. + // Example without push notification: + // John Doe<sips:jdoe@10.10.10.10:5060;transport=tls> + // Example with push notification: + // John Doe<sips:jdoe@10.10.10.10:5060;transport=tls;pn-provider=XXX;pn-param=YYY;pn-prid=ZZZ> + + std::ostringstream contact; + + contact << displayName << "<" << scheme << ":" << username_ << (username_.empty() ? "" : "@") + << address << ":" << port << transport; + + if (not deviceKey_.empty()) { + contact #if defined(__ANDROID__) || defined(ANDROID) - PN_FCM, + << "pn-provider=" << PN_FCM #elif defined(__Apple__) - PN_APNS, + << "pn-provider=" << PN_APNS #endif - "", - deviceKey_.c_str()); + << "pn-param=;" + << "pn-prid=" << deviceKey_; } + contact << ">"; + + return contact.str(); } pjsip_host_port @@ -2007,9 +1999,10 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam* param, pj_pool_t* pool) setPublishedAddress(IpAddr(via_addrstr)); /* Compare received and rport with the URI in our registration */ + auto pjContact = sip_utils::CONST_PJ_STR(getContactHeader()); const pj_str_t STR_CONTACT = {(char*) "Contact", 7}; pjsip_contact_hdr* contact_hdr = (pjsip_contact_hdr*) - pjsip_parse_hdr(pool, &STR_CONTACT, contact_.ptr, contact_.slen, nullptr); + pjsip_parse_hdr(pool, &STR_CONTACT, pjContact.ptr, pjContact.slen, nullptr); pj_assert(contact_hdr != nullptr); pjsip_sip_uri* uri = (pjsip_sip_uri*) contact_hdr->uri; pj_assert(uri != nullptr); @@ -2106,21 +2099,21 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam* param, pj_pool_t* pool) transport_param = ";transport=tls"; } - char* tmp = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE); - int len = printContactHeader(tmp, "", scheme, via_addrstr, rport, transport_param); + auto tmp = printContactHeader("", scheme, via_addrstr, rport, transport_param); - if (len < 1) { - JAMI_ERR("URI too long"); + if (tmp.empty()) { + JAMI_ERR("Invalid contact header"); return false; } - pj_str_t tmp_str = {tmp, len}; - pj_strncpy_with_null(&contact_, &tmp_str, PJSIP_MAX_URL_SIZE); + // Update + contact_ = std::move(tmp); + pjContact = sip_utils::CONST_PJ_STR(contact_); } if (contactRewriteMethod_ == 2 && regc_ != nullptr) { contactOverwritten_ = true; - pjsip_regc_update_contact(regc_, 1, &contact_); + pjsip_regc_update_contact(regc_, 1, &pjContact); /* Perform new registration at the next registration cycle */ } diff --git a/src/sip/sipaccount.h b/src/sip/sipaccount.h index c3d473b1908da6e9edc8747989e31021ae06dc85..c71d6c4d05cdbdb43a3933ed644441b491ae16c2 100644 --- a/src/sip/sipaccount.h +++ b/src/sip/sipaccount.h @@ -69,9 +69,6 @@ class SIPAccount : public SIPAccountBase { public: constexpr static const char* const ACCOUNT_TYPE = "SIP"; - constexpr static const char* const CONTACT_HEADER_WITH_PN - = "%s<%s:%s%s%s:%d%s;pn-provider=%s;pn-param=%s;pn-prid=%s>"; - constexpr static const char* const CONTACT_HEADER_WITHOUT_PN = "%s<%s:%s%s%s:%d%s>"; constexpr static const char* const PN_FCM = "fcm"; constexpr static const char* const PN_APNS = "apns"; @@ -348,9 +345,9 @@ public: /** * Get the contact header for - * @return pj_str_t The contact header based on account information + * @return The contact header based on account information */ - pj_str_t getContactHeader(pjsip_transport* = nullptr) override; + std::string getContactHeader(SipTransport* transport = nullptr) override; std::string getServiceRoute() const { return serviceRoute_; } @@ -613,12 +610,11 @@ private: /** * Print contact header in certain format */ - int printContactHeader(char* data, - const std::string& displayName, - const char* scheme, - const std::string& address, - pj_uint16_t port, - const char* transport); + std::string printContactHeader(const std::string& displayName, + const char* scheme, + const std::string& address, + pj_uint16_t port, + const char* transport); /** * Resolved IP of hostname_ (for registration) @@ -750,8 +746,7 @@ private: */ std::string upnpIpAddr_; - char contactBuffer_[PJSIP_MAX_URL_SIZE]; - pj_str_t contact_; + std::string contact_; int contactRewriteMethod_; bool allowIPAutoRewrite_; /* Undocumented feature in pjsip, this can == 2 */ diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp index a71979d6252c4115eacd6c9e2da713662e3a222e..498561e7e50d3f1176215f6153b6b2c2a39c65c5 100644 --- a/src/sip/sipaccountbase.cpp +++ b/src/sip/sipaccountbase.cpp @@ -458,7 +458,7 @@ SIPAccountBase::getIceOptions() const noexcept void SIPAccountBase::onTextMessage(const std::string& id, const std::string& from, - const std::string& deviceId, + const std::string& /* deviceId */, const std::map<std::string, std::string>& payloads) { JAMI_DBG("Text message received from %s, %zu part(s)", from.c_str(), payloads.size()); @@ -476,7 +476,8 @@ SIPAccountBase::onTextMessage(const std::string& id, #ifdef ENABLE_PLUGIN auto& pluginChatManager = Manager::instance().getJamiPluginManager().getChatServicesManager(); if (pluginChatManager.hasHandlers()) { - pluginChatManager.publishMessage(std::make_shared<JamiMessage>(accountID_, from, true, payloads, false)); + pluginChatManager.publishMessage( + std::make_shared<JamiMessage>(accountID_, from, true, payloads, false)); } #endif emitSignal<DRing::ConfigurationSignal::IncomingAccountMessage>(accountID_, from, id, payloads); diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h index e5d571fe712d49e51687782627cba8762b79c483..67837d113e7432a35134ee85f9bef5021356643f 100644 --- a/src/sip/sipaccountbase.h +++ b/src/sip/sipaccountbase.h @@ -216,9 +216,9 @@ public: /** * Get the contact header for - * @return pj_str_t The contact header based on account information + * @return The contact header based on account information */ - virtual pj_str_t getContactHeader(pjsip_transport* = nullptr) = 0; + virtual std::string getContactHeader(SipTransport* transport = nullptr) = 0; virtual std::string getToUri(const std::string& username) const = 0; diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index fc0cccd0a19619ca3d8ab618761f1e9a82bce1a2..5b134a62ff8a3056e4208f996161311bd1f893d0 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -420,9 +420,15 @@ SIPCall::generateMediaPorts() } void -SIPCall::setContactHeader(pj_str_t contact) +SIPCall::setContactHeader(const std::string& contact) { - pj_strcpy(&contactHeader_, &contact); + contactHeader_ = contact; +} + +const std::string& +SIPCall::getContactHeader() const +{ + return contactHeader_; } void @@ -437,6 +443,12 @@ SIPCall::setTransport(const std::shared_ptr<SipTransport>& t) if (not t) { return; } + auto account = getSIPAccount(); + if (not account) { + JAMI_ERR("[call:%s] No account detected", getCallId().c_str()); + } + + setContactHeader(account->getContactHeader(transport_.get())); if (isSrtpEnabled() and not transport_->isSecure()) { JAMI_WARN("[call:%s] Crypto (SRTP) is negotiated over an un-encrypted signaling channel", @@ -701,9 +713,7 @@ SIPCall::terminateSipSession(int status) if (tdata) { auto account = getSIPAccount(); if (account) { - sip_utils::addContactHeader(account->getContactHeader( - transport_ ? transport_->get() : nullptr), - tdata); + sip_utils::addContactHeader(contactHeader_, tdata); // Add user-agent header sip_utils::addUserAgentHeader(account->getUserAgentName(), tdata); } else { @@ -750,8 +760,6 @@ SIPCall::answer() Manager::instance().sipVoIPLink().createSDPOffer(inviteSession_.get()); } - setContactHeader(account->getContactHeader(transport_ ? transport_->get() : nullptr)); - pjsip_tx_data* tdata; if (!inviteSession_->last_answer) throw std::runtime_error("Should only be called for initial answer"); @@ -765,15 +773,16 @@ SIPCall::answer() != PJ_SUCCESS) throw std::runtime_error("Could not init invite request answer (200 OK)"); - // contactStr must stay in scope as long as tdata - if (contactHeader_.slen) { - JAMI_DBG("[call:%s] Answering with contact header: %.*s", - getCallId().c_str(), - (int) contactHeader_.slen, - contactHeader_.ptr); - sip_utils::addContactHeader(contactHeader_, tdata); + if (contactHeader_.empty()) { + throw std::runtime_error("Cant answer with an invalid contact header"); } + JAMI_DBG("[call:%s] Answering with contact header: %s", + getCallId().c_str(), + contactHeader_.c_str()); + + sip_utils::addContactHeader(contactHeader_, tdata); + // Add user-agent header sip_utils::addUserAgentHeader(account->getUserAgentName(), tdata); @@ -879,8 +888,6 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList) } } - setContactHeader(account->getContactHeader(transport_ ? transport_->get() : nullptr)); - if (!inviteSession_->last_answer) throw std::runtime_error("Should only be called for initial answer"); @@ -896,14 +903,16 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList) != PJ_SUCCESS) throw std::runtime_error("Could not init invite request answer (200 OK)"); - if (contactHeader_.slen) { - JAMI_DBG("[call:%s] Answering with contact header: %.*s", - getCallId().c_str(), - (int) contactHeader_.slen, - contactHeader_.ptr); - sip_utils::addContactHeader(contactHeader_, tdata); + if (contactHeader_.empty()) { + throw std::runtime_error("Cant answer with an invalid contact header"); } + JAMI_DBG("[call:%s] Answering with contact header: %s", + getCallId().c_str(), + contactHeader_.c_str()); + + sip_utils::addContactHeader(contactHeader_, tdata); + // Add user-agent header sip_utils::addUserAgentHeader(account->getUserAgentName(), tdata); @@ -990,7 +999,7 @@ SIPCall::answerMediaChangeRequest(const std::vector<DRing::MediaMap>& mediaList) return; } - if (contactHeader_.slen) { + if (not contactHeader_.empty()) { sip_utils::addContactHeader(contactHeader_, tdata); } @@ -2501,7 +2510,7 @@ SIPCall::onReceiveOffer(const pjmedia_sdp_session* offer, const pjsip_rx_data* r NULL, &tdata) != PJ_SUCCESS) { - JAMI_ERR("Could not create initial answer OK"); + JAMI_ERR("[call:%s] Could not create initial answer OK", getCallId().c_str()); return !PJ_SUCCESS; } @@ -2514,11 +2523,15 @@ SIPCall::onReceiveOffer(const pjmedia_sdp_session* offer, const pjsip_rx_data* r return !PJ_SUCCESS; } - // ContactStr must stay in scope as long as tdata - sip_utils::addContactHeader(getSIPAccount()->getContactHeader(getTransport()->get()), tdata); + if (contactHeader_.empty()) { + JAMI_ERR("[call:%s] Contact header is empty!", getCallId().c_str()); + return !PJ_SUCCESS; + } + + sip_utils::addContactHeader(contactHeader_, tdata); if (pjsip_inv_send_msg(inviteSession_.get(), tdata) != PJ_SUCCESS) { - JAMI_ERR("Could not send msg OK"); + JAMI_ERR("[call:%s] Could not send msg OK", getCallId().c_str()); return !PJ_SUCCESS; } @@ -3029,8 +3042,7 @@ SIPCall::merge(Call& call) sdp_ = std::move(subcall.sdp_); peerHolding_ = subcall.peerHolding_; upnp_ = std::move(subcall.upnp_); - std::copy_n(subcall.contactBuffer_, PJSIP_MAX_URL_SIZE, contactBuffer_); - pj_strcpy(&contactHeader_, &subcall.contactHeader_); + contactHeader_ = std::move(subcall.contactHeader_); localAudioPort_ = subcall.localAudioPort_; localVideoPort_ = subcall.localVideoPort_; peerUserAgent_ = subcall.peerUserAgent_; diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h index d0c1a5465c2a3dfb7418eb382eedaad77cc66edc..1860a1d0805ac1a698186030d2026720a47d0ebc 100644 --- a/src/sip/sipcall.h +++ b/src/sip/sipcall.h @@ -219,7 +219,8 @@ public: void onMediaNegotiationComplete(); // End fo SiPVoipLink events - void setContactHeader(pj_str_t contact); + void setContactHeader(const std::string& contact); + const std::string& getContactHeader() const; void setTransport(const std::shared_ptr<SipTransport>& t); @@ -432,8 +433,7 @@ private: std::string peerRegisteredName_ {}; - char contactBuffer_[PJSIP_MAX_URL_SIZE] {}; - pj_str_t contactHeader_ {contactBuffer_, 0}; + std::string contactHeader_ {}; std::shared_ptr<jami::upnp::Controller> upnp_; diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp index b82c6b4e5eb9ab6c741b696394eafad313ebc697..85301860e0d18282cfd8cf944891e87c9a54863d 100644 --- a/src/sip/sipvoiplink.cpp +++ b/src/sip/sipvoiplink.cpp @@ -560,7 +560,7 @@ transaction_request_cb(pjsip_rx_data* rdata) return PJ_FALSE; } - sip_utils::addContactHeader(account->getContactHeader(transport->get()), tdata); + sip_utils::addContactHeader(call->getContactHeader(), tdata); if (pjsip_inv_send_msg(call->inviteSession_.get(), tdata) != PJ_SUCCESS) { JAMI_ERR("Could not send msg RINGING"); return PJ_FALSE;