[asterisk-commits] file: branch 1.2-netsec r42081 - in /branches/1.2-netsec: ./ apps/ channels/ ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Sep 5 16:48:48 MST 2006


Author: file
Date: Tue Sep  5 18:48:48 2006
New Revision: 42081

URL: http://svn.digium.com/view/asterisk?rev=42081&view=rev
Log:
Merged revisions 41768,41827,41830,41880,41882,41989,42014,42054 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r41768 | file | 2006-09-01 18:49:07 -0400 (Fri, 01 Sep 2006) | 2 lines

Only wipe the redirected audio & video IP/port if it's specified, and trigger a reinvite.

........
r41827 | bweschke | 2006-09-03 10:16:08 -0400 (Sun, 03 Sep 2006) | 3 lines

 Setting a retry of 0 is generally not a good idea and shouldn't be allowed. (#7574 - reported by regin)


........
r41830 | bweschke | 2006-09-03 10:50:59 -0400 (Sun, 03 Sep 2006) | 3 lines

 Let's NOT spy on Zap/psuedo channels, mmmmmmmmk? 


........
r41880 | bweschke | 2006-09-03 13:13:38 -0400 (Sun, 03 Sep 2006) | 3 lines

 Don't keep trying the same member in certain strategies when members of the queue are unavailable (#7278 - diLLec reported and patched) - This should have been patched here first and then merged into /trunk. My bad!


........
r41882 | bweschke | 2006-09-03 13:38:22 -0400 (Sun, 03 Sep 2006) | 3 lines

 Make sure the forwarded channel inherits variables appropriately when we receive a call forward in the queue. (#7867 - raarts reported and patched)


........
r41989 | oej | 2006-09-04 11:46:07 -0400 (Mon, 04 Sep 2006) | 2 lines

Don't kill the pvt before we have sent ACK on CANCEL (needs more testing before making a release)

........
r42014 | qwell | 2006-09-05 12:27:46 -0400 (Tue, 05 Sep 2006) | 4 lines

Small typo in zapata.conf.sample

Reported by ppyy in 7881

........
r42054 | file | 2006-09-05 16:02:48 -0400 (Tue, 05 Sep 2006) | 2 lines

Merge in last round of spy fixes. This should hopefully eliminate all the issues people have been seeing by distinctly separating what each component (core/spy) is responsible for. Core is responsible for adding a spy to a channel, feeding frames to the spy, removing the spy from a channel, and telling the spy to stop. Spy is responsible for reading frames in, and cleaning up after itself.

........

Modified:
    branches/1.2-netsec/   (props changed)
    branches/1.2-netsec/apps/app_chanspy.c
    branches/1.2-netsec/apps/app_mixmonitor.c
    branches/1.2-netsec/apps/app_queue.c
    branches/1.2-netsec/channel.c
    branches/1.2-netsec/channels/chan_sip.c
    branches/1.2-netsec/configs/zapata.conf.sample
    branches/1.2-netsec/include/asterisk/chanspy.h

Propchange: branches/1.2-netsec/
------------------------------------------------------------------------------
    automerge = *

Propchange: branches/1.2-netsec/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Sep  5 18:48:48 2006
@@ -1,1 +1,1 @@
-/branches/1.2:1-41733
+/branches/1.2:1-42080

Modified: branches/1.2-netsec/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/apps/app_chanspy.c?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/apps/app_chanspy.c (original)
+++ branches/1.2-netsec/apps/app_chanspy.c Tue Sep  5 18:48:48 2006
@@ -131,7 +131,7 @@
 	ast_mutex_lock(&modlock);
 	chan = local_channel_walk(NULL);
 	while (chan) {
-		if (!strncmp(chan->name, name, strlen(name))) {
+		if (!strncmp(chan->name, name, strlen(name)) && strncmp(chan->name, "Zap/pseudo", 10)) {
 			ret = chan;
 			break;
 		}
@@ -206,21 +206,6 @@
 
 	return res;
 }
-
-static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy) 
-{
-	/* If our status has changed to DONE, then the channel we're spying on is gone....
-	   DON'T TOUCH IT!!!  RUN AWAY!!! */
-	if (spy->status == CHANSPY_DONE)
-		return;
-
-	if (!chan)
-		return;
-
-	ast_mutex_lock(&chan->lock);
-	ast_channel_spy_remove(chan, spy);
-	ast_mutex_unlock(&chan->lock);
-};
 
 /* Map 'volume' levels from -4 through +4 into
    decibel (dB) settings for channel drivers
@@ -338,7 +323,13 @@
 			}
 		}
 		ast_deactivate_generator(chan);
-		stop_spying(spyee, &csth.spy);
+
+		if (csth.spy.chan) {
+			csth.spy.status = CHANSPY_DONE;
+			ast_mutex_lock(&csth.spy.chan->lock);
+			ast_channel_spy_remove(csth.spy.chan, &csth.spy);
+			ast_mutex_unlock(&csth.spy.chan->lock);
+		}
 
 		if (option_verbose >= 2) {
 			ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name);
@@ -347,7 +338,7 @@
 		running = 0;
 	}
 
-	ast_mutex_destroy(&csth.spy.lock);
+	ast_channel_spy_free(&csth.spy);
 
 	return running;
 }

Modified: branches/1.2-netsec/apps/app_mixmonitor.c
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/apps/app_mixmonitor.c?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/apps/app_mixmonitor.c (original)
+++ branches/1.2-netsec/apps/app_mixmonitor.c Tue Sep  5 18:48:48 2006
@@ -109,23 +109,6 @@
 	AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
 });
 
-static void stopmon(struct ast_channel_spy *spy) 
-{
-	struct ast_channel *chan = spy->chan;
-
-	/* If our status has changed to DONE, then the channel we're spying on is gone....
-	   DON'T TOUCH IT!!!  RUN AWAY!!! */
-	if (spy->status == CHANSPY_DONE)
-		return;
-  
-	if (!chan)
-		return;
-
-	ast_mutex_lock(&chan->lock);
-	ast_channel_spy_remove(chan, spy);
-	ast_mutex_unlock(&chan->lock);
-}
-
 static int startmon(struct ast_channel *chan, struct ast_channel_spy *spy) 
 {
 	struct ast_channel *peer;
@@ -164,9 +147,8 @@
 
 		ast_channel_spy_trigger_wait(&mixmonitor->spy);
 		
-		if (!mixmonitor->spy.chan || mixmonitor->spy.status != CHANSPY_RUNNING) {
+		if (!mixmonitor->spy.chan || mixmonitor->spy.status != CHANSPY_RUNNING)
 			break;
-		}
 		
 		while (1) {
 			if (!(f = ast_channel_spy_read_frame(&mixmonitor->spy, SAMPLES_PER_FRAME)))
@@ -189,7 +171,7 @@
 
 	ast_mutex_unlock(&mixmonitor->spy.lock);
 	
-	stopmon(&mixmonitor->spy);
+	ast_channel_spy_free(&mixmonitor->spy);
 
 	if (option_verbose > 1)
 		ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
@@ -199,8 +181,6 @@
 			ast_verbose(VERBOSE_PREFIX_2 "Executing [%s]\n", mixmonitor->post_process);
 		ast_safe_system(mixmonitor->post_process);
 	}
-
-	ast_mutex_destroy(&mixmonitor->spy.lock);
 		
 	ast_closestream(mixmonitor->fs);
 

Modified: branches/1.2-netsec/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/apps/app_queue.c?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/apps/app_queue.c (original)
+++ branches/1.2-netsec/apps/app_queue.c Tue Sep  5 18:48:48 2006
@@ -777,7 +777,7 @@
 		q->periodicannouncefrequency = atoi(val);
 	} else if (!strcasecmp(param, "retry")) {
 		q->retry = atoi(val);
-		if (q->retry < 0)
+		if (q->retry <= 0)
 			q->retry = DEFAULT_RETRY;
 	} else if (!strcasecmp(param, "wrapuptime")) {
 		q->wrapuptime = atoi(val);
@@ -1518,6 +1518,11 @@
 			ast_cdr_busy(qe->chan->cdr);
 		tmp->stillgoing = 0;
 		update_dial_status(qe->parent, tmp->member, status);
+
+		ast_mutex_lock(&qe->parent->lock);
+		qe->parent->rrpos++;
+		ast_mutex_unlock(&qe->parent->lock);
+
 		(*busies)++;
 		return 0;
 	} else if (status != tmp->oldstatus) 
