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()
// cache this often used account using a weak_ptr
ip2ip_account_ = createAccount(SIPAccount::ACCOUNT_TYPE,
SIPAccount::IP2IP_PROFILE);
SIPVoIPLink::loadIP2IPSettings();
}
......@@ -192,6 +192,14 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl)
toUri = getToUri(to);
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());
}
else {
......@@ -204,6 +212,7 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl)
else
toUri = getToUri(to);
call->setTransport(transport_);
// FIXME : for now, use the same address family as the SIP tranport
family = pjsip_transport_type_get_af(getTransportType());
......@@ -328,7 +337,7 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
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) {
ERROR("Unable to associate transport for invite session dialog");
return false;
......@@ -687,9 +696,21 @@ void SIPAccount::doRegister()
transportType_ = IPv6 ? PJSIP_TRANSPORT_TLS6 : PJSIP_TRANSPORT_TLS;
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
#endif
{
tlsListener_.reset();
transportType_ = IPv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP;
}
......@@ -703,14 +724,36 @@ void SIPAccount::doRegister()
// In our definition of the ip2ip profile (aka Direct IP Calls),
// 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;
}
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();
} catch (const VoipLinkException &e) {
ERROR("%s", e.what());
setRegistrationState(RegistrationState::ERROR_GENERIC);
return;
}
#ifdef SFL_PRESENCE
......@@ -723,6 +766,7 @@ void SIPAccount::doRegister()
void SIPAccount::doUnregister(std::function<void(bool)> released_cb)
{
tlsListener_.reset();
if (isIP2IP()) {
if (released_cb)
released_cb(false);
......@@ -730,18 +774,20 @@ void SIPAccount::doUnregister(std::function<void(bool)> released_cb)
}
try {
sendUnregister(released_cb);
sendUnregister();
} catch (const VoipLinkException &e) {
ERROR("doUnregister %s", e.what());
}
// remove the transport from the account
if (transport_)
setTransport();
if (released_cb)
released_cb(false);
}
released_cb(true);
}
void SIPAccount::startKeepAliveTimer()
{
if (isTlsEnabled())
return;
......@@ -794,13 +840,6 @@ SIPAccount::sendRegister()
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);
setRegistrationState(RegistrationState::TRYING);
......@@ -826,10 +865,10 @@ SIPAccount::sendRegister()
pjsip_host_port *via = getViaAddr();
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");
} 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");
}
}
......@@ -861,7 +900,7 @@ SIPAccount::sendRegister()
if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
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)
throw VoipLinkException("Unable to set transport");
......@@ -872,7 +911,6 @@ SIPAccount::sendRegister()
}
setRegistrationInfo(regc);
link_->sipTransport->cleanupTransports();
}
void
......@@ -972,13 +1010,11 @@ SIPAccount::onRegister(pjsip_regc_cbparam *param)
}
void
SIPAccount::sendUnregister(std::function<void(bool)> released_cb)
SIPAccount::sendUnregister()
{
// This may occurs if account failed to register and is in state INVALID
if (!isRegistered()) {
setRegistrationState(RegistrationState::UNREGISTERED);
if (released_cb)
released_cb(true);
return;
}
......@@ -1000,13 +1036,6 @@ SIPAccount::sendUnregister(std::function<void(bool)> released_cb)
}
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
......@@ -1243,7 +1272,7 @@ std::string SIPAccount::getServerUri() const
pj_str_t
SIPAccount::getContactHeader()
{
if (transport_ == nullptr)
if (!transport_)
ERROR("Transport not created yet");
if (contact_.slen and contactOverwritten_)
......@@ -1259,14 +1288,22 @@ SIPAccount::getContactHeader()
std::string address;
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_) {
address = publishedIpAddress_;
port = publishedPort_;
DEBUG("Using published address %s and port %d", address.c_str(), port);
} else if (stunEnabled_) {
link_->sipTransport->findLocalAddressFromSTUN(transport_, &stunServerName_, stunPort_, address, port);
link_->sipTransport->findLocalAddressFromSTUN(
transport_ ? transport_->get() : nullptr,
&stunServerName_,
stunPort_,
address, port);
setPublishedAddress(address);
publishedPort_ = port;
usePublishedAddressPortInVIA();
......@@ -1317,7 +1354,11 @@ SIPAccount::getHostPortFromSTUN(pj_pool_t *pool)
{
std::string addr;
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;
pj_strdup2(pool, &result.host, addr.c_str());
result.host.slen = addr.length();
......@@ -1380,19 +1421,13 @@ computeMd5HashFromCredential(const std::string& username,
}
void
SIPAccount::setTransport(pjsip_transport* transport, pjsip_tpfactory* lis)
SIPAccount::setTransport(const std::shared_ptr<SipTransport>& t)
{
// release old transport
if (transport_ && transport_ != transport) {
if (regc_)
if (transport_ == t)
return;
if (transport_ && regc_)
pjsip_regc_release_transport(regc_);
pjsip_transport_dec_ref(transport_);
}
if (tlsListener_ && tlsListener_ != lis)
tlsListener_->destroy(tlsListener_);
// set new transport
transport_ = transport;
tlsListener_ = lis;
SIPAccountBase::setTransport(t);
}
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)
pj_assert(contactRewriteMethod_ == 1 or contactRewriteMethod_ == 2);
std::shared_ptr<SipTransport> tmp_tp {nullptr};
if (contactRewriteMethod_ == 1) {
/* Save transport in case we're gonna reuse it */
tmp_tp = transport_;
/* Unregister current contact */
sendUnregister();
destroyRegistrationInfo();
......@@ -1841,6 +1879,7 @@ SIPAccount::checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool)
/* Unregister old contact */
try {
tmp_tp = transport_;
sendUnregister();
} catch (const VoipLinkException &e) {
ERROR("%s", e.what());
......
......@@ -174,7 +174,7 @@ class SIPAccount : public SIPAccountBase {
* Build and send SIP unregistration request
* @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 {
return cred_.data();
......@@ -405,7 +405,7 @@ class SIPAccount : public SIPAccountBase {
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 */
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
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
SIPAccountBase::setTransport(pjsip_transport* transport, pjsip_tpfactory* lis)
SIPAccountBase::setTransport(const std::shared_ptr<SipTransport>& t)
{
// release old transport
if (transport_ && transport_ != transport) {
pjsip_transport_dec_ref(transport_);
using namespace std::placeholders;
if (t == transport_)
return;
if (transport_) {
DEBUG("Removing transport from account");
transport_->removeStateListener(reinterpret_cast<uintptr_t>(this));
}
if (tlsListener_ && tlsListener_ != lis)
tlsListener_->destroy(tlsListener_);
// set new transport
transport_ = transport;
tlsListener_ = lis;
transport_ = t;
if (transport_)
transport_->addStateListener(reinterpret_cast<uintptr_t>(this), std::bind(&SIPAccountBase::onTransportStateChanged, this, _1, _2));
}
// returns even number in range [lower, upper]
......
......@@ -126,8 +126,9 @@ public:
*/
SIPAccountBase(const std::string& accountID);
virtual ~SIPAccountBase() = default;
virtual ~SIPAccountBase() {
setTransport();
}
/**
* Create incoming SIPCall.
......@@ -265,12 +266,12 @@ public:
#endif
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_;
}
virtual void setTransport(pjsip_transport* transport = nullptr, pjsip_tpfactory* lis = nullptr);
inline pjsip_transport_type_e getTransportType() const {
return transportType_;
}
......@@ -279,10 +280,11 @@ public:
* Shortcut for SipTransport::getTransportSelector(account.getTransport()).
*/
inline pjsip_tpselector getTransportSelector() {
return SipTransport::getTransportSelector(transport_);
if (!transport_)
return SipTransportBroker::getTransportSelector(nullptr);
return SipTransportBroker::getTransportSelector(transport_->get());
}
protected:
virtual void serialize(YAML::Emitter &out);
virtual void unserialize(const YAML::Node &node);
......@@ -292,14 +294,19 @@ protected:
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:
......@@ -337,11 +344,6 @@ protected:
*/
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
*/
......
......@@ -57,6 +57,7 @@ struct pjsip_inv_session;
class Sdp;
class SIPAccountBase;
class SipTransport;
/**
* @file sipcall.h
......@@ -122,6 +123,14 @@ class SIPCall : public Call
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 answer();
......@@ -199,6 +208,13 @@ class SIPCall : public Call
sfl_video::VideoRtpSession videortp_;
#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
*/
......
This diff is collapsed.
......@@ -40,10 +40,6 @@
#include "logger.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
#include <pjnath/stun_config.h>
#include <functional>
......@@ -59,18 +55,124 @@
class SIPAccountBase;
struct SipTransportDescr
{
SipTransportDescr() {}
SipTransportDescr(pjsip_transport_type_e t)
: type(t), listenerPort(pjsip_transport_get_default_port_for_type(t)) {}
SipTransportDescr(pjsip_transport_type_e t, pj_uint16_t port, std::string i)
: type(t), listenerPort(port), interface(i) {}
class SipTransport {
public:
SipTransport(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool);
~SipTransport();
static inline pjsip_transport_type_e actualType(pjsip_transport_type_e t) {
return (t == PJSIP_TRANSPORT_START_OTHER) ? PJSIP_TRANSPORT_UDP : t;
}
/**
* General Sip transport creation method according to the
* transport type specified in account settings
* @param account The account for which a transport must be created.
inline bool operator==(SipTransportDescr const& o) const {
return actualType(type) == actualType(o.type)
&& listenerPort == o.listenerPort
&& interface == o.interface;
}
inline bool operator<(SipTransportDescr const& o) const {
return actualType(type) < actualType(o.type)
|| listenerPort < o.listenerPort
|| std::hash<std::string>()(interface) < std::hash<std::string>()(o.interface);
}
std::string toString() const;
pjsip_transport_type_e type {PJSIP_TRANSPORT_UNSPECIFIED};
pj_uint16_t listenerPort {DEFAULT_SIP_PORT};
std::string interface {"default"};
};
struct SipTransport;
struct TlsListener
{
TlsListener() {}
TlsListener(pjsip_tpfactory* f) : listener(f) {}
virtual ~TlsListener() {
DEBUG("Destroying listener");
listener->destroy(listener);
}
pjsip_tpfactory* get() {
return listener;
}
private:
NON_COPYABLE(TlsListener);
pjsip_tpfactory* listener {nullptr};
};
typedef std::function<void(pjsip_transport_state, const pjsip_transport_state_info*)> SipTransportStateCallback;
struct SipTransport
{
SipTransport() {}
SipTransport(pjsip_transport*, const std::shared_ptr<TlsListener>& l = {});
virtual ~SipTransport();
static const char* stateToStr(pjsip_transport_state state);
void stateCallback(pjsip_transport_state state, const pjsip_transport_state_info *info) {
std::vector<SipTransportStateCallback> cbs {};
{
std::lock_guard<std::mutex> lock(stateListenersMutex_);
cbs.reserve(stateListeners.size());
for (auto& l : stateListeners)
cbs.push_back(l.second);
}
for (auto& cb : cbs)
cb(state, info);
}
pjsip_transport* get() {
return transport;
}
void addStateListener(uintptr_t lid, SipTransportStateCallback cb) {
std::lock_guard<std::mutex> lock(stateListenersMutex_);
stateListeners[lid] = cb;
}
bool removeStateListener(uintptr_t lid) {
std::lock_guard<std::mutex> lock(stateListenersMutex_);
auto it = stateListeners.find(lid);
if (it != stateListeners.end()) {
stateListeners.erase(it);
return true;
}
return false;
}
static bool isAlive(const std::shared_ptr<SipTransport>&, pjsip_transport_state state);
private:
NON_COPYABLE(SipTransport);
pjsip_transport* transport {nullptr};
std::shared_ptr<TlsListener> tlsListener {};
std::map<uintptr_t, SipTransportStateCallback> stateListeners {};
std::mutex stateListenersMutex_ {};
};
/**
* Manages the transports and receive callbacks from PJSIP
*/
void createSipTransport(SIPAccountBase &account);
class SipTransportBroker {
public:
SipTransportBroker(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool);
~SipTransportBroker();
std::shared_ptr<SipTransport> getUdpTransport(const SipTransportDescr&);
#if HAVE_TLS
std::shared_ptr<TlsListener> getTlsListener(const SipTransportDescr&, const pjsip_tls_setting*);
std::shared_ptr<SipTransport> getTlsTransport(const std::shared_ptr<TlsListener>&, const std::string& remoteSipUri);
#endif
std::shared_ptr<SipTransport> findTransport(pjsip_transport*);
/**
* Initialize the transport selector
......@@ -100,43 +202,16 @@ class SipTransport {
void findLocalAddressFromSTUN(pjsip_transport *transport, pj_str_t *stunServerName,
int stunPort, std::string &address, pj_uint16_t &port) const;
/**
* Go through the transport list and remove unused ones.
*/
void cleanupTransports();
/**
* Call released_cb(success) when transport tp is destroyed, making the
* socket available for a new similar transport.
* success is true if the transport is actually released.
* TODO: make this call non-blocking.
*/
void waitForReleased(pjsip_transport* tp, std::function<void(bool)> released_cb);
void waitForReleased(const SipTransportDescr& tp, std::function<void(bool)> released_cb);
private:
NON_COPYABLE(SipTransport);
#if HAVE_TLS
/**
* Create a connection oriented TLS transport and register to the specified remote address.
* First, initialize the TLS listener sole instance. This means that, for the momment, only one TLS transport
* is allowed to be created in the application. Any subsequent account attempting to
* register a new using this transport even if new settings are specified.
* @param the account that is creating the TLS transport
*/
pjsip_transport *
createTlsTransport(SIPAccountBase &account);
/**
* Create The default TLS listener which is global to the application. This means that
* only one TLS connection can be established for the momment.
* @param the SIPAccount for which we are creating the TLS listener
* @param IP protocol version to use, can be pj_AF_INET() or pj_AF_INET6()
* @return a pointer to the new listener
*/
pjsip_tpfactory *
createTlsListener(SIPAccountBase &account, pj_uint16_t family = pj_AF_UNSPEC());
#endif
private:
NON_COPYABLE(SipTransportBroker);
/**
* Create SIP UDP transport from account's setting
......@@ -144,33 +219,29 @@ class SipTransport {
* @param IP protocol version to use, can be pj_AF_INET() or pj_AF_INET6()
* @return a pointer to the new transport
*/
pjsip_transport *createUdpTransport(const std::string &interface,
pj_uint16_t port, pj_uint16_t family = pj_AF_UNSPEC());
std::shared_ptr<SipTransport> createUdpTransport(const SipTransportDescr&);
/**
* Go through the transport list and remove unused ones.
* Returns a list of LOCKED transports that have to be processed and unlocked.
*/
std::vector<pjsip_transport*> _cleanupTransports();
static void tp_state_callback(pjsip_transport*, pjsip_transport_state, const pjsip_transport_state_info*);
static void tp_state_callback(pjsip_transport *, pjsip_transport_state, const pjsip_transport_state_info *);
void transportStateChanged(pjsip_transport*, pjsip_transport_state, const pjsip_transport_state_info*);
void transportStateChanged(pjsip_transport* tp, pjsip_transport_state state, const pjsip_transport_state_info* info);
/**
* List of transports so we can bubble the events up.
*/
std::map<pjsip_transport*, std::weak_ptr<SipTransport>> transports_ {};
/**
* UDP Transports are stored in this map in order to retreive them in case
* Transports are stored in this map in order to retreive them in case
* several accounts would share the same port number.
*/
std::map<std::string, pjsip_transport*> transportMap_;
std::mutex transportMapMutex_;
std::condition_variable transportDestroyedCv_;
std::map<SipTransportDescr, pjsip_transport*> udpTransports_ {};
std::mutex transportMapMutex_ {};
std::condition_variable transportDestroyedCv_ {};
pj_caching_pool& cp_;
pj_pool_t& pool_;
pjsip_endpoint *endpt_;
};
void sip_strerror(pj_status_t code);
#endif // SIPTRANSPORT_H_
......@@ -289,7 +289,7 @@ transaction_request_cb(pjsip_rx_data *rdata)
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());
IpAddr addrToUse = ip_utils::getInterfaceAddr(sipaccount->getLocalInterface(), family);
......@@ -297,8 +297,6 @@ transaction_request_cb(pjsip_rx_data *rdata)
IpAddr addrSdp = sipaccount->isStunEnabled() or (not sipaccount->getPublishedSameasLocal())
? sipaccount->getPublishedIpAddress() : addrToUse;
pjsip_tpselector tp_sel = sipaccount->getTransportSelector();
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);
std::string peerNumber(tmp, std::min(length, sizeof tmp));
......@@ -307,8 +305,19 @@ transaction_request_cb(pjsip_rx_data *rdata)
if (not remote_user.empty() and not remote_hostname.empty())
peerNumber = remote_user + "@" + remote_hostname;
//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());