[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