[svn-commits] mmichelson: trunk r355745 - in /trunk: ./ channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Feb 17 13:22:28 CST 2012


Author: mmichelson
Date: Fri Feb 17 13:22:22 2012
New Revision: 355745

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=355745
Log:
Fix regressions with regards to route-set creation on early dialogs.

This fixes two main issues:

1. Asterisk would send a CANCEL to the route created by the provisional response
   instead of using the same destination it did in the initial INVITE.
2. If a new route set arrives in a 200 OK than was in the 1XX response (perfectly
   possible if our outbound INVITE gets forked), then the route set in the 200 OK
   needs to overwrite the route set in the 1XX response.

(closes issue ASTERISK-19358)
Reported by: Karsten Wemheuer
Tested by: Karsten Wemheuer
patches:
   ASTERISK-19358.patch uploaded by Mark Michelson (license 5049)
   ASTERISK-19358.patch uploaded by Stefan Schmidt (license 6034)

Review: https://reviewboard.asterisk.org/r/1749
........

Merged revisions 355732 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 355733 from http://svn.asterisk.org/svn/asterisk/branches/10

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=355745&r1=355744&r2=355745
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Feb 17 13:22:22 2012
@@ -1296,7 +1296,7 @@
 static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method);
 static void free_old_route(struct sip_route *route);
 static void list_route(struct sip_route *route);
-static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards);
+static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp);
 static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sockaddr *addr,
 					      struct sip_request *req, const char *uri);
 static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag);
@@ -8184,7 +8184,7 @@
 	ast_string_field_set(p, our_contact, original->our_contact);
 	ast_string_field_set(p, fullcontact, original->fullcontact);
 	parse_ok_contact(p, req);
-	build_route(p, req, 1);
+	build_route(p, req, 1, 0);
 
 	transmit_request(p, SIP_ACK, p->ocseq, XMIT_UNRELIABLE, TRUE);
 	transmit_request(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
@@ -10663,7 +10663,11 @@
 	snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text);
 
 	add_header(req, "Via", p->via);
-	if (p->route) {
+	/*
+	 * Use the learned route set unless this is a CANCEL. For a CANCEL
+	 * we have to send to the same destination as the original INVITE.
+	 */
+	if (p->route && sipmethod != SIP_CANCEL) {
 		set_destination(p, p->route->hop);
 		add_route(req, is_strict ? p->route->next : p->route);
 	}
@@ -14632,8 +14636,9 @@
 	}
 }
 
-/*! \brief Build route list from Record-Route header */
-static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards)
+/*! \brief Build route list from Record-Route header 
+    \param resp the SIP response code or 0 for a request */
+static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp)
 {
 	struct sip_route *thishop, *head, *tail;
 	int start = 0;
@@ -14651,8 +14656,11 @@
 		p->route = NULL;
 	}
 
-	/* We only want to create the route set the first time this is called */
-	p->route_persistent = 1;
+	/* We only want to create the route set the first time this is called except
+	   it is called from a provisional response.*/
+	if ((resp < 100) || (resp > 199)) {
+		p->route_persistent = 1;
+	}
 
 	/* Build a tailq, then assign it to p->route when done.
 	 * If backwards, we add entries from the head so they end up
@@ -20775,7 +20783,7 @@
 		 * */
 		parse_ok_contact(p, req);
 		if (!reinvite) {
-			build_route(p, req, 1);
+			build_route(p, req, 1, resp);
 		}
 		if (!req->ignore && p->owner) {
 			if (get_rpid(p, req)) {
@@ -20826,7 +20834,7 @@
 		 * */
 		parse_ok_contact(p, req);
 		if (!reinvite) {
-			build_route(p, req, 1);
+			build_route(p, req, 1, resp);
 		}
 		if (!req->ignore && p->owner) {
 			struct ast_party_redirecting redirecting;
@@ -20853,7 +20861,7 @@
 		 * */
 		parse_ok_contact(p, req);
 		if (!reinvite) {
-			build_route(p, req, 1);
+			build_route(p, req, 1, resp);
 		}
 		if (!req->ignore && p->owner) {
 			if (get_rpid(p, req)) {
@@ -20955,7 +20963,7 @@
 			parse_ok_contact(p, req);
 			/* Save Record-Route for any later requests we make on this dialogue */
 			if (!reinvite) {
-				build_route(p, req, 1);
+				build_route(p, req, 1, resp);
 			}
 
 			if(set_address_from_contact(p)) {
@@ -23530,7 +23538,7 @@
 			*recount = 1;
 
 			/* Save Record-Route for any later requests we make on this dialogue */
-			build_route(p, req, 0);
+			build_route(p, req, 0, 0);
 
 			if (c) {
 				ast_party_redirecting_init(&redirecting);
@@ -25567,7 +25575,7 @@
 		if (sipdebug)
 			ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
 		check_via(p, req);
-		build_route(p, req, 0);
+		build_route(p, req, 0, 0);
 	} else if (req->debug && req->ignore)
 		ast_verbose("Ignoring this SUBSCRIBE request\n");
 




More information about the svn-commits mailing list