[svn-commits] dvossel: branch 1.6.2 r248398 - in /branches/1.6.2: ./ channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Feb 23 10:37:52 CST 2010


Author: dvossel
Date: Tue Feb 23 10:37:48 2010
New Revision: 248398

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=248398
Log:
Merged revisions 248397 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r248397 | dvossel | 2010-02-23 10:34:39 -0600 (Tue, 23 Feb 2010) | 15 lines
  
  Merged revisions 248396 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r248396 | dvossel | 2010-02-23 10:26:05 -0600 (Tue, 23 Feb 2010) | 9 lines
    
    fixes invite with replaces deadlock
    
    (closes issue #16862)
    Reported by: pwalker
    Patches:
          replaces_deadlock_1.4 uploaded by dvossel (license 671)
    Tested by: pwalker, dvossel
  ........
................

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/channels/chan_sip.c

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.2/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.2/channels/chan_sip.c?view=diff&rev=248398&r1=248397&r2=248398
==============================================================================
--- branches/1.6.2/channels/chan_sip.c (original)
+++ branches/1.6.2/channels/chan_sip.c Tue Feb 23 10:37:48 2010
@@ -19641,6 +19641,7 @@
 	int gotdest;
 	const char *p_replaces;
 	char *replace_id = NULL;
+	int refer_locked = 0;
 	const char *required;
 	unsigned int required_profile = 0;
 	struct ast_channel *c = NULL;		/* New channel */
@@ -19681,7 +19682,8 @@
 			p->invitestate = INV_COMPLETED;
 			if (!p->lastinvite)
 				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-			return -1;
+			res = -1;
+			goto request_invite_cleanup;
 		}
 	}
 
@@ -19708,7 +19710,8 @@
 			transmit_response(p, "482 Loop Detected", req);
 			p->invitestate = INV_COMPLETED;
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		} else {
 			/*! This is a spiral. What we need to do is to just change the outgoing INVITE
 			 * so that it now routes to the new Request URI. Since we created the INVITE ourselves
@@ -19734,7 +19737,8 @@
 			 */
 			ast_string_field_set(p->owner, call_forward, peerorhost);
 			ast_queue_control(p->owner, AST_CONTROL_BUSY);
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		}
 	}
 
@@ -19772,7 +19776,8 @@
 			transmit_response_reliable(p, "491 Request Pending", req);
 			ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
 			/* Don't destroy dialog here */
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		}
 	}
 
@@ -19789,7 +19794,8 @@
 			ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
 			transmit_response_reliable(p, "400 Bad request", req);	/* The best way to not not accept the transfer */
 			/* Do not destroy existing call */
-			return -1;
+			res = -1;
+			goto request_invite_cleanup;
 		}
 
 		if (sipdebug)
@@ -19803,7 +19809,8 @@
 			append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 			p->invitestate = INV_COMPLETED;
-			return -1;
+			res = -1;
+			goto request_invite_cleanup;
 		}
 
 		/*  Todo: (When we find phones that support this)
@@ -19862,6 +19869,8 @@
 			ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
 			transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
 			error = 1;
+		} else {
+			refer_locked = 1;
 		}
 
 		/* The matched call is the call from the transferer to Asterisk .
@@ -19899,8 +19908,10 @@
 					ast_channel_unlock(p->refer->refer_call->owner);
 				}
 			}
+			refer_locked = 0;
 			p->invitestate = INV_COMPLETED;
-			return -1;
+			res = -1;
+			goto request_invite_cleanup;
 		}
 	}
 
@@ -19933,7 +19944,8 @@
 					transmit_response_reliable(p, "488 Not acceptable here", req);
 					if (!p->lastinvite)
 						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-					return -1;
+					res = -1;
+					goto request_invite_cleanup;
 				}
 				ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
 			} else {
@@ -19952,7 +19964,8 @@
 		res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
 		if (res == AUTH_CHALLENGE_SENT) {
 			p->invitestate = INV_COMPLETED;		/* Needs to restart in another INVITE transaction */
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		}
 		if (res < 0) { /* Something failed in authentication */
 			if (res == AUTH_FAKE_AUTH) {
@@ -19965,7 +19978,8 @@
 			p->invitestate = INV_COMPLETED;
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 			ast_string_field_set(p, theirtag, NULL);
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		}
 
 		/* If T38 is needed but not present, then make it magically appear */
@@ -19982,7 +19996,8 @@
 				p->invitestate = INV_COMPLETED;
 				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				ast_debug(1, "No compatible codecs for this SIP call.\n");
-				return -1;
+				res = -1;
+				goto request_invite_cleanup;
 			}
 			if (ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC)) {
 				if (p->rtp) {
@@ -20017,7 +20032,8 @@
 				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				p->invitestate = INV_COMPLETED;
 			}
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		}
 		gotdest = get_destination(p, NULL);	/* Get destination right away */
 		get_rdnis(p, NULL);			/* Get redirect information */
@@ -20044,7 +20060,8 @@
 			p->invitestate = INV_COMPLETED;
 			update_call_counter(p, DEC_CALL_LIMIT);
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		} else {
 
 			/* If no extension was specified, use the s one */
@@ -20098,7 +20115,8 @@
 				if (!p->lastinvite) {
 					sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				}
-				return -1;
+				res = -1;
+				goto request_invite_cleanup;
 			}
 		}
 
@@ -20112,7 +20130,8 @@
 				if (!p->lastinvite) {
 					sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				}
-				return -1;
+				res = -1;
+				goto request_invite_cleanup;
 			}
 		}
 
@@ -20126,7 +20145,8 @@
 				if (!p->lastinvite) {
 					sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				}
-				return -1;
+				res = -1;
+				goto request_invite_cleanup;
 			}
 
 			p->stimer->st_active_peer_ua = TRUE;
@@ -20156,7 +20176,8 @@
 				if (!p->lastinvite) {
 					sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 				}
-				return -1;
+				res = -1;
+				goto request_invite_cleanup;
 			}
 			break;
 
@@ -20230,12 +20251,15 @@
 			ast_hangup(c);
 			sip_pvt_lock(p);
 
-			return 0;
+			res = 0;
+			goto request_invite_cleanup;
 		} else {
 			/* Go and take over the target call */
 			if (sipdebug)
 				ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
-			return handle_invite_replaces(p, req, debug, seqno, sin, nounlock);
+			res = handle_invite_replaces(p, req, debug, seqno, sin, nounlock);
+			refer_locked = 0;
+			goto request_invite_cleanup;
 		}
 	}
 
@@ -20360,6 +20384,16 @@
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		}
 	}
+
+request_invite_cleanup:
+
+	if (refer_locked && p->refer && p->refer->refer_call) {
+		sip_pvt_unlock(p->refer->refer_call);
+		if (p->refer->refer_call->owner) {
+			ast_channel_unlock(p->refer->refer_call->owner);
+		}
+	}
+
 	return res;
 }
 




More information about the svn-commits mailing list