aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_iax2.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 4f2ad60f1..a9ce7915f 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -993,12 +993,19 @@ static int send_ping(const void *data);
static void __send_ping(const void *data)
{
- int callno = (long)data;
+ int callno = (long) data;
+
ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno] && iaxs[callno]->pingid != -1) {
+
+ while (iaxs[callno] && iaxs[callno]->pingid != -1) {
+ if (!iaxs[callno]->peercallno) {
+ break;
+ }
send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
+ break;
}
+
ast_mutex_unlock(&iaxsl[callno]);
}
@@ -1027,13 +1034,19 @@ static int send_lagrq(const void *data);
static void __send_lagrq(const void *data)
{
- int callno = (long)data;
- /* Ping only if it's real not if it's bridged */
+ int callno = (long) data;
+
ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno] && iaxs[callno]->lagid > -1) {
+
+ while (iaxs[callno] && iaxs[callno]->lagid > -1) {
+ if (!iaxs[callno]->peercallno) {
+ break;
+ }
send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
+ break;
}
+
ast_mutex_unlock(&iaxsl[callno]);
}
@@ -7128,8 +7141,25 @@ static int socket_process(struct iax2_thread *thread)
}
if (!fr->callno) {
- fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd,
- (ntohs(mh->callno) & IAX_FLAG_FULL) && f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK);
+ int check_dcallno = 0;
+
+ /*
+ * We enforce accurate destination call numbers for all full frames except
+ * LAGRQ and PING commands. This is because older versions of Asterisk
+ * schedule these commands to get sent very quickly, and they will sometimes
+ * be sent before they receive the first frame from the other side. When
+ * that happens, it doesn't contain the destination call number. However,
+ * not checking it for these frames is safe.
+ *
+ * Discussed in the following thread:
+ * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
+ */
+
+ if (ntohs(mh->callno) & IAX_FLAG_FULL) {
+ check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
+ }
+
+ fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
}
if (fr->callno > 0)