diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 11d55d3647..d6deac7797 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -820,6 +820,15 @@ struct chan_iax2_pvt {
 	int frames_received;
 	/*! num bytes used for calltoken ie, even an empty ie should contain 2 */
 	unsigned char calltoken_ie_len;
+	/*! hold all signaling frames from the pbx thread until we have a destination callno */
+	char hold_signaling;
+	/*! frame queue for signaling frames from pbx thread waiting for destination callno */
+	AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
+};
+
+struct signaling_queue_entry {
+	struct ast_frame f;
+	AST_LIST_ENTRY(signaling_queue_entry) next;
 };
 
 /*! table of available call numbers */
@@ -1703,10 +1712,56 @@ static int scheduled_destroy(const void *vid)
 	return 0;
 }
 
+static void free_signaling_queue_entry(struct signaling_queue_entry *s)
+{
+	ast_free(s->f.data.ptr);
+	ast_free(s);
+}
+
+/*! \brief This function must be called once we are sure the other side has
+ *  given us a call number.  All signaling is held here until that point. */
+static void send_signaling(struct chan_iax2_pvt *pvt)
+{
+	struct signaling_queue_entry *s = NULL;
+
+	while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
+		iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
+		free_signaling_queue_entry(s);
+	}
+	pvt->hold_signaling = 0;
+}
+
+/*! \brief All frames other than that of type AST_FRAME_IAX must be held until
+ *  we have received a destination call number. */
+static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
+{
+	struct signaling_queue_entry *new;
+
+	if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
+		return 1; /* do not queue this frame */
+	} else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
+		return -1;  /* out of memory */
+	}
+
+	memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
+
+	if (new->f.datalen) { /* if there is data in this frame copy it over as well */
+		if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
+			free_signaling_queue_entry(new);
+			return -1;
+		}
+		memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
+	}
+	AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
+
+	return 0;
+}
+
 static void pvt_destructor(void *obj)
 {
 	struct chan_iax2_pvt *pvt = obj;
 	struct iax_frame *cur = NULL;
+	struct signaling_queue_entry *s = NULL;
 
 	ast_mutex_lock(&iaxsl[pvt->callno]);
 
@@ -1725,6 +1780,10 @@ static void pvt_destructor(void *obj)
 
 	ast_mutex_unlock(&iaxsl[pvt->callno]);
 
+	while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
+		free_signaling_queue_entry(s);
+	}
+
 	if (pvt->reg) {
 		pvt->reg->callno = 0;
 	}
@@ -1781,6 +1840,9 @@ static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
 
 	AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
 
+	tmp->hold_signaling = 1;
+	AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
+
 	return tmp;
 }
 
@@ -7148,6 +7210,7 @@ static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsig
 		int now, int transfer, int final)
 {
 	struct ast_frame f = { 0, };
+	int res = 0;
 
 	f.frametype = type;
 	f.subclass = command;
@@ -7155,6 +7218,10 @@ static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsig
 	f.src = __FUNCTION__;
 	f.data.ptr = (void *) data;
 
+	if ((res = queue_signalling(i, &f)) <= 0) {
+		return res;
+	}
+
 	return iax2_send(i, &f, ts, seqno, now, transfer, final);
 }
 
@@ -9634,19 +9701,15 @@ static int socket_process(struct iax2_thread *thread)
 		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.
-		 * 
+		 * We enforce accurate destination call numbers for ACKs.  This forces the other
+		 * end to know the destination call number before call setup can complete.
+		 *
 		 * 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;
+		if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
+			check_dcallno = 1;
 		}
 
 		if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
@@ -9922,6 +9985,12 @@ static int socket_process(struct iax2_thread *thread)
 			}
 		}
 
+		/* once we receive our first IAX Full Frame that is not CallToken related, send all
+		 * queued signaling frames that were being held. */
+		if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
+			send_signaling(iaxs[fr->callno]);
+		}
+
 		if (f.frametype == AST_FRAME_VOICE) {
 			if (f.subclass != iaxs[fr->callno]->voiceformat) {
 					iaxs[fr->callno]->voiceformat = f.subclass;