diff options
author | Russell Bryant <russell@russellbryant.com> | 2008-05-08 19:17:04 +0000 |
---|---|---|
committer | Russell Bryant <russell@russellbryant.com> | 2008-05-08 19:17:04 +0000 |
commit | c961d9637f5d64a85b5990311c90112a5b2a4a40 (patch) | |
tree | 56bc8463b99e99394f8033bf64b0e3fa6aec391c | |
parent | c02cf176e134ea05a705a6a7ca6cf27317bcf1cd (diff) |
Merged revisions 115565 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
................
r115565 | russell | 2008-05-08 14:15:25 -0500 (Thu, 08 May 2008) | 33 lines
Merged revisions 115564 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r115564 | russell | 2008-05-08 14:14:04 -0500 (Thu, 08 May 2008) | 25 lines
Fix a race condition that bbryant just found while doing some IAX2 testing.
He was running Asterisk trunk running IAX2 calls through a few Asterisk boxes,
however, the audio was extremely choppy. We looked at a packet trace and saw
a storm of INVAL and VNAK frames being sent from one box to another.
It turned out that what had happened was that one box tried to send a CONTROL
frame before the 3 way handshake had completed. So, that frame did not include
the destination call number, because it didn't have it yet. Part of our recent
work for security issues included an additional check to ensure that frames that
are supposed to include the destination call number have the correct one. This
caused the frame to be rejected with an INVAL. The frame would get retransmitted
for forever, rejected every time ...
This race condition exists in all versions that got the security changes,
in theory. However, it is really only likely that this would cause a problem in
Asterisk trunk. There was a control frame being sent (SRCUPDATE) at the _very_
beginning of the call, which does not exist in 1.2 or 1.4. However, I am fixing
all versions that could potentially be affected by the introduced race condition.
These changes are what bbryant and I came up with to fix the issue. Instead of
simply dropping control frames that get sent before the handshake is complete,
the code attempts to wait a little while, since in most cases, the handshake
will complete very quickly. If it doesn't complete after yielding for a little
while, then the frame gets dropped.
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@115566 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r-- | channels/chan_iax2.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 5bdea6592..73eb3f138 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -3927,6 +3927,24 @@ static int iax2_indicate(struct ast_channel *c, int condition, const void *data, ast_mutex_lock(&iaxsl[callno]); pvt = iaxs[callno]; + if (!pvt->peercallno) { + /* We don't know the remote side's call number, yet. :( */ + int count = 10; + while (count-- && pvt && !pvt->peercallno) { + ast_mutex_unlock(&iaxsl[callno]); + usleep(1); + ast_mutex_lock(&iaxsl[callno]); + pvt = iaxs[callno]; + } + if (pvt->peercallno) { + ast_log(LOG_NOTICE, "Yay, we didn't know the peercallno, but we were patient and got it.\n"); + } else { + ast_log(LOG_NOTICE, "Damnit! We waited around and never got the peercallno ...\n"); + res = -1; + goto done; + } + } + switch (condition) { case AST_CONTROL_HOLD: if (strcasecmp(pvt->mohinterpret, "passthrough")) { |