- fixes after review
This commit is contained in:
@@ -93,11 +93,13 @@ void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, Sdp
|
||||
// Check if SRTP suite is found already or not
|
||||
if (mSrtpSuite == SRTP_NONE)
|
||||
{
|
||||
// RFC 4568 requires a unique tag per crypto attribute; use the suite id.
|
||||
for (int suite = SRTP_AES_128_AUTH_80; suite <= SRTP_LAST; suite++)
|
||||
sdp.addAttribute("crypto", resip::Data(createCryptoAttribute((SrtpSuite)suite)));
|
||||
sdp.addAttribute("crypto", resip::Data(createCryptoAttribute((SrtpSuite)suite, suite)));
|
||||
}
|
||||
else
|
||||
sdp.addAttribute("crypto", resip::Data(createCryptoAttribute(mSrtpSuite)));
|
||||
// Answer/re-offer: echo the tag of the negotiated attribute.
|
||||
sdp.addAttribute("crypto", resip::Data(createCryptoAttribute(mSrtpSuite, mSrtpTag)));
|
||||
}
|
||||
|
||||
// Use CodecListPriority mCodecPriority adapter to work with codec priorities
|
||||
@@ -246,11 +248,13 @@ bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& m
|
||||
{
|
||||
const resip::Data& attr = *attrIter;
|
||||
ByteBuffer tempkey;
|
||||
SrtpSuite suite = processCryptoAttribute(attr, tempkey);
|
||||
if (suite > ss)
|
||||
int tag = 1;
|
||||
SrtpSuite suite = processCryptoAttribute(attr, tempkey, &tag);
|
||||
if (srtpSuiteStrength(suite) > srtpSuiteStrength(ss))
|
||||
{
|
||||
ss = suite;
|
||||
mSrtpSuite = suite;
|
||||
mSrtpTag = tag;
|
||||
key = tempkey;
|
||||
}
|
||||
}
|
||||
@@ -295,26 +299,30 @@ MT::PStream AudioProvider::activeStream()
|
||||
return mActiveStream;
|
||||
}
|
||||
|
||||
std::string AudioProvider::createCryptoAttribute(SrtpSuite suite)
|
||||
std::string AudioProvider::createCryptoAttribute(SrtpSuite suite, int tag)
|
||||
{
|
||||
if (!mActiveStream)
|
||||
return "";
|
||||
|
||||
// Print key to base64 string
|
||||
PByteBuffer keyBuffer = mActiveStream->srtp().outgoingKey(suite).first;
|
||||
if (!keyBuffer)
|
||||
return "";
|
||||
resip::Data d(keyBuffer->data(), keyBuffer->size());
|
||||
resip::Data keyText = d.base64encode();
|
||||
|
||||
return std::format("{} {} inline:{}", 1, toString(suite), keyText.c_str());
|
||||
return std::format("{} {} inline:{}", tag, toString(suite), keyText.c_str());
|
||||
}
|
||||
|
||||
SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key)
|
||||
SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key, int* tag)
|
||||
{
|
||||
int srtpTag = 0;
|
||||
char suite[64], keyChunk[256];
|
||||
int components = sscanf(value.c_str(), "%d %63s inline: %255s", &srtpTag, suite, keyChunk);
|
||||
if (components != 3)
|
||||
return SRTP_NONE;
|
||||
if (tag)
|
||||
*tag = srtpTag;
|
||||
|
||||
const char* delimiter = strchr(keyChunk, '|');
|
||||
resip::Data keyText;
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
void setupMirror(bool enable);
|
||||
|
||||
void configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag);
|
||||
static SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key);
|
||||
static SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key, int* tag = nullptr);
|
||||
|
||||
protected:
|
||||
// SDP's stream name
|
||||
@@ -93,6 +93,7 @@ protected:
|
||||
|
||||
unsigned mState;
|
||||
SrtpSuite mSrtpSuite;
|
||||
int mSrtpTag = 1; // RFC 4568 tag of the negotiated crypto attribute
|
||||
struct RemoteCodec
|
||||
{
|
||||
RemoteCodec(MT::Codec::Factory* factory, int payloadType)
|
||||
@@ -109,7 +110,7 @@ protected:
|
||||
MT::Stream::MediaObserver* mMediaObserver = nullptr;
|
||||
void* mMediaObserverTag = nullptr;
|
||||
|
||||
std::string createCryptoAttribute(SrtpSuite suite);
|
||||
std::string createCryptoAttribute(SrtpSuite suite, int tag);
|
||||
void findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs);
|
||||
|
||||
// Implements setState() logic. This allows to be called from constructor (it is not virtual function)
|
||||
|
||||
@@ -470,8 +470,10 @@ void UserAgent::process()
|
||||
// Send generated packet via provider's method to allow custom scheme of encryption
|
||||
ICELogDebug(<<"Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with " << buffer->comment());
|
||||
|
||||
PDatagramSocket s = iceComponentId == ICE_RTP_ID ? stream.socket4().mRtp : stream.socket4().mRtcp;
|
||||
stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size());
|
||||
RtpPair<PDatagramSocket>& pair = buffer->remoteAddress().family() == AF_INET6 ? stream.socket6() : stream.socket4();
|
||||
PDatagramSocket s = iceComponentId == ICE_RTP_ID ? pair.mRtp : pair.mRtcp;
|
||||
if (s)
|
||||
stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size());
|
||||
break;
|
||||
}
|
||||
} // end of provider iterating
|
||||
@@ -805,7 +807,10 @@ void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::Si
|
||||
/// called when dialog enters the Early state - typically after getting 18x
|
||||
void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg)
|
||||
{
|
||||
PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId);
|
||||
ResipSession* rs = CAST2RESIPSESSION(h);
|
||||
if (!rs)
|
||||
return;
|
||||
PSession s = getUserSession(rs->mSessionId);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -821,7 +826,10 @@ void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::S
|
||||
/// called when a dialog initiated as a UAC enters the connected state
|
||||
void UserAgent::onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg)
|
||||
{
|
||||
PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId);
|
||||
ResipSession* rs = CAST2RESIPSESSION(h);
|
||||
if (!rs)
|
||||
return;
|
||||
PSession s = getUserSession(rs->mSessionId);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -874,7 +882,10 @@ void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessag
|
||||
|
||||
void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related)
|
||||
{
|
||||
PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId);
|
||||
ResipSession* rs = CAST2RESIPSESSION(h);
|
||||
if (!rs)
|
||||
return;
|
||||
PSession s = getUserSession(rs->mSessionId);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -920,6 +931,8 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
|
||||
if (!resipSession)
|
||||
return;
|
||||
Session* s = resipSession->session();
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
bool iceAvailable = true;
|
||||
|
||||
@@ -1069,7 +1082,8 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
|
||||
/// Called when an SDP offer is received - must send an answer soon after this
|
||||
void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& msg, const resip::SdpContents& sdp)
|
||||
{
|
||||
PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId);
|
||||
ResipSession* rs = CAST2RESIPSESSION(h);
|
||||
PSession s = rs ? getUserSession(rs->mSessionId) : PSession();
|
||||
if (!s)
|
||||
{
|
||||
h->reject(488);
|
||||
@@ -1091,7 +1105,8 @@ void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& m
|
||||
|
||||
uint64_t version = sdp.session().origin().getVersion();
|
||||
std::string remoteIp = sdp.session().connection().getAddress().c_str();
|
||||
int code;
|
||||
// Default to 200: a retransmitted offer (same origin version) keeps the session.
|
||||
int code = 200;
|
||||
if ((uint64_t)-1 == s->mRemoteOriginVersion)
|
||||
{
|
||||
code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media());
|
||||
@@ -1299,6 +1314,8 @@ void UserAgent::onPresenceUpdate(PClientObserver observer, const std::string& pe
|
||||
void UserAgent::onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage& sub)
|
||||
{
|
||||
ResipSession* s = CAST2RESIPSESSION(h);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
// Get the event package name
|
||||
const char* event = sub.header(resip::h_Event).value().c_str();
|
||||
|
||||
@@ -346,6 +346,10 @@ void Session::stop()
|
||||
// Free socket
|
||||
SocketHeap::instance().freeSocketPair( dataStream.socket4() );
|
||||
SocketHeap::instance().freeSocketPair( dataStream.socket6() );
|
||||
|
||||
// Drop the references so the destructor's cleanup does not free them again
|
||||
dataStream.setSocket4(RtpPair<PDatagramSocket>());
|
||||
dataStream.setSocket6(RtpPair<PDatagramSocket>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +479,7 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
|
||||
if (stat.mReceivedRtp)
|
||||
info[SessionInfo_PacketLoss] = static_cast<int>((stat.mPacketLoss * 1000) / stat.mReceivedRtp);
|
||||
|
||||
if (media)
|
||||
if (media && mIceStack)
|
||||
info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString();
|
||||
|
||||
info[SessionInfo_Jitter] = stat.mJitter;
|
||||
@@ -485,7 +489,8 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
|
||||
info[SessionInfo_BitrateSwitchCounter] = stat.mBitrateSwitchCounter;
|
||||
info[SessionInfo_CngCounter] = stat.mCng;
|
||||
#endif
|
||||
info[SessionInfo_SSRC] = stat.mSsrc;
|
||||
// Variant stores VTYPE_INT here; keep the 32 bits (consumers read it back with asInt()).
|
||||
info[SessionInfo_SSRC] = static_cast<int>(stat.mSsrc);
|
||||
info[SessionInfo_RemotePeer] = stat.mRemotePeer.toStdString();
|
||||
}
|
||||
|
||||
@@ -741,9 +746,12 @@ PDataProvider Session::findProviderByPort(int family, unsigned short port)
|
||||
{
|
||||
Stream& s = mStreamList[i];
|
||||
|
||||
if ((s.socket4().mRtp->localport() == port || s.socket4().mRtcp->localport() == port) && family == AF_INET)
|
||||
// Sockets may not be allocated yet (stream created from SDP, sockets follow later)
|
||||
if (family == AF_INET && s.socket4().mRtp && s.socket4().mRtcp &&
|
||||
(s.socket4().mRtp->localport() == port || s.socket4().mRtcp->localport() == port))
|
||||
return s.provider();
|
||||
if ((s.socket6().mRtp->localport() == port || s.socket6().mRtcp->localport() == port) && family == AF_INET6)
|
||||
if (family == AF_INET6 && s.socket6().mRtp && s.socket6().mRtcp &&
|
||||
(s.socket6().mRtp->localport() == port || s.socket6().mRtcp->localport() == port))
|
||||
return s.provider();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user