diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 8c94967e6..aa9ac1cbb 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -9471,6 +9471,7 @@ static int socket_process(struct iax2_thread *thread) int updatehistory=1; int new = NEW_PREVENT; int dcallno = 0; + char decrypted = 0; struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; @@ -9532,6 +9533,25 @@ static int socket_process(struct iax2_thread *thread) /* Get the destination call number */ dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; + + + /* check to make sure this full frame isn't encrypted before we attempt + * to look inside of it. If it is encrypted, decrypt it first. Its ok if the + * callno is not found here, that just means one hasn't been allocated for + * this connection yet. */ + if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { + ast_mutex_lock(&iaxsl[fr->callno]); + if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { + if (decrypt_frame(fr->callno, fh, &f, &res)) { + ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); + ast_mutex_unlock(&iaxsl[fr->callno]); + return 1; + } + decrypted = 1; + } + ast_mutex_unlock(&iaxsl[fr->callno]); + } + /* Retrieve the type and subclass */ f.frametype = fh->type; if (f.frametype == AST_FRAME_VIDEO) { @@ -9642,18 +9662,22 @@ static int socket_process(struct iax2_thread *thread) ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } - if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { + if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { if (decrypt_frame(fr->callno, fh, &f, &res)) { ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } -#ifdef DEBUG_SUPPORT - else - iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); -#endif + decrypted = 1; } +#ifdef DEBUG_SUPPORT + if (decrypted) { + iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); + } +#endif + + /* count this frame */ iaxs[fr->callno]->frames_received++;