Commit cd4d4488 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #25295: audiortp: get ports from STUN

parent 9bba9489
......@@ -126,7 +126,7 @@ void AudioRtpFactory::initSession()
rtpSession_ = new AudioSymmetricRtpSession(*ca_);
}
std::pair<int, int>
std::vector<long>
AudioRtpFactory::getSocketDescriptors() const
{
return rtpSession_->getSocketDescriptors();
......
......@@ -66,7 +66,7 @@ class AudioRtpFactory {
AudioRtpFactory(SIPCall *ca);
~AudioRtpFactory();
std::pair<int, int>
std::vector<long>
getSocketDescriptors() const;
void initConfig();
......
......@@ -73,7 +73,7 @@ class AudioRtpSession : public AudioRtpRecordHandler {
virtual std::vector<uint8> getLocalMasterSalt() const = 0;
virtual std::pair<unsigned, unsigned>
virtual std::vector<long>
getSocketDescriptors() const = 0;
private:
......
......@@ -47,10 +47,13 @@ AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall &call) :
audioRtpRecord_.callId_ = call_.getCallId();
}
std::pair<unsigned, unsigned>
std::vector<long>
AudioSymmetricRtpSession::getSocketDescriptors() const
{
return std::pair<unsigned, unsigned>(dso->getRecvSocket(), cso->getRecvSocket());
std::vector<long> result;
result.push_back(dso->getRecvSocket());
result.push_back(cso->getRecvSocket());
return result;
}
void AudioSymmetricRtpSession::startReceiveThread()
......
......@@ -61,7 +61,7 @@ class AudioSymmetricRtpSession : public ost::SymmetricRTPSession, public AudioRt
*/
AudioSymmetricRtpSession(SIPCall &call);
std::pair<unsigned, unsigned>
std::vector<long>
getSocketDescriptors() const;
virtual bool onRTPPacketRecv(ost::IncomingRTPPkt& pkt) {
......
......@@ -57,10 +57,13 @@ AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string &zidFilename
audioRtpRecord_.callId_ = call_.getCallId();
}
std::pair<unsigned, unsigned>
std::vector<long>
AudioZrtpSession::getSocketDescriptors() const
{
return std::pair<unsigned, unsigned>(dso->getRecvSocket(), cso->getRecvSocket());
std::vector<long> result;
result.push_back(dso->getRecvSocket());
result.push_back(cso->getRecvSocket());
return result;
}
void AudioZrtpSession::initializeZid()
......
......@@ -60,7 +60,7 @@ class AudioZrtpSession :
public:
AudioZrtpSession(SIPCall &call, const std::string& zidFilename);
std::pair<unsigned, unsigned>
std::vector<long>
getSocketDescriptors() const;
virtual bool onRTPPacketRecv(ost::IncomingRTPPkt &pkt) {
......
......@@ -62,8 +62,10 @@ Sdp::Sdp(pj_pool_t *pool)
, sessionVideoMedia_()
, localIpAddr_()
, remoteIpAddr_()
, localAudioPort_(0)
, localVideoPort_(0)
, localAudioDataPort_(0)
, localAudioControlPort_(0)
, localVideoDataPort_(0)
, localVideoControlPort_(0)
, remoteAudioPort_(0)
, remoteVideoPort_(0)
, zrtpHelloHash_()
......@@ -205,7 +207,7 @@ Sdp::setMediaDescriptorLines(bool audio)
med->desc.media = audio ? pj_str((char*) "audio") : pj_str((char*) "video");
med->desc.port_count = 1;
med->desc.port = audio ? localAudioPort_ : localVideoPort_;
med->desc.port = audio ? localAudioDataPort_ : localVideoDataPort_;
// in case of sdes, media are tagged as "RTP/SAVP", RTP/AVP elsewhere
med->desc.transport = pj_str(srtpCrypto_.empty() ? (char*) "RTP/AVP" : (char*) "RTP/SAVP");
......@@ -283,10 +285,8 @@ Sdp::setMediaDescriptorLines(bool audio)
void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
{
// FIXME: get this from CCRTP directly, don't just assume that the RTCP port is
// RTP + 1
std::ostringstream os;
os << localIpAddr_ << ":" << (localAudioPort_ + 1);
os << localIpAddr_ << ":" << localAudioControlPort_;
const std::string str(os.str());
pj_str_t input_str = pj_str((char*) str.c_str());
pj_sockaddr outputAddr;
......@@ -300,6 +300,15 @@ void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
pjmedia_sdp_attr_add(&med->attr_count, med->attr, attr);
}
void
Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
{
localAudioDataPort_ = pj_ntohs(sockets[0].sin_port);
localAudioControlPort_ = pj_ntohs(sockets[1].sin_port);
localVideoDataPort_ = pj_ntohs(sockets[2].sin_port);
localVideoControlPort_ = pj_ntohs(sockets[3].sin_port);
}
void Sdp::setTelephoneEventRtpmap(pjmedia_sdp_media *med)
{
......
......@@ -163,13 +163,17 @@ class Sdp {
}
void setLocalPublishedAudioPort(int port) {
localAudioPort_ = port;
localAudioDataPort_ = port;
localAudioControlPort_ = port + 1;
}
void setLocalPublishedVideoPort (int port) {
localVideoPort_ = port;
localVideoDataPort_ = port;
localVideoControlPort_ = port + 1;
}
void updatePorts(const std::vector<pj_sockaddr_in> &sockets);
/**
* Return IP of destination
* @return const std:string The remote IP address
......@@ -203,7 +207,7 @@ class Sdp {
}
unsigned int getLocalVideoPort() const {
return localVideoPort_;
return localVideoDataPort_;
}
void addAttributeToLocalAudioMedia(const char *attr);
......@@ -308,8 +312,10 @@ class Sdp {
std::string localIpAddr_;
std::string remoteIpAddr_;
int localAudioPort_;
int localVideoPort_;
int localAudioDataPort_;
int localAudioControlPort_;
int localVideoDataPort_;
int localVideoControlPort_;
unsigned int remoteAudioPort_;
unsigned int remoteVideoPort_;
......
......@@ -461,6 +461,27 @@ pjsip_tpselector *SipTransport::createTransportSelector(pjsip_transport *transpo
return tp;
}
std::vector<pj_sockaddr_in>
SipTransport::getSTUNAddresses(const SIPAccount &account,
std::vector<long> &socketDescriptors) const
{
const pj_str_t serverName = account.getStunServerName();
const pj_uint16_t port = account.getStunPort();
std::vector<pj_sockaddr_in> result(socketDescriptors.size());
if (pjstun_get_mapped_addr(&cp_->factory, socketDescriptors.size(), &socketDescriptors[0],
&serverName, port, &serverName, port, &result[0]) != PJ_SUCCESS)
throw std::runtime_error("Can't contact STUN server");
for (std::vector<pj_sockaddr_in>::const_iterator it = result.begin();
it != result.end(); ++it)
WARN("STUN PORTS: %ld", pj_ntohs(it->sin_port));
return result;
}
pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
{
#define RETURN_IF_STUN_FAIL(A, M, ...) \
......
......@@ -112,6 +112,13 @@ class SipTransport {
*/
void shutdownSTUNResolver(SIPAccount &account);
/**
* This function returns a list of STUN mapped sockets for
* a given set of socket file descriptors */
std::vector<pj_sockaddr_in>
getSTUNAddresses(const SIPAccount &account,
std::vector<long> &socks) const;
/**
* This function unset the transport for a given account.
*/
......
......@@ -189,6 +189,23 @@ pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
return PJ_FALSE;
}
void updateSDPFromSTUN(SIPCall &call, const SIPAccount &account, const SipTransport &transport)
{
std::vector<long> socketDescriptors(call.getAudioRtp().getSocketDescriptors());
try {
std::vector<pj_sockaddr_in> stunPorts(transport.getSTUNAddresses(account, socketDescriptors));
// FIXME: get video sockets
stunPorts.resize(4);
call.getLocalSDP()->updatePorts(stunPorts);
} catch (const std::runtime_error &e) {
ERROR("%s", e.what());
}
}
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
{
if (!rdata or !rdata->msg_info.msg) {
......@@ -310,6 +327,9 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
return PJ_FALSE;
}
if (account->isStunEnabled())
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
if (body and body->len > 0 and call->getAudioRtp().isSdesEnabled()) {
std::string sdpOffer(static_cast<const char*>(body->data), body->len);
size_t start = sdpOffer.find("a=crypto:");
......@@ -900,6 +920,10 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
try {
call->getAudioRtp().initConfig();
call->getAudioRtp().initSession();
if (account->isStunEnabled())
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
call->getAudioRtp().initLocalCryptoInfo();
call->getAudioRtp().start(audioCodecs);
} catch (...) {
......@@ -1100,6 +1124,13 @@ SIPVoIPLink::offhold(const std::string& id)
call->getAudioRtp().initConfig();
call->getAudioRtp().initSession();
const std::string account_id(call->getAccountId());
SIPAccount *account = Manager::instance().getSipAccount(account_id);
if (account and account->isStunEnabled())
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
call->getAudioRtp().restoreLocalContext();
call->getAudioRtp().initLocalCryptoInfoOnOffHold();
call->getAudioRtp().start(audioCodecs);
......@@ -1830,8 +1861,12 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
const std::string accountID = call->getAccountId();
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
if (sipaccount and sipaccount->getSrtpFallback())
if (sipaccount and sipaccount->getSrtpFallback()) {
call->getAudioRtp().initSession();
if (sipaccount->isStunEnabled())
updateSDPFromSTUN(*call, *sipaccount, SIPVoIPLink::instance()->sipTransport);
}
}
#endif // HAVE_SDES
......@@ -2255,13 +2290,8 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
// We only want to set ports to new values if they haven't been set
if (call->getLocalAudioPort() == 0) {
const unsigned callLocalAudioPort = getRandomEvenNumber(10500, 64998);
const unsigned int callLocalExternAudioPort = account->isStunEnabled()
? account->getStunPort()
: callLocalAudioPort;
call->setLocalAudioPort(callLocalAudioPort);
call->getLocalSDP()->setLocalPublishedAudioPort(callLocalExternAudioPort);
call->getLocalSDP()->setLocalPublishedAudioPort(callLocalAudioPort);
}
call->setLocalIp(localIP);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment