[svn-commits] oej: branch oej/yaob-01 r101317 - in /team/oej/yaob-01: ./ channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jan 30 13:46:51 CST 2008


Author: oej
Date: Wed Jan 30 13:46:51 2008
New Revision: 101317

URL: http://svn.digium.com/view/asterisk?view=rev&rev=101317
Log:
Playing around

Modified:
    team/oej/yaob-01/   (props changed)
    team/oej/yaob-01/channels/chan_sip.c

Propchange: team/oej/yaob-01/
------------------------------------------------------------------------------
    automerge = http://www.codename-pineapple.org/

Propchange: team/oej/yaob-01/
------------------------------------------------------------------------------
    automerge-email = oej at edvina.net

Modified: team/oej/yaob-01/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/yaob-01/channels/chan_sip.c?view=diff&rev=101317&r1=101316&r2=101317
==============================================================================
--- team/oej/yaob-01/channels/chan_sip.c (original)
+++ team/oej/yaob-01/channels/chan_sip.c Wed Jan 30 13:46:51 2008
@@ -1049,20 +1049,30 @@
 							you know more) */
 };
 
-static struct sip_pvt *dialoglist = NULL;
+struct dialoglist {
+	struct sip_pvt *list;			/*!< The list */
+	ast_mutex_t lock;			/*!< Dialog list private lock */
+};
+
+/*! \brief The list of current dialogs, excluding SUBSCRIBE dialogs that are handled by subscribe_dialoglist */
+static struct dialoglist dialoglist;
+
+/*! \brief The list of current subscriptions */
+static struct dialoglist subscribe_dialoglist;
 
 /*! \brief Protect the SIP dialog list (of sip_pvt's) */
-AST_MUTEX_DEFINE_STATIC(dialoglock);
+//AST_MUTEX_DEFINE_STATIC(dialoglock)//;
 
 /*! \brief hide the way the list is locked/unlocked */
