mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
* #25295: audiortp: get ports from STUN
This commit is contained in:
@ -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);
|
||||
|
Reference in New Issue
Block a user