Index: channels/chan_iax2.c =================================================================== --- channels/chan_iax2.c (revision 71749) +++ channels/chan_iax2.c (working copy) @@ -267,7 +267,8 @@ IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ - IAX_MAXAUTHREQ = (1 << 23) /*!< Maximum outstanding AUTHREQ restriction is in place */ + IAX_MAXAUTHREQ = (1 << 23), /*!< Maximum outstanding AUTHREQ restriction is in place */ + IAX_RESPRECV = (1 << 24), /*!< Whether we've received a response yet (fix for DoS amplification attacks) */ } iax2_flags; static int global_rtautoclear = 120; @@ -1512,6 +1513,11 @@ /* Called with iaxsl held */ if (!iaxs[f->callno]) return -1; + /* Don't send any packets until we receive an ACK */ + if (!ast_test_flag(iaxs[f->callno], IAX_RESPRECV)) { + if (f->af.frametype != AST_FRAME_IAX || f->af.subclass != IAX_COMMAND_ACCEPT) + return 0; + } if (option_debug > 2 && iaxdebug) ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port)); /* Don't send if there was an error, but return error instead */ @@ -6874,6 +6880,7 @@ switch(f.subclass) { case IAX_COMMAND_ACK: /* Do nothing */ + ast_set_flag(iaxs[fr->callno], IAX_RESPRECV); break; case IAX_COMMAND_QUELCH: if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {