- fixes after review

This commit is contained in:
2026-06-16 18:05:51 +03:00
parent 2c89b80dcd
commit 40f3b34b16
23 changed files with 390 additions and 254 deletions
+15 -7
View File
@@ -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;
+3 -2
View File
@@ -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)
+24 -7
View File
@@ -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();
+12 -4
View File
@@ -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();
}