[Home]

Summary:ASTERISK-10237: SIP Reinvite behaviour does not work as expected with certain dial() options
Reporter:Sam Deller (samdell3)Labels:
Date Opened:2007-09-05 00:50:30Date Closed:2011-06-07 14:07:19
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Core/RTP
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) 10647.diff
( 1) Code_hack_sip-conf_additional_debugging.txt
( 2) Dial_with_t_option_additional_debug_output.txt
( 3) inviteproblem-t-option-canreinvite-yes-sniffedAtPeerB.cap
( 4) inviteproblem-t-option-canreinvite-yes-sniffedAtProxy.cap
( 5) sip.conf
( 6) verbosedebug.txt
Description:With canreinvite=no on any SIP peer, the call is never reinvited (this is correct behaviour)

With canreinvite=yes, and using with a Dial() option from below, re-invites are not issued correctly. (actually, reinvites should not be issued at all...)

Asterisk is not supposed to perform a re-invite when using any of the following Dial() options: t, T, h, H, w, W or L (with multiple arguments)
This is not the case.
Asterisk still issues a Re-invite to one of the call legs causing an asytmetrical RTP traffic flow (causing one-way audio if the SIP peer filters RTP packets coming from somehwere that was not in it's own SDP)

EG
SIPPeerA------ASTERISK-----SIPPeerB

SIPPeerA calls SIPPeerB

If either or both SIPPeerA or SIPPeerB have canreinvite=no, the RTP flow is always via Asterisk - this is correct.

If Both SIPPeers are canreinvite=yes, AND the dial command contains any of the above dial() options, then the RTP flow forms a triangle due to a single re-invite STILL being issued by Asterisk. EG A's RTP goes to Asterisk, Asterisk's RTP goes to B, but B's RTP goes to A. This is because Asterisk issues a re-invite and tells B to talk to A when it shouldn't.
If Asterisk does issue a re-invite for one leg, it should issue a re-invite for both legs! But in this case it should not issues any re-invites at all.

****** ADDITIONAL INFORMATION ******

Possibly apparent in every 1.4.x version. Confirmed faulty behaviour in 1.4.5 and 1.4.11.

I *think* this is also what is breaking certain T.38 calls too... and possibly the root of several other problems we are experiencing.

Very easy to reproduce. Confirmed with Dial Options t T h H, and combinations thereof. They all perform the same (wrong behaviour).
Comments:By: Joshua C. Colp (jcolp) 2007-09-05 08:01:26

I was unable to reproduce this strange behavior... below is what I got so please attach a sip.conf and console output with debug enabled.

t and T options:
No native bridge is attempted.

h, H, w, and W options:

Packet2Packet bridge is attempted (NOT a reinvite, still stays through Asterisk).

L with 1 option:

Native bridge (which is fine).

L with 2+ options:

Does not even attempt to native bridge or Packet2Packet bridge.



By: Sam Deller (samdell3) 2007-09-05 17:47:44

Verbose debug attached
SIP capture's attached (2 vantage points, Asterisk and SIP PeerB)
Edited sip.conf attached

PeerA = SIP Gateway
PeerB = Polycom Handset

Test call came in via PeerA, to IVR at Asterisk. Option 3 pressed, causing PeerB to be dialled with t option and canreinvite=yes. picked up PeerB's handset, with one way audio problem. PeerB cannot hear anything, but PeerA can hear PeerB
You can see the 'triangle' RTP Flow in 'sniffedAtPeerB.cap'.
Polycom handsets, by default, filter RTP traffic sent to it that was not negotiated in the SDP, becasue it was never sent the re-invite

NOTE: PeerB has a 10.x.x.x address. It is *NOT* behind NAT, rather, a private routed network at layer 3. PeerA and Asterisk are in the same public subnet.

By: Joshua C. Colp (jcolp) 2007-09-06 10:31:27

Please try the attached patch.

By: Sam Deller (samdell3) 2007-09-06 17:42:37

Nice Work, thanks File

However, the same problem appears to exist.

Now, I 'aint no C coder but I did have a go at adding additional logging in and around the area where the patch was applied to see what code gets 'hit'.
The changes I hacked in can be seen in Code_hack_sip-conf_additional_debugging.txt

I then made an identical test call (canreinvite=yes, dial() option 't') and copied the console output (with extra debugging added) to  Dial_with_t_option_additional_debug_output.txt

Hope this helps ?

By: Sam Deller (samdell3) 2007-09-08 18:56:00

Quick Update: The culprit is line 17265 transmit_reinvite_with_sdp(p).

I think line 17265 transmit_reinvite_with_sdp is triggered by this:

17168    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17169       res = AST_RTP_TRY_NATIVE;

..as it gets hit at soon as PeerB answers - everytime canreinvite is set to yes and using t (and other) dial() options.

I added further debug messages to chan_sip.c and app_dial.c.
They show as follows:

Canreinvite=yes (one-way incorrectly reinvited audio):

   -- Executing [3@airnetmainivr:9] Dial("SIP/202.137.240.83-0821dcc8", "SIP/66502222|10|t") in new stack
[Sep  9 08:54:02] NOTICE[24644]: chan_sip.c:17157 sip_get_rtp_peer: HIT: chan->_state != AST_STATE_UP && !global_directrtpsetup
[Sep  9 08:54:02] NOTICE[24644]: chan_sip.c:17182 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
   -- Called 66502222
   -- SIP/66502222-08278c70 is ringing
[Sep  9 08:54:02] NOTICE[24644]: chan_sip.c:17182 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
[Sep  9 08:54:02] NOTICE[24644]: chan_sip.c:17157 sip_get_rtp_peer: HIT: chan->_state != AST_STATE_UP && !global_directrtpsetup
PICKED UP HANDSET HERE
  -- SIP/66502222-08278c70 answered SIP/202.137.240.83-0821dcc8
[Sep  9 08:54:10] NOTICE[24644]: chan_sip.c:17182 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
[Sep  9 08:54:10] NOTICE[24644]: chan_sip.c:17182 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
[Sep  9 08:54:10] NOTICE[24644]: chan_sip.c:17282 sip_set_rtp_peer: HIT: transmit_reinvite_with_sdp thing
[Sep  9 08:54:10] NOTICE[24644]: app_dial.c:1601 dial_exec_full: HIT: app_dial.c OPT_CALLEE_TRANSFER
HANGUP HANDSET HERE
[Sep  9 08:54:17] NOTICE[24644]: app_dial.c:1654 dial_exec_full: HIT: App Dial.c ast_bridge_call
 == Spawn extension (airnetmainivr, 3, 9) exited non-zero on 'SIP/202.137.240.83-0821dcc8'


Canreinvite=no (audio good):

   -- Executing [3@airnetmainivr:9] Dial("SIP/202.137.240.83-b7307080", "SIP/66502222|10|t") in new stack
[Sep  9 10:27:00] NOTICE[10774]: chan_sip.c:17160 sip_get_rtp_peer: HIT: chan->_state != AST_STATE_UP && !global_directrtpsetup
[Sep  9 10:27:00] NOTICE[10774]: chan_sip.c:17185 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
   -- Called 66502222
   -- SIP/66502222-08268cb0 is ringing
[Sep  9 10:27:00] NOTICE[10774]: chan_sip.c:17185 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
[Sep  9 10:27:00] NOTICE[10774]: chan_sip.c:17160 sip_get_rtp_peer: HIT: chan->_state != AST_STATE_UP && !global_directrtpsetup
PICKED UP HANDSET HERE
  -- SIP/66502222-08268cb0 answered SIP/202.137.240.83-b7307080
[Sep  9 10:27:05] NOTICE[10774]: chan_sip.c:17185 sip_get_rtp_peer: HIT: ast_test_flag(&p->flags[0], SIP_CAN_REINVITE
[Sep  9 10:27:05] NOTICE[10774]: app_dial.c:1601 dial_exec_full: HIT: app_dial.c OPT_CALLEE_TRANSFER
HANGUP HANDSET HERE
[Sep  9 10:27:12] NOTICE[10774]: app_dial.c:1654 dial_exec_full: HIT: App Dial.c ast_bridge_call
 == Spawn extension (airnetmainivr, 3, 9) exited non-zero on 'SIP/202.137.240.83-b7307080'



By: Sam Deller (samdell3) 2007-09-11 19:51:58

Update again

With:
canreinvite=yes
directrtpsetup=yes
Dial(SIP/66500504|10|tThHL(100000:50000:50000))

Completes the call setup properly with direct media, and 2-way audio.
It COMPLETELY ignores the dial options that should keep Asterisk in the audio path. ie none of the dial options work.


With:
canreinvite=yes
directrtpsetup=no
Dial(SIP/66500504|10|tThHL(100000:50000:50000))

A single re-invite is still issued to one leg of the call, breaking the RTP flow and causing 1-way audio
chan_sip.c transmit_reinvite_with_sdp gets hit once, and one re-invite is still sent to the peer that initiated the call, when it shouldn't.



By: Sam Deller (samdell3) 2007-09-15 01:42:03

Anyone here ?

How do I switch off 'status = feedback' ?



By: gm (gmvoip) 2007-10-19 03:52:57

Hi,

I have been trying the possibility of setting up a Direct RTP session between two SIP clients.
I tried all the permutations suggested, with Trixbox(1.2.18) as my
server and clients A and B made through resiprocate but Asterisk doesnt send me the re-invite after the session establishment(OnConnectedConfirmed state). So, A and B are unable to see each other's IP.
In Asterisk, I have set canreinvite=yes(I have set this for both the clients or trunks in sip_additional.conf) and all the 3 conditions below are satisfied

* If one of the clients is configured with canreinvite=NO, Asterisk will not issue a re-invite at all.
* If the clients use different codecs, Asterisk will not issue a re-invite.( I use pcmu for both)
* If the Dial() command contains ''t'', ''T", "h", "H", "w", "W" or "L" (with multiple arguments) Asterisk will not issue a re-invite(dial option = r in my case)

I tried another field in sip.conf, directrtpsetup=yes, also canreinvite=nonat,update .. doesnt work either.
The set up is a normal LAN. A,B and server all on same subnet, so i presume no NAT issues are there.(Tried nat=no also) ....
Probably the problem is on Asterisk side. Has somebody got this re-invite after session
establishmet with IP's of A and B ?

Any hints would be great.
Regards
Megs

By: Joshua C. Colp (jcolp) 2007-10-19 09:55:10

Wow, I'm surprised this bug never came up on my radar... strange.

samdell3: Email me or Jabber me.

GMvoip: 1.2 is no longer supported, and the code between 1.2/1.4 is quite different for this stuff but if you can reproduce it with 1.4 feel free to open a bug.

By: Private Name (falves11) 2007-10-19 20:06:44

I thin that there should be a way to use L(XXXX) to limit the max duration of the call and still have both peers to talk to each other, I mean, do not proxy the media. Media proxying should be avoided, but we need a way to set a limit to the call. Can this be done?

By: Joshua C. Colp (jcolp) 2007-11-02 09:56:21

falves11: It's only code, so sure it's possible. With the current state of the RTP stack it could be relatively easy...

By: Olle Johansson (oej) 2007-12-16 03:38:44.000-0600

I don't think "L" should block re-invites. L doesn't involve DTMF.

By: Digium Subversion (svnbot) 2008-02-11 10:14:05.000-0600

Repository: asterisk
Revision: 103314

U   trunk/channels/chan_iax2.c
U   trunk/main/channel.c

------------------------------------------------------------------------
r103314 | file | 2008-02-11 10:14:03 -0600 (Mon, 11 Feb 2008) | 4 lines

Add support for allowing a native bridge to happen when the L option is enabled. The RTP bridging could already handle this, it just needed to be enabled in the main bridging code.
(issue ASTERISK-10237)
Reported by: samdell3

------------------------------------------------------------------------

http://svn.digium.com/view/asterisk?view=rev&revision=103314

By: Joshua C. Colp (jcolp) 2008-02-11 10:14:19.000-0600

Suspending since the original reporter has not gotten in contact with me... as for the L option, I've added support for native bridging with it in trunk as of revision 103314.

By: Joshua C. Colp (jcolp) 2008-02-15 15:54:16.000-0600

Reopened per request.

By: Joshua C. Colp (jcolp) 2008-02-20 14:45:53.000-0600

Status update: Reporter has been given exact code flow and is tracking it down on their own.

By: Joshua C. Colp (jcolp) 2008-03-26 12:49:20

Any progress based on the information of how things work I gave?

By: Joshua C. Colp (jcolp) 2008-05-05 09:45:15

While I hate to suspend this it has been quite some time, and I've given all the information requested. Was the issue outside the scope of Asterisk? Did you need more information?