diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 2260bb1671cdb1db93499c92459e4e3c143dfa65..f6b040df3589159d834bf88afd199003a4a7dca9 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1144,12 +1144,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]);
 }
 
@@ -1178,13 +1185,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]);
 }
 
@@ -7999,8 +8012,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)