Hi,

I have discovered a bug in sems 1.5.0 and I need some help in fixing it:
in AmRtpStream.cpp, there is a comment before setLocalIP

/*
 * This function must be called before setLocalPort, because
 * setLocalPort will bind the socket and it will be not
 * possible to change the IP later
 */
void AmRtpStream::setLocalIP(const string& ip)

however, if I put a debug message in it, I get this:
2012-10-01 15:38:33.978451500 [#b5df4bb0/4750] [setLocalPort, AmRtpStream.cpp:180] DEBUG: added stream [0xb6a99008] to RTP receiver (0.0.0.0:10006) 2012-10-01 15:38:33.979488500 [#b5df4bb0/4750] [setLocalIP, AmRtpStream.cpp:84] DEBUG: XX.XX.XX.XX This is wrong, of course, and if there is IP alias used, the outgoing packet will go from the first IP of the interface, which is may or may not the same as media_ip, which is specified in the SDP.

The wrong order is because the OfferAnswer module calls them in that order:

#0  AmRtpStream::setLocalPort (this=0xb7475008) at AmRtpStream.cpp:181
#1 0x081162b9 in AmRtpStream::getLocalPort (this=0xb7475008) at AmRtpStream.cpp:410
#2  0x081162f8 in AmRtpStream::getSdp (this=0xb7475008, m=@0x82ae3b0)
    at AmRtpStream.cpp:504
#3  0x08116362 in AmRtpStream::getSdpAnswer (this=0xb7475008, index=0,
    offer=@0x82c0290, answer=@0x82ae3b0) at AmRtpStream.cpp:523
#4 0x0810c2b8 in AmRtpAudio::getSdpAnswer (this=0xb7475008, index=0, offer=@0x82c0290,
    answer=@0x82ae3b0) at AmRtpAudio.cpp:315
#5 0x0813b6c1 in AmSession::getSdpAnswer (this=0x82b04f8, offer=@0x82b0a18,
    answer=@0x82b0afc) at AmSession.cpp:1000
#6 0x08141475 in AmSipDialog::getSdpAnswer (this=0x82b07fc, offer=@0x82b0a18,
    answer=@0x82b0afc) at AmSipDialog.cpp:266
#7 0x080f1c2f in AmOfferAnswer::getSdpBody (this=0x81fb7d8, sdp_body=@0xb60e9554)
    at AmOfferAnswer.cpp:442
#8 0x080f39f1 in AmOfferAnswer::onReplyOut (this=0x82b0a0c, reply=@0xb60e9e08)
    at AmOfferAnswer.cpp:366
#9 0x0814c9d8 in AmSipDialog::reply (this=0x82b07fc, t=@0xb60e9eec, code=200, reason=@0xb60e9f40, body=0x0, hdrs=@0xb60e9f3c, flags=0) at AmSipDialog.cpp:779 #10 0x0814dc69 in AmSipDialog::reply (this=0x82b07fc, req=@0x82bf264, code=200, reason=@0xb60e9f40, body=0x0, hdrs=@0xb60e9f3c, flags=0) at AmSipDialog.cpp:730
#11 0x0813c006 in AmSession::onInvite (this=0x82b04f8, req=@0x82bf264)
    at AmSession.cpp:891

and later:

#0 AmRtpStream::setLocalIP (this=0xb7475008, ip=@0x82b0b80) at AmRtpStream.cpp:84
#1  0x08116ed7 in AmRtpStream::init (this=0xb7475008, local=@0x82b0afc,
    remote=@0x82b0a18, force_passive_mode=false) at AmRtpStream.cpp:628
#2  0x0810df84 in AmRtpAudio::init (this=0xb7475008, local=@0x82b0afc,
    remote=@0x82b0a18, force_symmetric_rtp=false) at AmRtpAudio.cpp:322
#3 0x08139e79 in AmSession::onSdpCompleted (this=0x82b04f8, local_sdp=@0x82b0afc,
    remote_sdp=@0x82b0a18) at AmSession.cpp:1075
#4 0x08146cf6 in AmSipDialog::onSdpCompleted (this=0x82b07fc) at AmSipDialog.cpp:237
#5  0x080f28f5 in AmOfferAnswer::checkStateChange (this=0xb7475008)
    at AmOfferAnswer.cpp:96
#6 0x080f292b in AmOfferAnswer::onReplySent (this=0x82b0a0c, reply=@0xb60e9e08)
    at AmOfferAnswer.cpp:411
#7 0x0814cf3f in AmSipDialog::reply (this=0x82b07fc, t=@0xb60e9eec, code=200, reason=@0xb60e9f40, body=0x0, hdrs=@0xb60e9f3c, flags=0) at AmSipDialog.cpp:809 #8 0x0814dc69 in AmSipDialog::reply (this=0x82b07fc, req=@0x82bf264, code=200, reason=@0xb60e9f40, body=0x0, hdrs=@0xb60e9f3c, flags=0) at AmSipDialog.cpp:730
#9  0x0813c006 in AmSession::onInvite (this=0x82b04f8, req=@0x82bf264)
    at AmSession.cpp:891

As you can see, the AmOfferAnswer::onReplyOut is the offending code that ends up calling setLocalPort, while the setLocalIP is trigged only by AmOfferAnswer::onReplySent.

In AmSession::getSdpAnswer we already have the IP, so around there we should let the AmRtpStream know.

In the incoming invite case maybe

--- AmSession.cpp       (revision 17833)
+++ AmSession.cpp       (working copy)
@@ -997,6 +997,7 @@
         && audio_1st_stream
         && (m_it->port != 0) ) {

+       RTPStream()->setLocalIP(answer.conn.address);
       RTPStream()->getSdpAnswer(media_index,*m_it,answer_media);
       if(answer_media.payloads.empty() ||
         ((answer_media.payloads.size() == 1) &&

is enough but I don't know about the other direction, and the setLocalIP in the ::init() is clearly useless, so please someone with broader oversight fix this for me :)

br

Szo
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to