[asterisk-dev] Need thoughts on potential solution to SIP one-way audio problem

Mark Michelson mmichelson at digium.com
Fri May 15 11:09:58 CDT 2009


Hello list,

For the past two days, I have been debugging a one-way audio issue with SIP in 
Asterisk 1.4. After many hours of searching through packet captures and code, 
plus a healthy discussion with Josh Colp yesterday, we came up with a potential 
solution for the problem, but I'd like to run it by the dev list in case there 
is objection to our idea or suggestion for a different solution.

First, I need to present the scenario to you. I must warn that it is long and 
complicated, so bear with me here.

The scenario is that there are two Asterisk boxes (we'll call them A and B), and 
two SIP phones (we'll call them 1 and 2). A diagram of the setup is as follows:


1<---->A<---->B<---->2 (arrows represent SIP links)

The sip.conf files in A and B do not specify values for canreinvite or nat, 
meaning that the settings default to "nonat" and "no" respectively.

Now that the setup is in place, the one-way audio situation sometimes results 
(about 40%-50% of the time in my setup anyway) when a call is placed from 1 to 
2. The following is the SIP signaling involved in the call. I have left out 
provisional responses because they are unimportant with regards to this problem.

1                 A                   B                      2
   ---INVITE [1]-->
                    ------INVITE-[2]-->
                                        -------INVITE [3]---->
                                        <------200 OK [3]-----
                                        --------ACK [3]------>
                    <-----200 OK [2]---
                                        ------REINVITE [4]--->
                    -------ACK [2]---->
   <---200 OK [1]--
                    -----REINVITE [5]->
                    <----REINVITE [6]--
                    -------491 [6]---->
                    <------491 [5]-----
                    -------ACK [5]---->
                    <------ACK [6]-----
   -----ACK [1]--->
   <--REINVITE [7]-                     <--------200 OK [4]----
   ----200 OK [7]->                     ----------ACK [4]----->
   <-----ACK [7]---

I have labeled all INVITE transactions with numbers so that it is easier to see 
which responses and ACKs align with each INVITE. Below are high-level summaries 
of the c= lines from the SDPs of each REINVITE.

REINVITE [4] from B tells 2 to send its media to A.
REINVITE [5] from A tells B to send its media to 1.
REINVITE [6] from B tells A to send its media to 2.
REINVITE [7] from A tells 1 to send its media to B.

REINVITES 5 and 6 happened in a "glare" situation, meaning that the recipients 
of those REINVITES did not process the SDPs contained within. At this point in 
the call, B and A are waiting to re-send reinvites 5 and 6 to each other.

Because we are actually RFC 3261-compliant now with regards to 491 response 
handling, we are guaranteed that B will be the first to try re-sending REINVITE 
[6] to A. B will do so between 0.1 and 2 seconds from the time that the 491 [6] 
was received.

There is a race condition at this point. If B is able to re-send REINVITE [6] to 
A before 2 sends media to A (or to be more accurate, if A processes REINVITE [6] 
from B before reading media from 2), then all goes well. More REINVITEs are sent 
and eventually, media flows between 1 and 2 bidirectionally.

If, though, A reads media from 2 before the retransmitted REINVITE [6] from B 
arrives, then we have an interesting situation. A is expecting media from B, not 
from 2. As a result, A thinks that there is some NAT scenario present. Because 
the sip.conf entry for 1 in A has canreinvite set to its default value, "nonat", 
A will not send a REINVITE to 1 with the new media source. A few REINVITES later 
between A and B and B and 2, and we are left with one-way audio. 2 can hear 1, 
but 1 cannot hear 2.

First off, for any of you that are using Asterisk 1.4 and are encountering this 
scenario, you can avoid it completely by setting canreinvite=yes in sip.conf. 
This will allow A to continue to send REINVITEs to 1 regardless of whether A's 
RTP stack thinks there is a media NAT scenario in use.

The idea that Josh and I came up with was that if we receive a REINVITE to which 
we are going to respond with a 491, then we should let the RTP stack know that 
it may receive media from the IP address and port in the SDP of that REINVITE, 
and not to think that we are in an odd NAT situation if we suddenly receive 
media from that address and port.

I want to know if the above idea makes sense and sounds like a workable 
solution. Also, I am open to other potential methods for solving this issue. I 
may not have explained the one-way audio situation clearly enough, and if more 
clarification is needed as to what exactly is occurring, I can try to be a bit 
more descriptive.

Thanks for any comments you may have on the matter.
Mark Michelson



More information about the asterisk-dev mailing list