diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index db6fab255b..c89d18e1dc 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -3851,6 +3851,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; @@ -3863,8 +3885,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); @@ -3875,6 +3912,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat ast_free(h); return res; } + } } static struct ast_frame *iax2_read(struct ast_channel *c) @@ -4161,17 +4199,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) {