Commit 82a0e238 authored by Adrien Béraud's avatar Adrien Béraud Committed by Tristan Matthews

sip: transport refactoring

SIPTransport now represents a SIP transport.
The old SIPTransport class becomes SIPTransportBroker.
Makes every sip call have its own transport, to allow IP2IP calls
using TLS.

Refs #53057
Change-Id: I6ae8e1a4c681c6f4f5887772f5b852bd440df13f
parent ff4ee38a
...@@ -204,5 +204,4 @@ void AccountFactory::initIP2IPAccount() ...@@ -204,5 +204,4 @@ void AccountFactory::initIP2IPAccount()
// cache this often used account using a weak_ptr // cache this often used account using a weak_ptr
ip2ip_account_ = createAccount(SIPAccount::ACCOUNT_TYPE, ip2ip_account_ = createAccount(SIPAccount::ACCOUNT_TYPE,
SIPAccount::IP2IP_PROFILE); SIPAccount::IP2IP_PROFILE);
SIPVoIPLink::loadIP2IPSettings();
} }
...@@ -192,6 +192,14 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) ...@@ -192,6 +192,14 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl)
toUri = getToUri(to); toUri = getToUri(to);
family = ipv6 ? pj_AF_INET6() : pj_AF_INET(); family = ipv6 ? pj_AF_INET6() : pj_AF_INET();
std::shared_ptr<SipTransport> t =
#if HAVE_TLS
isTlsEnabled() ? link_->sipTransport->getTlsTransport(tlsListener_, toUri) :
#endif
transport_;
setTransport(t);
call->setTransport(t);
DEBUG("New %s IP to IP call to %s", ipv6?"IPv6":"IPv4", to.c_str()); DEBUG("New %s IP to IP call to %s", ipv6?"IPv6":"IPv4", to.c_str());
} }
else { else {
...@@ -204,6 +212,7 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) ...@@ -204,6 +212,7 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl)
else else
toUri = getToUri(to); toUri = getToUri(to);
call->setTransport(transport_);
// FIXME : for now, use the same address family as the SIP tranport // FIXME : for now, use the same address family as the SIP tranport
family = pjsip_transport_type_get_af(getTransportType()); family = pjsip_transport_type_get_af(getTransportType());
...@@ -328,7 +337,7 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call) ...@@ -328,7 +337,7 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
return false; return false;
} }
const pjsip_tpselector tp_sel = getTransportSelector(); const pjsip_tpselector tp_sel = SipTransportBroker::getTransportSelector(call->getTransport()->get());
if (pjsip_dlg_set_transport(dialog, &tp_sel) != PJ_SUCCESS) { if (pjsip_dlg_set_transport(dialog, &tp_sel) != PJ_SUCCESS) {
ERROR("Unable to associate transport for invite session dialog"); ERROR("Unable to associate transport for invite session dialog");
return false; return false;
...@@ -687,9 +696,21 @@ void SIPAccount::doRegister() ...@@ -687,9 +696,21 @@ void SIPAccount::doRegister()
transportType_ = IPv6 ? PJSIP_TRANSPORT_TLS6 : PJSIP_TRANSPORT_TLS; transportType_ = IPv6 ? PJSIP_TRANSPORT_TLS6 : PJSIP_TRANSPORT_TLS;
initTlsConfiguration(); initTlsConfiguration();
if (!tlsListener_) {
tlsListener_ = link_->sipTransport->getTlsListener(
SipTransportDescr {getTransportType(), getTlsListenerPort(), getLocalInterface()},
getTlsSetting());
if (!tlsListener_) {
setRegistrationState(RegistrationState::ERROR_GENERIC);
ERROR("Error creating TLS listener.");
return;
}
}
} else } else
#endif #endif
{ {
tlsListener_.reset();
transportType_ = IPv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP; transportType_ = IPv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP;
} }
...@@ -703,14 +724,36 @@ void SIPAccount::doRegister() ...@@ -703,14 +724,36 @@ void SIPAccount::doRegister()
// In our definition of the ip2ip profile (aka Direct IP Calls), // In our definition of the ip2ip profile (aka Direct IP Calls),
// no registration should be performed // no registration should be performed
if (isIP2IP()) if (isIP2IP()) {
// If we use Tls for IP2IP, transports will be created on connection.
if (!tlsEnable_)
setTransport(link_->sipTransport->getUdpTransport(
SipTransportDescr { getTransportType(), getLocalPort(), getLocalInterface() }
));
return; return;
}
try { try {
WARN("Creating transport");
transport_.reset();
#if HAVE_TLS
if (isTlsEnabled()) {
setTransport(link_->sipTransport->getTlsTransport(tlsListener_, getServerUri()));
} else
#endif
{
setTransport(link_->sipTransport->getUdpTransport(
SipTransportDescr { getTransportType(), getLocalPort(), getLocalInterface() }
));
}
if (!transport_)
throw VoipLinkException("Can't create transport");
sendRegister(); sendRegister();
} catch (const VoipLinkException &e) { } catch (const VoipLinkException &e) {
ERROR("%s", e.what()); ERROR("%s", e.what());
setRegistrationState(RegistrationState::ERROR_GENERIC); setRegistrationState(RegistrationState::ERROR_GENERIC);
return;
} }
#ifdef SFL_PRESENCE #ifdef SFL_PRESENCE
...@@ -723,6 +766,7 @@ void SIPAccount::doRegister() ...@@ -723,6 +766,7 @@ void SIPAccount::doRegister()
void SIPAccount::doUnregister(std::function<void(bool)> released_cb) void SIPAccount::doUnregister(std::function<void(bool)> released_cb)
{ {
tlsListener_.reset();
if (isIP2IP()) { if (isIP2IP()) {
if (released_cb) if (released_cb)
released_cb(false); released_cb(false);
...@@ -730,18 +774,20 @@ void SIPAccount::doUnregister(std::function<void(bool)> released_cb) ...@@ -730,18 +774,20 @@ void SIPAccount::doUnregister(std::function<void(bool)> released_cb)
} }
try { try {
sendUnregister(released_cb); sendUnregister();
} catch (const VoipLinkException &e) { } catch (const VoipLinkException &e) {
ERROR("doUnregister %s", e.what()); ERROR("doUnregister %s", e.what());
setTransport();
if (released_cb)
released_cb(false);
} }
// remove the transport from the account
if (transport_)
setTransport();
if (released_cb)
released_cb(true);
} }
void SIPAccount::startKeepAliveTimer() void SIPAccount::startKeepAliveTimer()
{ {
if (isTlsEnabled()) if (isTlsEnabled())
return; return;
...@@ -794,13 +840,6 @@ SIPAccount::sendRegister() ...@@ -794,13 +840,6 @@ SIPAccount::sendRegister()
return; return;
} }
try {
link_->sipTransport->createSipTransport(*this);
} catch (const std::runtime_error &e) {
ERROR("%s", e.what());
throw VoipLinkException("Could not create or acquire SIP transport");
}
setRegister(true); setRegister(true);
setRegistrationState(RegistrationState::TRYING); setRegistrationState(RegistrationState::TRYING);
...@@ -826,10 +865,10 @@ SIPAccount::sendRegister() ...@@ -826,10 +865,10 @@ SIPAccount::sendRegister()
pjsip_host_port *via = getViaAddr(); pjsip_host_port *via = getViaAddr();
DEBUG("Setting VIA sent-by to %.*s:%d", via->host.slen, via->host.ptr, via->port); DEBUG("Setting VIA sent-by to %.*s:%d", via->host.slen, via->host.ptr, via->port);
if (pjsip_regc_set_via_sent_by(regc, via, transport_) != PJ_SUCCESS) if (pjsip_regc_set_via_sent_by(regc, via, transport_->get()) != PJ_SUCCESS)
throw VoipLinkException("Unable to set the \"sent-by\" field"); throw VoipLinkException("Unable to set the \"sent-by\" field");
} else if (isStunEnabled()) { } else if (isStunEnabled()) {
if (pjsip_regc_set_via_sent_by(regc, getViaAddr(), transport_) != PJ_SUCCESS) if (pjsip_regc_set_via_sent_by(regc, getViaAddr(), transport_->get()) != PJ_SUCCESS)
throw VoipLinkException("Unable to set the \"sent-by\" field"); throw VoipLinkException("Unable to set the \"sent-by\" field");
} }
} }
...@@ -861,7 +900,7 @@ SIPAccount::sendRegister() ...@@ -861,7 +900,7 @@ SIPAccount::sendRegister()
if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS) if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
throw VoipLinkException("Unable to initialize transaction data for account registration"); throw VoipLinkException("Unable to initialize transaction data for account registration");
const pjsip_tpselector tp_sel = SipTransport::getTransportSelector(transport_); const pjsip_tpselector tp_sel = getTransportSelector();
if (pjsip_regc_set_transport(regc, &tp_sel) != PJ_SUCCESS) if (pjsip_regc_set_transport(regc, &tp_sel) != PJ_SUCCESS)
throw VoipLinkException("Unable to set transport"); throw VoipLinkException("Unable to set transport");
...@@ -872,7 +911,6 @@ SIPAccount::sendRegister() ...@@ -872,7 +911,6 @@ SIPAccount::sendRegister()
} }
setRegistrationInfo(regc); setRegistrationInfo(regc);
link_->sipTransport->cleanupTransports();
} }
void void
...@@ -972,13 +1010,11 @@ SIPAccount::onRegister(pjsip_regc_cbparam *param) ...@@ -972,13 +1010,11 @@ SIPAccount::onRegister(pjsip_regc_cbparam *param)
} }
void void
SIPAccount::sendUnregister(std::function<void(bool)> released_cb) SIPAccount::sendUnregister()
{ {
// This may occurs if account failed to register and is in state INVALID // This may occurs if account failed to register and is in state INVALID
if (!isRegistered()) { if (!isRegistered()) {
setRegistrationState(RegistrationState::UNREGISTERED); setRegistrationState(RegistrationState::UNREGISTERED);
if (released_cb)
released_cb(true);
return; return;
} }
...@@ -1000,13 +1036,6 @@ SIPAccount::sendUnregister(std::function<void(bool)> released_cb) ...@@ -1000,13 +1036,6 @@ SIPAccount::sendUnregister(std::function<void(bool)> released_cb)
} }
setRegister(false); setRegister(false);
// remove the transport from the account
auto transport = getTransport();
setTransport();
link_->sipTransport->cleanupTransports();
if (released_cb)
link_->sipTransport->waitForReleased(transport, released_cb);
} }
#if HAVE_TLS #if HAVE_TLS
...@@ -1243,7 +1272,7 @@ std::string SIPAccount::getServerUri() const ...@@ -1243,7 +1272,7 @@ std::string SIPAccount::getServerUri() const
pj_str_t pj_str_t
SIPAccount::getContactHeader() SIPAccount::getContactHeader()
{ {
if (transport_ == nullptr) if (!transport_)
ERROR("Transport not created yet"); ERROR("Transport not created yet");
if (contact_.slen and contactOverwritten_) if (contact_.slen and contactOverwritten_)
...@@ -1259,14 +1288,22 @@ SIPAccount::getContactHeader() ...@@ -1259,14 +1288,22 @@ SIPAccount::getContactHeader()
std::string address; std::string address;
pj_uint16_t port; pj_uint16_t port;
link_->sipTransport->findLocalAddressFromTransport(transport_, transportType, hostname_, address, port); link_->sipTransport->findLocalAddressFromTransport(
transport_ ? transport_->get() : nullptr,
transportType,
hostname_,
address, port);
if (not publishedSameasLocal_) { if (not publishedSameasLocal_) {
address = publishedIpAddress_; address = publishedIpAddress_;
port = publishedPort_; port = publishedPort_;
DEBUG("Using published address %s and port %d", address.c_str(), port); DEBUG("Using published address %s and port %d", address.c_str(), port);
} else if (stunEnabled_) { } else if (stunEnabled_) {
link_->sipTransport->findLocalAddressFromSTUN(transport_, &stunServerName_, stunPort_, address, port); link_->sipTransport->findLocalAddressFromSTUN(
transport_ ? transport_->get() : nullptr,
&stunServerName_,
stunPort_,
address, port);
setPublishedAddress(address); setPublishedAddress(address);
publishedPort_ = port; publishedPort_ = port;
usePublishedAddressPortInVIA(); usePublishedAddressPortInVIA();
...@@ -1317,7 +1354,11 @@ SIPAccount::getHostPortFromSTUN(pj_pool_t *pool) ...@@ -1317,7 +1354,11 @@ SIPAccount::getHostPortFromSTUN(pj_pool_t *pool)
{ {
std::string addr; std::string addr;
pj_uint16_t port; pj_uint16_t port;
link_->sipTransport->findLocalAddressFromSTUN(transport_, &stunServerName_, stunPort_, addr, port); link_->sipTransport->findLocalAddressFromSTUN(
transport_ ? transport_->get() : nullptr,
&stunServerName_,
stunPort_,
addr, port);
pjsip_host_port result; pjsip_host_port result;
pj_strdup2(pool, &result.host, addr.c_str()); pj_strdup2(pool, &result.host, addr.c_str());
result.host.slen = addr.length(); result.host.slen = addr.length();
...@@ -1380,19 +1421,13 @@ computeMd5HashFromCredential(const std::string& username, ...@@ -1380,19 +1421,13 @@ computeMd5HashFromCredential(const std::string& username,
} }
void void
SIPAccount::setTransport(pjsip_transport* transport, pjsip_tpfactory* lis) SIPAccount::setTransport(const std::shared_ptr<SipTransport>& t)
{ {
// release old transport if (transport_ == t)
if (transport_ && transport_ != transport) { return;
if (regc_) if (transport_ && regc_)
pjsip_regc_release_transport(regc_); pjsip_regc_release_transport(regc_);
pjsip_transport_dec_ref(transport_); SIPAccountBase::setTransport(t);
}
if (tlsListener_ && tlsListener_ != lis)
tlsListener_->destroy(tlsListener_);
// set new transport
transport_ = transport;
tlsListener_ = lis;
} }
void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::string> >& creds) void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::string> >& creds)
...@@ -1794,7 +1829,10 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool) ...@@ -1794,7 +1829,10 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool)
pj_assert(contactRewriteMethod_ == 1 or contactRewriteMethod_ == 2); pj_assert(contactRewriteMethod_ == 1 or contactRewriteMethod_ == 2);
std::shared_ptr<SipTransport> tmp_tp {nullptr};
if (contactRewriteMethod_ == 1) { if (contactRewriteMethod_ == 1) {
/* Save transport in case we're gonna reuse it */
tmp_tp = transport_;
/* Unregister current contact */ /* Unregister current contact */
sendUnregister(); sendUnregister();
destroyRegistrationInfo(); destroyRegistrationInfo();
...@@ -1841,6 +1879,7 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool) ...@@ -1841,6 +1879,7 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool)
/* Unregister old contact */ /* Unregister old contact */
try { try {
tmp_tp = transport_;
sendUnregister(); sendUnregister();
} catch (const VoipLinkException &e) { } catch (const VoipLinkException &e) {
ERROR("%s", e.what()); ERROR("%s", e.what());
......
...@@ -174,7 +174,7 @@ class SIPAccount : public SIPAccountBase { ...@@ -174,7 +174,7 @@ class SIPAccount : public SIPAccountBase {
* Build and send SIP unregistration request * Build and send SIP unregistration request
* @param destroy_transport If true, attempt to destroy the transport. * @param destroy_transport If true, attempt to destroy the transport.
*/ */
void sendUnregister(std::function<void(bool)> cb = std::function<void(bool)>()); void sendUnregister();
const pjsip_cred_info* getCredInfo() const { const pjsip_cred_info* getCredInfo() const {
return cred_.data(); return cred_.data();
...@@ -405,7 +405,7 @@ class SIPAccount : public SIPAccountBase { ...@@ -405,7 +405,7 @@ class SIPAccount : public SIPAccountBase {
return keepAliveEnabled_; return keepAliveEnabled_;
} }
void setTransport(pjsip_transport* transport = nullptr, pjsip_tpfactory* lis = nullptr); virtual void setTransport(const std::shared_ptr<SipTransport>& = nullptr);
/* Returns true if the username and/or hostname match this account */ /* Returns true if the username and/or hostname match this account */
MatchRank matches(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const; MatchRank matches(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
......
...@@ -235,19 +235,37 @@ SIPAccountBase::getAccountDetails() const ...@@ -235,19 +235,37 @@ SIPAccountBase::getAccountDetails() const
return a; return a;
} }
void
SIPAccountBase::onTransportStateChanged(pjsip_transport_state state, const pjsip_transport_state_info *info)
{
DEBUG("Transport state changed to %s for account %s !", SipTransport::stateToStr(state), accountID_.c_str());
if (!SipTransport::isAlive(transport_, state)) {
if (info) {
char err_msg[128];
err_msg[0] = '\0';
pj_str_t descr = pj_strerror(info->status, err_msg, sizeof(err_msg));
ERROR("Transport disconnected: %.*s", descr.slen, descr.ptr);
}
setRegistrationState(RegistrationState::ERROR_GENERIC);
setTransport();
}
}
void void
SIPAccountBase::setTransport(pjsip_transport* transport, pjsip_tpfactory* lis) SIPAccountBase::setTransport(const std::shared_ptr<SipTransport>& t)
{ {
// release old transport using namespace std::placeholders;
if (transport_ && transport_ != transport) { if (t == transport_)
pjsip_transport_dec_ref(transport_); return;
if (transport_) {
DEBUG("Removing transport from account");
transport_->removeStateListener(reinterpret_cast<uintptr_t>(this));
} }
if (tlsListener_ && tlsListener_ != lis)
tlsListener_->destroy(tlsListener_); transport_ = t;
// set new transport
transport_ = transport; if (transport_)
tlsListener_ = lis; transport_->addStateListener(reinterpret_cast<uintptr_t>(this), std::bind(&SIPAccountBase::onTransportStateChanged, this, _1, _2));
} }
// returns even number in range [lower, upper] // returns even number in range [lower, upper]
......
...@@ -126,8 +126,9 @@ public: ...@@ -126,8 +126,9 @@ public:
*/ */
SIPAccountBase(const std::string& accountID); SIPAccountBase(const std::string& accountID);
virtual ~SIPAccountBase() = default; virtual ~SIPAccountBase() {
setTransport();
}
/** /**
* Create incoming SIPCall. * Create incoming SIPCall.
...@@ -265,12 +266,12 @@ public: ...@@ -265,12 +266,12 @@ public:
#endif #endif
static void releasePort(uint16_t port); static void releasePort(uint16_t port);
inline pjsip_transport* getTransport() { virtual void setTransport(const std::shared_ptr<SipTransport>& = nullptr);
inline const std::shared_ptr<SipTransport>& getTransport() {
return transport_; return transport_;
} }
virtual void setTransport(pjsip_transport* transport = nullptr, pjsip_tpfactory* lis = nullptr);
inline pjsip_transport_type_e getTransportType() const { inline pjsip_transport_type_e getTransportType() const {
return transportType_; return transportType_;
} }
...@@ -279,10 +280,11 @@ public: ...@@ -279,10 +280,11 @@ public:
* Shortcut for SipTransport::getTransportSelector(account.getTransport()). * Shortcut for SipTransport::getTransportSelector(account.getTransport()).
*/ */
inline pjsip_tpselector getTransportSelector() { inline pjsip_tpselector getTransportSelector() {
return SipTransport::getTransportSelector(transport_); if (!transport_)
return SipTransportBroker::getTransportSelector(nullptr);
return SipTransportBroker::getTransportSelector(transport_->get());
} }
protected: protected:
virtual void serialize(YAML::Emitter &out); virtual void serialize(YAML::Emitter &out);
virtual void unserialize(const YAML::Node &node); virtual void unserialize(const YAML::Node &node);
...@@ -292,14 +294,19 @@ protected: ...@@ -292,14 +294,19 @@ protected:
virtual std::map<std::string, std::string> getAccountDetails() const; virtual std::map<std::string, std::string> getAccountDetails() const;
/** /**
* Voice over IP Link contains a listener thread and calls * Callback called by the transport layer when the registration
* transport state changes.
*/ */
std::shared_ptr<SIPVoIPLink> link_; virtual void onTransportStateChanged(pjsip_transport_state state, const pjsip_transport_state_info *info);
/** /**
* Pointer to the transport used by this acccount * Voice over IP Link contains a listener thread and calls
*/ */
pjsip_transport* transport_ {nullptr}; std::shared_ptr<SIPVoIPLink> link_;
std::shared_ptr<SipTransport> transport_ {};
std::shared_ptr<TlsListener> tlsListener_ {};
/** /**
* Transport type used for this sip account. Currently supported types: * Transport type used for this sip account. Currently supported types:
...@@ -337,11 +344,6 @@ protected: ...@@ -337,11 +344,6 @@ protected:
*/ */
pj_uint16_t publishedPort_ {DEFAULT_SIP_PORT}; pj_uint16_t publishedPort_ {DEFAULT_SIP_PORT};
/**
* If a TLS tranport, pointer to the tls listener.
*/
pjsip_tpfactory* tlsListener_ {nullptr};
/** /**
* The global TLS listener port which can be configured through the IP2IP_PROFILE * The global TLS listener port which can be configured through the IP2IP_PROFILE
*/ */
......
...@@ -57,6 +57,7 @@ struct pjsip_inv_session; ...@@ -57,6 +57,7 @@ struct pjsip_inv_session;
class Sdp; class Sdp;
class SIPAccountBase; class SIPAccountBase;
class SipTransport;
/** /**
* @file sipcall.h * @file sipcall.h
...@@ -122,6 +123,14 @@ class SIPCall : public Call ...@@ -122,6 +123,14 @@ class SIPCall : public Call
void setContactHeader(pj_str_t *contact); void setContactHeader(pj_str_t *contact);
void setTransport(const std::shared_ptr<SipTransport>& t) {
transport_ = t;
}
inline const std::shared_ptr<SipTransport>& getTransport() {
return transport_;
}
void sendSIPInfo(const char *const body, const char *const subtype); void sendSIPInfo(const char *const body, const char *const subtype);
void answer(); void answer();
...@@ -199,6 +208,13 @@ class SIPCall : public Call ...@@ -199,6 +208,13 @@ class SIPCall : public Call
sfl_video::VideoRtpSession videortp_; sfl_video::VideoRtpSession videortp_;
#endif #endif
/**
* Hold the transport used for SIP communication.
* Will be different from the account registration transport for
* non-IP2IP calls.
*/
std::shared_ptr<SipTransport> transport_ {};
/** /**
* The pool to allocate memory, released once call hang up * The pool to allocate memory, released once call hang up
*/ */
......
This diff is collapsed.
This diff is collapsed.
...@@ -289,7 +289,7 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -289,7 +289,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
auto call = sipaccount->newIncomingCall(Manager::instance().getNewCallID()); auto call = sipaccount->newIncomingCall(Manager::instance().getNewCallID());
// FIXME : for now, use the same address family as the SIP tranport // FIXME : for now, use the same address family as the SIP transport
auto family = pjsip_transport_type_get_af(sipaccount->getTransportType()); auto family = pjsip_transport_type_get_af(sipaccount->getTransportType());
IpAddr addrToUse = ip_utils::getInterfaceAddr(sipaccount->getLocalInterface(), family); IpAddr addrToUse = ip_utils::getInterfaceAddr(sipaccount->getLocalInterface(), family);
...@@ -297,8 +297,6 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -297,8 +297,6 @@ transaction_request_cb(pjsip_rx_data *rdata)
IpAddr addrSdp = sipaccount->isStunEnabled() or (not sipaccount->getPublishedSameasLocal()) IpAddr addrSdp = sipaccount->isStunEnabled() or (not sipaccount->getPublishedSameasLocal())
? sipaccount->getPublishedIpAddress() : addrToUse; ? sipaccount->getPublishedIpAddress() : addrToUse;
pjsip_tpselector tp_sel = sipaccount->getTransportSelector();
char tmp[PJSIP_MAX_URL_SIZE]; char tmp[PJSIP_MAX_URL_SIZE];
size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE); size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
std::string peerNumber(tmp, std::min(length, sizeof tmp)); std::string peerNumber(tmp, std::min(length, sizeof tmp));
...@@ -307,8 +305,19 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -307,8 +305,19 @@ transaction_request_cb(pjsip_rx_data *rdata)
if (not remote_user.empty() and not remote_hostname.empty()) if (not remote_user.empty() and not remote_hostname.empty())
peerNumber = remote_user + "@" + remote_hostname; peerNumber = remote_user + "@" + remote_hostname;
//DEBUG("transaction_request_cb viaHostname %s toUsername %s addrToUse %s addrSdp %s peerNumber: %s" , // DEBUG("transaction_request_cb viaHostname %s toUsername %s addrToUse %s addrSdp %s peerNumber: %s" ,
//viaHostname.c_str(), toUsername.c_str(), addrToUse.toString().c_str(), addrSdp.toString().c_str(), peerNumber.c_str()); // viaHostname.c_str(), toUsername.c_str(), addrToUse.toString().c_str(), addrSdp.toString().c_str(), peerNumber.c_str());
auto transport = getSIPVoIPLink()->sipTransport->findTransport(rdata->tp_info.transport);
if (!transport) {
transport = sipaccount->getTransport();
if (!transport) {
ERROR("No suitable transport to answer this call.");
return PJ_FALSE;
} else {
WARN("Using transport from account.");
}
}
call->setConnectionState(Call::PROGRESSING); call->setConnectionState(Call::PROGRESSING);
call->setPeerNumber(peerNumber); call->setPeerNumber(peerNumber);
...@@ -317,6 +326,7 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -317,6 +326,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
call->setCallMediaLocal(addrToUse); call->setCallMediaLocal(addrToUse);
call->getLocalSDP().setPublishedIP(addrSdp); call->getLocalSDP().setPublishedIP(addrSdp);
call->getAudioRtp().initConfig(); call->getAudioRtp().initConfig();
call->setTransport(transport);
try { try {
call->getAudioRtp().initSession(); call->getAudioRtp().initSession();
...@@ -381,6 +391,7 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -381,6 +391,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
return PJ_FALSE; return PJ_FALSE;
} }
pjsip_tpselector tp_sel = SipTransportBroker::getTransportSelector(transport->get());
if (!dialog or pjsip_dlg_set_transport(dialog, &tp_sel) != PJ_SUCCESS) { if (!dialog or pjsip_dlg_set_transport(dialog, &tp_sel) != PJ_SUCCESS) {
ERROR("Could not set transport for dialog"); ERROR("Could not set transport for dialog");
return PJ_FALSE; return PJ_FALSE;
...@@ -492,11 +503,6 @@ pj_pool_t* SIPVoIPLink::getPool() const ...@@ -492,11 +503,6 @@ pj_pool_t* SIPVoIPLink::getPool() const
} }
SIPVoIPLink::SIPVoIPLink() SIPVoIPLink::SIPVoIPLink()
: sipTransport()