MT#62859 AmB2BSession::acceptPendingInviteB2B use local conn/port

Don't re-exploit the connection information and port
(taken from the coming SDP offer) for creation of faked
SDP answer (200OK). This is confusing and can break things
in rtpengine monologues handling.

Better to create fake SDP answer based on already learned
local SDP port and entirely connection information.

Change-Id: Id71453022fd6c93f6743f1046588447b52c38c07
mr13.5
Donat Zenichev 1 year ago
parent 3b94b6d14b
commit 5bb04271c1

@ -276,6 +276,15 @@ void AmB2BSession::createFakeReply(const AmMimeBody *sdp, AmMimeBody& reply_bo
ILOG_DLG(L_DBG, "created pending INVITE reply body: %s\n", body_str.c_str());
}
static void sdp2body(const AmSdp &sdp, AmMimeBody &body)
{
string body_str;
sdp.print(body_str);
AmMimeBody *s = body.hasContentType(SIP_APPLICATION_SDP);
if (s) s->parse(SIP_APPLICATION_SDP, (const unsigned char*)body_str.c_str(), body_str.length());
else body.parse(SIP_APPLICATION_SDP, (const unsigned char*)body_str.c_str(), body_str.length());
}
void AmB2BSession::acceptPendingInvite(AmSipRequest *invite)
{
// reply the INVITE with fake 200 reply
@ -292,9 +301,44 @@ void AmB2BSession::acceptPendingInvite(AmSipRequest *invite)
void AmB2BSession::acceptPendingInviteB2B(const AmSipRequest& invite)
{
const AmMimeBody *sdp = invite.body.hasContentType(SIP_APPLICATION_SDP);
AmSipReply n_reply;
createFakeReply(sdp, n_reply.body);
/* local sdp, which was already learned before */
AmSdp remote_sdp = dlg->getRemoteSdp();
unsigned int remote_port = 0;
if (dlg->getRemoteMediaPort() > 0) {
ILOG_DLG(L_DBG, "Using remotely seen SDP port for faking this reply: '%d'\n", dlg->getRemoteMediaPort());
remote_port = dlg->getRemoteMediaPort();
}
else if (!remote_sdp.media.empty()) {
/* take first possible media and re-use its port */
SdpMedia remote_sdp_media = remote_sdp.media.front();
if (remote_sdp_media.port > 0) {
ILOG_DLG(L_DBG, "Using remotely seen SDP port for faking this reply: '%d'\n", remote_sdp_media.port);
remote_port = remote_sdp_media.port;
}
}
if (remote_port > 0) {
/* create fake AmSdp from AmMimeBody */
AmSdp fake_sdp;
AmMimeBody fake_mimebody;
fake_sdp.parse((const char *)sdp->getPayload());
ILOG_DLG(L_DBG, "Using local SDP port for faking this reply: '%d'\n", remote_port);
for (auto it = fake_sdp.media.begin(); it != fake_sdp.media.end(); ++it)
{
it->port = remote_port;
}
sdp2body(fake_sdp, fake_mimebody);
createFakeReply(&fake_mimebody, n_reply.body);
}
else {
createFakeReply(sdp, n_reply.body);
}
n_reply.code = 200;
n_reply.reason = "OK";

@ -58,7 +58,8 @@ AmOfferAnswer::AmOfferAnswer(AmSipDialog* dlg)
sdp_remote(),
sdp_local(),
dlg(dlg),
force_sdp(true)
force_sdp(true),
remote_port_seen(0)
{
}
@ -85,6 +86,11 @@ const AmSdp& AmOfferAnswer::getRemoteSdp() const
return sdp_remote;
}
const unsigned int& AmOfferAnswer::getRemoteMediaPort() const
{
return remote_port_seen;
}
/** State maintenance */
void AmOfferAnswer::saveState()
{
@ -225,6 +231,12 @@ int AmOfferAnswer::onReplyIn(const AmSipReply& reply)
dlg->onSdpReceived(true);
}
if (!sdp_remote.media.empty())
{
SdpMedia remote = sdp_remote.media.front();
remote_port_seen = remote.port;
}
} else {
bool is_reliable = reply.code >= 200 || key_in_list(getHeader(reply.hdrs, SIP_HDR_REQUIRE), SIP_EXT_100REL);
saveState();
@ -274,6 +286,12 @@ int AmOfferAnswer::onRxSdp(unsigned int m_cseq, const string& m_remote_tag,
sdp_remote.clear();
}
if (!sdp_remote.media.empty())
{
SdpMedia remote = sdp_remote.media.front();
remote_port_seen = remote.port;
}
if(err_code == 0) {
switch(state) {

@ -53,6 +53,9 @@ private:
AmSdp sdp_remote;
AmSdp sdp_local;
/* saved remote port */
unsigned int remote_port_seen;
AmSipDialog* dlg;
/** Should SDP generation be forced when not required by standards? */
@ -79,6 +82,7 @@ public:
void setState(OAState n_st);
const AmSdp& getLocalSdp() const;
const AmSdp& getRemoteSdp() const;
const unsigned int& getRemoteMediaPort() const;
void clear();
void clearTransitionalState();

@ -134,6 +134,7 @@ protected:
const AmSdp& getLocalSdp() { return oa.getLocalSdp(); }
const AmSdp& getRemoteSdp() { return oa.getRemoteSdp(); }
const unsigned int& getRemoteMediaPort() { return oa.getRemoteMediaPort(); }
/**
* Reliable provisional replies

Loading…
Cancel
Save