[asterisk-commits] twilson: branch 1.8 r351130 - /branches/1.8/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 16 15:12:58 CST 2012


Author: twilson
Date: Mon Jan 16 15:12:53 2012
New Revision: 351130

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=351130
Log:
Ensure ACK retransmit & hangup on non-200 response to INVITE

When handling a non-2xx final response on an INVITE transaction, we have to
keep the transaction around after we send an ACK in case we receive a
retransmission of the response so we can re-transmit the ACK, but also tear
down the ast_channel as soon as we transmit the ACK. Before this patch, we
could fail at both of these things. Calling sip_alreadygone/needdestroy
prevented us from keeping the transaction up and retransmitting the ACK, and
queueing CONGESTION was not sufficient to cause the channel to be torn down
when originating calls via the CLI, for example.

This patch queues a hangup with CONGESTION instead of just queueing CONGESTION
for these responses and removes the sip_alreadygone and sip_needdestroy calls
from handle_response_invite on non-2xx responses. It relies on the hangup
calling sip_scheddestroy.

For more information, see section 17.1.1.1 of RFC 3261.

(closes issue ASTERISK-17717)
Review: https://reviewboard.asterisk.org/r/1672/

Modified:
    branches/1.8/channels/chan_sip.c

Modified: branches/1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_sip.c?view=diff&rev=351130&r1=351129&r2=351130
==============================================================================
--- branches/1.8/channels/chan_sip.c (original)
+++ branches/1.8/channels/chan_sip.c Mon Jan 16 15:12:53 2012
@@ -19820,7 +19820,7 @@
 	 */
 	if (!reinvite) {
 		set_pvt_allowed_methods(p, req);
-	}		
+	}
 
 	switch (resp) {
 	case 100:	/* Trying */
@@ -20115,19 +20115,16 @@
 		ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
 		if (!req->ignore && p->owner) {
 			ast_set_hangupsource(p->owner, p->owner->name, 0);
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-		}
-		pvt_set_needdestroy(p, "received 403 response");
-		sip_alreadygone(p);
+			ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+		}
 		break;
 
 	case 404: /* Not found */
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
 		if (p->owner && !req->ignore) {
 			ast_set_hangupsource(p->owner, p->owner->name, 0);
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-		}
-		sip_alreadygone(p);
+			ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+		}
 		break;
 
 	case 408: /* Request timeout */
@@ -20135,9 +20132,9 @@
 		/* Could be REFER caused INVITE with replaces */
 		ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
-		if (p->owner)
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+		if (p->owner) {
+			ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+		}
 		break;
 
 	case 422: /* Session-Timers: Session interval too small */
@@ -20150,11 +20147,10 @@
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
 		append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
 		ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
-		if (p->owner)
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+		if (p->owner && !req->ignore) {
+			ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+		}
 		break;
-
-		
 
 	case 487: /* Cancelled transaction */
 		/* We have sent CANCEL on an outbound INVITE
@@ -20167,9 +20163,8 @@
  		} else if (!req->ignore) {
 			update_call_counter(p, DEC_CALL_LIMIT);
 			append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
-			pvt_set_needdestroy(p, "received 487 response");
-			sip_alreadygone(p);
-		}
+		}
+		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		break;
 	case 415: /* Unsupported media type */
 	case 488: /* Not acceptable here */
@@ -20184,20 +20179,16 @@
 			transmit_reinvite_with_sdp(p, FALSE, FALSE);
 		} else {
 			/* We can't set up this call, so give up */
-			if (p->owner && !req->ignore)
-				ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-			pvt_set_needdestroy(p, "received 488 response");
-			/* If there's no dialog to end, then mark p as already gone */
-			if (!reinvite)
-				sip_alreadygone(p);
+			if (p->owner && !req->ignore) {
+				ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+			}
 		}
 		break;
 	case 491: /* Pending */
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
 		if (p->owner && !req->ignore) {
 			if (p->owner->_state != AST_STATE_UP) {
-				ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-				pvt_set_needdestroy(p, "received 491 response");
+				ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
 			} else {
 				/* This is a re-invite that failed. */
 				/* Reset the flag after a while
@@ -20220,8 +20211,9 @@
 	case 405: /* Not allowed */
 	case 501: /* Not implemented */
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
-		if (p->owner)
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+		if (p->owner) {
+			ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
+		}
 		break;
 	}
 	if (xmitres == XMIT_ERROR)
@@ -20960,6 +20952,7 @@
 			}
 			break;
 
+		case 428:
 		case 422: /* Session-Timers: Session Interval Too Small */
 			if (sipmethod == SIP_INVITE) {
 				handle_response_invite(p, resp, rest, req, seqno);




More information about the asterisk-commits mailing list