[asterisk-commits] russell: branch 1.4 r160003 - /branches/1.4/channels/chan_iax2.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Dec 1 11:27:31 CST 2008
Author: russell
Date: Mon Dec 1 11:27:30 2008
New Revision: 160003
URL: http://svn.digium.com/view/asterisk?view=rev&rev=160003
Log:
Apply some logic used in iax2_indicate() to iax2_setoption(), as well, since they
both have the potential to send control frames in the middle of call setup. We
have to wait until we have received a message back from the remote end before
we try to send any more frames. Otherwise, the remote end will consider it
invalid, and we'll get stuck in an INVAL/VNAK storm.
Modified:
branches/1.4/channels/chan_iax2.c
Modified: branches/1.4/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_iax2.c?view=diff&rev=160003&r1=160002&r2=160003
==============================================================================
--- branches/1.4/channels/chan_iax2.c (original)
+++ branches/1.4/channels/chan_iax2.c Mon Dec 1 11:27:30 2008
@@ -3481,6 +3481,28 @@
return 0;
}
+/*!
+ * \note expects the pvt to be locked
+ */
+static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
+{
+ unsigned short callno = pvt->callno;
+
+ if (!pvt->peercallno) {
+ /* We don't know the remote side's call number, yet. :( */
+ int count = 10;
+ while (count-- && pvt && !pvt->peercallno) {
+ DEADLOCK_AVOIDANCE(&iaxsl[callno]);
+ pvt = iaxs[callno];
+ }
+ if (!pvt->peercallno) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
{
struct ast_option_header *h;
@@ -3493,8 +3515,23 @@
errno = ENOSYS;
return -1;
default:
- if (!(h = ast_malloc(datalen + sizeof(*h))))
+ {
+ unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
+ struct chan_iax2_pvt *pvt;
+
+ ast_mutex_lock(&iaxsl[callno]);
+ pvt = iaxs[callno];
+
+ if (wait_for_peercallno(pvt)) {
+ ast_mutex_unlock(&iaxsl[callno]);
return -1;
+ }
+
+ ast_mutex_unlock(&iaxsl[callno]);
+
+ if (!(h = ast_malloc(datalen + sizeof(*h)))) {
+ return -1;
+ }
h->flag = AST_OPTION_FLAG_REQUEST;
h->option = htons(option);
@@ -3504,6 +3541,7 @@
datalen + sizeof(*h), -1);
free(h);
return res;
+ }
}
}
@@ -3724,17 +3762,9 @@
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) {
- DEADLOCK_AVOIDANCE(&iaxsl[callno]);
- pvt = iaxs[callno];
- }
- if (!pvt->peercallno) {
- res = -1;
- goto done;
- }
+ if (wait_for_peercallno(pvt)) {
+ res = -1;
+ goto done;
}
switch (condition) {
More information about the asterisk-commits
mailing list