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.


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@160003 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 17 years ago
parent 8f27432e76
commit dfec3b69d6

@ -3481,6 +3481,28 @@ static int iax2_hangup(struct ast_channel *c)
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 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat
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);
@ -3505,6 +3542,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat
free(h);
return res;
}
}
}
static struct ast_frame *iax2_read(struct ast_channel *c)
@ -3724,17 +3762,9 @@ 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) {
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) {

Loading…
Cancel
Save