@@ -1824,6 +1829,7 @@
 						o->stillgoing = 0;
 						numnochan++;
 					} else {
+						ast_channel_inherit_variables(in, o->chan);
 						if (o->chan->cid.cid_num)
 							free(o->chan->cid.cid_num);
 						o->chan->cid.cid_num = NULL;

Modified: branches/1.2-netsec/channel.c
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/channel.c?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/channel.c (original)
+++ branches/1.2-netsec/channel.c Tue Sep  5 18:48:48 2006
@@ -1017,22 +1017,59 @@
 	return 0;
 }
 
+/* Clean up a channel's spy information */
+static void spy_cleanup(struct ast_channel *chan)
+{
+	if (AST_LIST_EMPTY(&chan->spies->list))
+		return;
+	if (chan->spies->read_translator.path)
+		ast_translator_free_path(chan->spies->read_translator.path);
+	if (chan->spies->write_translator.path)
+		ast_translator_free_path(chan->spies->write_translator.path);
+	free(chan->spies);
+	chan->spies = NULL;
+	return;
+}
+
+/* Detach a spy from it's channel */
+static void spy_detach(struct ast_channel_spy *spy, struct ast_channel *chan)
+{
+	ast_mutex_lock(&spy->lock);
+
+	/* We only need to poke them if they aren't already done */
+	if (spy->status != CHANSPY_DONE) {
+		spy->status = CHANSPY_STOP;
+		spy->chan = NULL;
+		if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
+			ast_cond_signal(&spy->trigger);
+	}
+	
+	/* Print it out while we still have a lock so the structure can't go away (if signalled above) */
+	ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
+
+	ast_mutex_unlock(&spy->lock);
+
+	return;
+}
+
 void ast_channel_spy_stop_by_type(struct ast_channel *chan, const char *type)
 {
-	struct ast_channel_spy *spy;
+	struct ast_channel_spy *spy = NULL;
 	
 	if (!chan->spies)
 		return;
 
-	AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
 		ast_mutex_lock(&spy->lock);
 		if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
-			spy->status = CHANSPY_STOP;
-			if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
-				ast_cond_signal(&spy->trigger);
-		}
-		ast_mutex_unlock(&spy->lock);
-	}
+			ast_mutex_unlock(&spy->lock);
+			AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
+			spy_detach(spy, chan);
+		} else
+			ast_mutex_unlock(&spy->lock);
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+	spy_cleanup(chan);
 }
 
 void ast_channel_spy_trigger_wait(struct ast_channel_spy *spy)
@@ -1049,65 +1086,59 @@
 
 void ast_channel_spy_remove(struct ast_channel *chan, struct ast_channel_spy *spy)
 {
-	struct ast_frame *f;
-
 	if (!chan->spies)
 		return;
 
 	AST_LIST_REMOVE(&chan->spies->list, spy, list);
 
-	ast_mutex_lock(&spy->lock);
-
-	spy->chan = NULL;
-
-	for (f = spy->read_queue.head; f; f = spy->read_queue.head) {
-		spy->read_queue.head = f->next;
-		ast_frfree(f);
-	}
+	spy_detach(spy, chan);
+	spy_cleanup(chan);
+}
+
+void ast_channel_spy_free(struct ast_channel_spy *spy)
+{
+	struct ast_frame *f = NULL;
+
+	if (spy->status == CHANSPY_DONE)
+		return;
+
+	/* Switch status to done in case we get called twice */
+	spy->status = CHANSPY_DONE;
+
+	/* Drop any frames in the queue */
 	for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
 		spy->write_queue.head = f->next;
 		ast_frfree(f);
 	}
-
+	for (f = spy->read_queue.head; f; f= spy->read_queue.head) {
+		spy->read_queue.head = f->next;
+		ast_frfree(f);
+	}
+
+	/* Destroy the condition if in use */
 	if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
 		ast_cond_destroy(&spy->trigger);
 