-static void dialoglist_lock(void)
-{
-	ast_mutex_lock(&dialoglock);
-}
-
-static void dialoglist_unlock(void)
-{
-	ast_mutex_unlock(&dialoglock);
+static void dialoglist_lock(struct dialoglist *list)
+{
+	ast_mutex_lock(&list->lock);
+}
+
+/*! \brief hide the way the list is locked/unlocked */
+static void dialoglist_unlock(struct dialoglist *list)
+{
+	ast_mutex_unlock(&list->lock);
 }
 
 #define FLAG_RESPONSE (1 << 0)
@@ -3355,15 +3365,15 @@
 
 	/* Lock dialog list before removing ourselves from the list */
 	if (lockdialoglist)
-		dialoglist_lock();
-	for (prev = NULL, cur = dialoglist; cur; prev = cur, cur = cur->next) {
+		dialoglist_lock(&dialoglist);
+	for (prev = NULL, cur = dialoglist.list; cur; prev = cur, cur = cur->next) {
 		if (cur == p) {
-			UNLINK(cur, dialoglist, prev);
+			UNLINK(cur, dialoglist.list, prev);
 			break;
 		}
 	}
 	if (lockdialoglist)
-		dialoglist_unlock();
+		dialoglist_unlock(&dialoglist);
 	if (!cur) {
 		ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
 		return;
@@ -4773,10 +4783,10 @@
 	ast_string_field_set(p, context, default_context);
 
 	/* Add to active dialog list */
-	dialoglist_lock();
-	p->next = dialoglist;
-	dialoglist = p;
-	dialoglist_unlock();
+	dialoglist_lock(&dialoglist);
+	p->next = dialoglist.list;
+	dialoglist.list = p;
+	dialoglist_unlock(&dialoglist);
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
 	return p;
@@ -4784,7 +4794,7 @@
 
 /*! \brief Connect incoming SIP message to current dialog or create new dialog structure
 	Called by handle_request, sipsock_read */
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
+static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int request_method)
 {
 	struct sip_pvt *p = NULL;
 	char *tag = "";	/* note, tag is never NULL */
@@ -4794,12 +4804,26 @@
 	const char *from = get_header(req, "From");
 	const char *to = get_header(req, "To");
 	const char *cseq = get_header(req, "Cseq");
+	struct dialoglist *dlist;
+	int reply_method = 0;
 
 	/* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
 	/* get_header always returns non-NULL so we must use ast_strlen_zero() */
 	if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
 			ast_strlen_zero(from) || ast_strlen_zero(cseq))
 		return NULL;	/* Invalid packet */
+
+	/* If this dialog is a response - to what? */
+	if (request_method == SIP_RESPONSE) {
+		const char *m = cseq;
+		while(*m && *m != ' ')
+			m++;
+		while(*m && *m == ' ')
+			m++;
+		reply_method = find_sip_method(m);
+	}
+
+	dlist = (request_method == SIP_SUBSCRIBE || reply_method == SIP_SUBSCRIBE? &subscribe_dialoglist : &dialoglist);
 
 	if (pedanticsipchecking) {
 		/* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
@@ -4831,8 +4855,8 @@
 		}
 	}
 
-	dialoglist_lock();
-	for (p = dialoglist; p; p = p->next) {
+	dialoglist_lock(dlist);
+	for (p = dlist->list; p; p = p->next) {
 		/* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
 		int found = FALSE;
 		if (ast_strlen_zero(p->callid))
@@ -4864,24 +4888,24 @@
 		if (found) {
 			/* Found the call */
 			sip_pvt_lock(p);
-			dialoglist_unlock();
+			dialoglist_unlock(dlist);
 			return p;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(dlist);
 	
 	/* See if the method is capable of creating a dialog */
-	if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
-		if (intended_method == SIP_REFER) {
+	if (sip_methods[request_method].can_create == CAN_CREATE_DIALOG) {
+		if (request_method == SIP_REFER) {
 			/* We do support REFER, but not outside of a dialog yet */
-			transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
-		} else if (intended_method == SIP_NOTIFY) {
+			transmit_response_using_temp(callid, sin, 1, request_method, req, "603 Declined (no dialog)");
+		} else if (request_method == SIP_NOTIFY) {
 			/* We do not support out-of-dialog NOTIFY either,
 		   	like voicemail notification, so cancel that early */
-			transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
+			transmit_response_using_temp(callid, sin, 1, request_method, req, "489 Bad event");
 		} else {
 			/* Ok, time to create a new SIP dialog object, a pvt */
-			if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
+			if ((p = sip_alloc(callid, sin, 1, request_method)))  {
 				/* Ok, we've created a dialog, let's go and process it */
 				sip_pvt_lock(p);
 			} else {
@@ -4893,26 +4917,26 @@
 	
 					Sorry, we apologize for the inconvienience
 				*/
-				transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
+				transmit_response_using_temp(callid, sin, 1, request_method, req, "500 Server internal error");
 				if (option_debug > 3)
 					ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
 			}
 		}
 		return p;
-	} else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
+	} else if( sip_methods[request_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
 		/* A method we do not support, let's take it on the volley */
-		transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
+		transmit_response_using_temp(callid, sin, 1, request_method, req, "501 Method Not Implemented");
 		if (option_debug > 1 )
 			ast_log(LOG_DEBUG, "Got a request with unsupported SIP method.\n");
-	} else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
+	} else if (request_method != SIP_RESPONSE && request_method != SIP_ACK) {
 		/* This is a request outside of a dialog that we don't know about */
-		transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
+		transmit_response_using_temp(callid, sin, 1, request_method, req, "481 Call leg/transaction does not exist");
 		if (option_debug > 1)
 			ast_log(LOG_DEBUG, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
 	}
 	/* We do not respond to responses for dialogs that we don't know about, we just drop
 	   the session quickly */
-	if (option_debug > 1 && intended_method == SIP_RESPONSE)
+	if (option_debug > 1 && request_method == SIP_RESPONSE)
 		ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Callid %s\n", callid ? callid : "<unknown>");
 
 	return p;
@@ -9326,8 +9350,8 @@
 		ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
 
 	/* Search dialogs and find the match */
-	dialoglist_lock();
-	for (sip_pvt_ptr = dialoglist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
+	dialoglist_lock(&dialoglist);
+	for (sip_pvt_ptr = dialoglist.list; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
 		if (!strcmp(sip_pvt_ptr->callid, callid)) {
 			int match = 1;
 			char *ourtag = sip_pvt_ptr->tag;
@@ -9361,7 +9385,7 @@
 			break;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(&dialoglist);
 	if (option_debug > 3 && !sip_pvt_ptr)
 		ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
 	return sip_pvt_ptr;
@@ -11303,11 +11327,13 @@
 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
 	struct sip_pvt *cur;
 	int numchans = 0;
+	struct dialoglist *dlist;
 
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
-	dialoglist_lock();
-	cur = dialoglist;
+	dlist = subscriptions ? &subscribe_dialoglist : &dialoglist;
+	dialoglist_lock(dlist);
+	cur = dlist->list;
 	if (!subscriptions)
 		ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
 	else 
@@ -11343,7 +11369,7 @@
 			numchans++;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(dlist);
 	if (!subscriptions)
 		ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
 	else
@@ -11362,14 +11388,14 @@
 	char *c = NULL;
 	int wordlen = strlen(word);
 
-	dialoglist_lock();
-	for (cur = dialoglist; cur; cur = cur->next) {
+	dialoglist_lock(&dialoglist);
+	for (cur = dialoglist.list; cur; cur = cur->next) {
 		if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
 			c = ast_strdup(cur->callid);
 			break;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(&dialoglist);
 	return c;
 }
 
@@ -11521,8 +11547,8 @@
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
 	len = strlen(argv[3]);
-	dialoglist_lock();
-	for (cur = dialoglist; cur; cur = cur->next) {
+	dialoglist_lock(&dialoglist);
+	for (cur = dialoglist.list; cur; cur = cur->next) {
 		if (!strncasecmp(cur->callid, argv[3], len)) {
 			char formatbuf[BUFSIZ/2];
 			ast_cli(fd,"\n");
@@ -11575,7 +11601,7 @@
 			found++;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(&dialoglist);
 	if (!found) 
 		ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
 	return RESULT_SUCCESS;
@@ -11593,8 +11619,8 @@
 	if (!recordhistory)
 		ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
 	len = strlen(argv[3]);
-	dialoglist_lock();
-	for (cur = dialoglist; cur; cur = cur->next) {
+	dialoglist_lock(&dialoglist);
+	for (cur = dialoglist.list; cur; cur = cur->next) {
 		if (!strncasecmp(cur->callid, argv[3], len)) {
 			struct sip_history *hist;
 			int x = 0;
@@ -11612,7 +11638,7 @@
 			found++;
 		}
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(&dialoglist);
 	if (!found) 
 		ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
 	return RESULT_SUCCESS;
@@ -15504,8 +15530,8 @@
 			for it to expire and send NOTIFY messages to the peer only to have them
 			ignored (or generate errors)
 			*/
-			dialoglist_lock();
-			for (p_old = dialoglist; p_old; p_old = p_old->next) {
+			dialoglist_lock(&dialoglist);
+			for (p_old = dialoglist.list; p_old; p_old = p_old->next) {
 				if (p_old == p)
 					continue;
 				if (p_old->initreq.method != SIP_SUBSCRIBE)
@@ -15523,7 +15549,7 @@
 				}
 				sip_pvt_unlock(p_old);
 			}
-			dialoglist_unlock();
+			dialoglist_unlock(&dialoglist);
 		}
 		if (!p->expiry)
 			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
@@ -16061,14 +16087,14 @@
 		}
 
 		/* Check for dialogs needing to be killed */
-		dialoglist_lock();
+		dialoglist_lock(&dialoglist);
 restartsearch:		
 		t = time(NULL);
 		/* don't scan the dialogs list if it hasn't been a reasonable period
 		   of time since the last time we did it (when MWI is being sent, we can
 		   get back to this point every millisecond or less)
 		*/
-		for (dialog = dialoglist; dialog; dialog = dialog->next) {
+		for (dialog = dialoglist.list; dialog; dialog = dialog->next) {
 			sip_pvt_lock(dialog);
 			/* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
 			check_rtp_timeout(dialog, t);
@@ -16083,7 +16109,7 @@
 			}
 			sip_pvt_unlock(dialog);
 		}
-		dialoglist_unlock();
+		dialoglist_unlock(&dialoglist);
 
 		pthread_testcancel();
 		/* Wait for sched or io */
@@ -18450,6 +18476,8 @@
 		sched_context_destroy(sched);
 		return AST_MODULE_LOAD_FAILURE;
 	}
+	dialoglist.list = NULL;				/* Initialize default dialog list */
+	subscribe_dialoglist.list = NULL;		/* Initialize subscribe dialog list */
 
 	sip_reloadreason = CHANNEL_MODULE_LOAD;
 
@@ -18529,13 +18557,13 @@
 	ast_manager_unregister("SIPpeers");
 	ast_manager_unregister("SIPshowpeer");
 
-	dialoglist_lock();
+	dialoglist_lock(&dialoglist);
 	/* Hangup all dialogs if they have an owner */
-	for (p = dialoglist; p ; p = p->next) {
+	for (p = dialoglist.list; p ; p = p->next) {
 		if (p->owner)
 			ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
 	}
-	dialoglist_unlock();
+	dialoglist_unlock(&dialoglist);
 
 	ast_mutex_lock(&monlock);
 	if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
@@ -18546,16 +18574,16 @@
 	monitor_thread = AST_PTHREADT_STOP;
 	ast_mutex_unlock(&monlock);
 
-	dialoglist_lock();
+	dialoglist_lock(&dialoglist);
 	/* Destroy all the dialogs and free their memory */
-	p = dialoglist;
+	p = dialoglist.list;
 	while (p) {
 		pl = p;
 		p = p->next;
 		__sip_destroy(pl, TRUE, TRUE);
 	}
-	dialoglist = NULL;
-	dialoglist_unlock();
+	dialoglist.list = NULL;
+	dialoglist_unlock(&dialoglist);
 
 	/* Free memory for local network address mask */
 	ast_free_ha(localaddr);




More information about the svn-commits mailing list