[asterisk-commits] russell: branch russell/iax2-frame-race-1.2 r118749 - /team/russell/iax2-fram...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 28 11:31:29 CDT 2008
Author: russell
Date: Wed May 28 11:31:29 2008
New Revision: 118749
URL: http://svn.digium.com/view/asterisk?view=rev&rev=118749
Log:
Fix a race condition that can cause an IAX2 call to end up in a storm of INVAL
and VNAK frames being sent.
The recent security fix was to make chan_iax2 do more strict checking
of incoming full frames. Part of this fix was to ensure that all full frames
that were supposed to include the destination call number, did include it.
So, the 2nd frame received for a call is expected to include the destination
call number. However, this is where a problem can occur.
The IAX2 channel driver schedules a PING and LAGRQ to be sent right after an
IAX2 exchange begins. One of these frames (usually the LAGRQ) may be sent as
the second frame before the first frame is received from the other end. If that
happens, then the frame will be rejected as invalid now, and for every time in
the future as it gets retransmitted.
I have made a minor change to the callbacks that send LAGRQ and PING to ensure
that they do not get sent unless the peer's call number is already known.
Modified:
team/russell/iax2-frame-race-1.2/channels/chan_iax2.c
Modified: team/russell/iax2-frame-race-1.2/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax2-frame-race-1.2/channels/chan_iax2.c?view=diff&rev=118749&r1=118748&r2=118749
==============================================================================
--- team/russell/iax2-frame-race-1.2/channels/chan_iax2.c (original)
+++ team/russell/iax2-frame-race-1.2/channels/chan_iax2.c Wed May 28 11:31:29 2008
@@ -806,15 +806,27 @@
static int send_ping(void *data)
{
int callno = (long)data;
+ int res = 0;
+
/* Ping only if it's real, not if it's bridged */
- if (iaxs[callno]) {
+
+ ast_mutex_lock(&iaxsl[callno]);
+
+ while (iaxs[callno]) {
+ res = 1;
+ if (!iaxs[callno]->peercallno) {
+ break;
+ }
#ifdef BRIDGE_OPTIMIZATION
if (!iaxs[callno]->bridgecallno)
#endif
send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
- return 1;
- } else
- return 0;
+ break;
+ }
+
+ ast_mutex_unlock(&iaxsl[callno]);
+
+ return res;
}
static int get_encrypt_methods(const char *s)
@@ -832,15 +844,27 @@
static int send_lagrq(void *data)
{
int callno = (long)data;
+ int res = 0;
+
/* Ping only if it's real not if it's bridged */
- if (iaxs[callno]) {
+
+ ast_mutex_lock(&iaxsl[callno]);
+
+ while (iaxs[callno]) {
+ res = 1;
+ if (!iaxs[callno]->peercallno) {
+ break;
+ }
#ifdef BRIDGE_OPTIMIZATION
if (!iaxs[callno]->bridgecallno)
#endif
send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
- return 1;
- } else
- return 0;
+ break;
+ }
+
+ ast_mutex_unlock(&iaxsl[callno]);
+
+ return res;
}
static unsigned char compress_subclass(int subclass)
More information about the asterisk-commits
mailing list