mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
SIP - prevent race condition when writing contact header
The contact header field was stored in a member varialbe of Jami/SIP accounts. There was a condition in which the contact header could be concurrently accessed by multiple threads. This typically happens when terminating calls in batch (when calling hangupCalls() for instance). Managment of SIP contact header in Jami and SIP accounts was reworked to prevent such race. Gitlab: #633 Change-Id: Ib9295070a5295969bf114ec29e66e36b1c5c5e03
This commit is contained in:
12
src/call.cpp
12
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()) {
|
||||
|
@ -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);
|
||||
auto address = td->self->getLocalAddress().toString(true);
|
||||
bool reliable = t->flag & PJSIP_TRANSPORT_RELIABLE;
|
||||
std::ostringstream contact;
|
||||
|
||||
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");
|
||||
if (auto transport = sipTransport->get()) {
|
||||
auto* td = reinterpret_cast<tls::AbstractSIPTransport::TransportData*>(transport);
|
||||
auto address = td->self->getLocalAddress().toString(true);
|
||||
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 */
|
||||
|
@ -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_;
|
||||
|
@ -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();
|
||||
|
@ -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 {};
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user