-	ast_mutex_unlock(&spy->lock);
-
-	ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n",
-		spy->type, chan->name);
-
-	if (AST_LIST_EMPTY(&chan->spies->list)) {
-		if (chan->spies->read_translator.path)
-			ast_translator_free_path(chan->spies->read_translator.path);
-		if (chan->spies->write_translator.path)
-			ast_translator_free_path(chan->spies->write_translator.path);
-		free(chan->spies);
-		chan->spies = NULL;
-	}
+	/* Destroy our mutex since it is no longer in use */
+	ast_mutex_destroy(&spy->lock);
+
+	return;
 }
 
 static void detach_spies(struct ast_channel *chan) 
 {
-	struct ast_channel_spy *spy;
+	struct ast_channel_spy *spy = NULL;
 
 	if (!chan->spies)
 		return;
 
-	/* Marking the spies as done is sufficient.  Chanspy or spy users will get the picture. */
-	AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
-		ast_mutex_lock(&spy->lock);
-		spy->chan = NULL;
-		if (spy->status == CHANSPY_RUNNING)
-			spy->status = CHANSPY_DONE;
-		if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
-			ast_cond_signal(&spy->trigger);
-		ast_mutex_unlock(&spy->lock);
-	}
-
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list)
-		ast_channel_spy_remove(chan, spy);
-	AST_LIST_TRAVERSE_SAFE_END;
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
+		AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
+		spy_detach(spy, chan);
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+
+	spy_cleanup(chan);
 }
 
 /*--- ast_softhangup_nolock: Softly hangup a channel, don't lock */

Modified: branches/1.2-netsec/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/channels/chan_sip.c?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/channels/chan_sip.c (original)
+++ branches/1.2-netsec/channels/chan_sip.c Tue Sep  5 18:48:48 2006
@@ -2447,7 +2447,7 @@
 {
 	struct sip_pvt *p = ast->tech_pvt;
 	int needcancel = 0;
-	struct ast_flags locflags = {0};
+	int needdestroy = 0;
 
 	if (!p) {
 		ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
@@ -2481,7 +2481,6 @@
 #endif
 
 	/* Disconnect */
-	p = ast->tech_pvt;
 	if (p->vad) {
 		ast_dsp_free(p->vad);
 	}
@@ -2493,7 +2492,16 @@
 	ast_mutex_unlock(&usecnt_lock);
 	ast_update_use_count();
 
-	ast_set_flag(&locflags, SIP_NEEDDESTROY);	
+	/* Do not destroy this pvt until we have timeout or
+	   get an answer to the BYE or INVITE/CANCEL 
+	   If we get no answer during retransmit period, drop the call anyway.
+	   (Sorry, mother-in-law, you can't deny a hangup by sending
+	   603 declined to BYE...)
+	*/
+	if (ast_test_flag(p, SIP_ALREADYGONE))
+		needdestroy = 1;	/* Set destroy flag at end of this function */
+	else
+		sip_scheddestroy(p, 32000);
 
 	/* Start the process if it's not already started */
 	if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
@@ -2506,13 +2514,12 @@
 				   it pending */
 				if (!ast_test_flag(p, SIP_CAN_BYE)) {
 					ast_set_flag(p, SIP_PENDINGBYE);
+					/* Do we need a timer here if we don't hear from them at all? */
 				} else {
 					/* Send a new request: CANCEL */
 					transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
 					/* Actually don't destroy us yet, wait for the 487 on our original 
 					   INVITE, but do set an autodestruct just in case we never get it. */
-					ast_clear_flag(&locflags, SIP_NEEDDESTROY);
-					sip_scheddestroy(p, 32000);
 				}
 				if ( p->initid != -1 ) {
 					/* channel still up - reverse dec of inUse counter
@@ -2538,7 +2545,8 @@
 			}
 		}
 	}
-	ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY);	
+	if (needdestroy)
+		ast_set_flag(p, SIP_NEEDDESTROY);
 	ast_mutex_unlock(&p->lock);
 	return 0;
 }
@@ -10085,6 +10093,9 @@
 				handle_response_invite(p, resp, rest, req, ignore, seqno);
 			} else if (sipmethod == SIP_REGISTER) {
 				res = handle_response_register(p, resp, rest, req, ignore, seqno);
+			} else if (sipmethod == SIP_BYE) {
+				/* Ok, we're ready to go */
+				ast_set_flag(p, SIP_NEEDDESTROY);	
 			} 
 			break;
 		case 401: /* Not www-authorized on SIP method */
@@ -10236,8 +10247,11 @@
 				handle_response_invite(p, resp, rest, req, ignore, seqno);
 			} else if (sipmethod == SIP_CANCEL) {
 				ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
-			} else if (sipmethod == SIP_MESSAGE)
+			} else if (sipmethod == SIP_MESSAGE) 
 				/* We successfully transmitted a message */
+				ast_set_flag(p, SIP_NEEDDESTROY);	
+			else if (sipmethod == SIP_BYE) 
+				/* Ok, we're ready to go */
 				ast_set_flag(p, SIP_NEEDDESTROY);	
 			break;
 		case 401:	/* www-auth */
@@ -10924,10 +10938,15 @@
 			if (p->owner)
 				ast_queue_hangup(p->owner);
 		}
-	} else if (p->owner)
+	} else if (p->owner) {
 		ast_queue_hangup(p->owner);
-	else
+		if (option_debug > 2)
+			ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n.");
+	} else {
 		ast_set_flag(p, SIP_NEEDDESTROY);	
+		if (option_debug > 2)
+			ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n.");
+	}
 	transmit_response(p, "200 OK", req);
 
 	return 1;
@@ -13057,24 +13076,26 @@
 	if (!p) 
 		return -1;
 	ast_mutex_lock(&p->lock);
-		if (rtp) {
+	if (rtp) {
 		changed |= ast_rtp_get_peer(rtp, &p->redirip);
 #ifdef SIP_MIDCOM
 		if (m_cb)
-		  m_cb->ast_rtp_get_their_nat_audio_hook(rtp, p->r);
+			m_cb->ast_rtp_get_their_nat_audio_hook(rtp, p->r);
 #endif
-		}
-	else
+	} else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
 		memset(&p->redirip, 0, sizeof(p->redirip));
-		if (vrtp) {
+		changed = 1;
+	}
+	if (vrtp) {
 		changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
 #ifdef SIP_MIDCOM
 		if (m_cb)
-		  m_cb->ast_rtp_get_their_nat_video_hook(vrtp, p->r);
+			m_cb->ast_rtp_get_their_nat_video_hook(vrtp, p->r);
 #endif
-		}
-	else
+	} else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
 		memset(&p->vredirip, 0, sizeof(p->vredirip));
+		changed = 1;
+	}
 	if (codecs && (p->redircodecs != codecs)) {
 		p->redircodecs = codecs;
 		changed = 1;

Modified: branches/1.2-netsec/configs/zapata.conf.sample
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/configs/zapata.conf.sample?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/configs/zapata.conf.sample (original)
+++ branches/1.2-netsec/configs/zapata.conf.sample Tue Sep  5 18:48:48 2006
@@ -16,7 +16,7 @@
 ; Trunk groups are used for NFAS or GR-303 connections.
 ;
 ; Group: Defines a trunk group.  
-;        group => <trunkgroup>,<dchannel>[,<backup1>...]
+;        trunkgroup => <trunkgroup>,<dchannel>[,<backup1>...]
 ;
 ;        trunkgroup  is the numerical trunk group to create
 ;        dchannel    is the zap channel which will have the 

Modified: branches/1.2-netsec/include/asterisk/chanspy.h
URL: http://svn.digium.com/view/asterisk/branches/1.2-netsec/include/asterisk/chanspy.h?rev=42081&r1=42080&r2=42081&view=diff
==============================================================================
--- branches/1.2-netsec/include/asterisk/chanspy.h (original)
+++ branches/1.2-netsec/include/asterisk/chanspy.h Tue Sep  5 18:48:48 2006
@@ -95,6 +95,15 @@
 void ast_channel_spy_remove(struct ast_channel *chan, struct ast_channel_spy *spy);
 
 /*!
+  \brief Free a spy.
+  \param spy The spy to free
+  \return nothing
+
+  Note: This function MUST NOT be called with the spy locked.
+*/
+void ast_channel_spy_free(struct ast_channel_spy *spy);
+
+/*!
   \brief Find all spies of a particular type on a channel and stop them.
   \param chan The channel to operate on
   \param type A character string identifying the type of spies to be stopped



More information about the asterisk-commits mailing list