[asterisk-commits] twilson: branch group/v6-new r264930 - in /team/group/v6-new: ./ apps/ channe...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 20 20:23:29 CDT 2010


Author: twilson
Date: Thu May 20 20:23:24 2010
New Revision: 264930

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=264930
Log:
Merged revisions 264626,264669,264711,264752,264779,264828,264905 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r264626 | twilson | 2010-05-20 12:54:02 -0500 (Thu, 20 May 2010) | 15 lines
  
  Add support for direct media ACLs
  
  directmediapermit/directmediadeny support to restrict which peers can do
  directmedia based on ip address. In some networks not all phones are fully
  routed, i.e. not all phones can ping each other. This patch adds a way to
  restrict directmedia for certain peers between certain networks.
  
  (closes issue #16645)
  Reported by: raarts
  Patches: 
        directmediapermit.patch uploaded by raarts (license 937)
  Tested by: raarts
  
  Review: https://reviewboard.asterisk.org/r/467/
................
  r264669 | rmudgett | 2010-05-20 14:40:03 -0500 (Thu, 20 May 2010) | 15 lines
  
  Dial and queue connected line update macro not always run when expected.
  
  The connected line update macro would not get run if the connected line
  number string was empty.  The number could be empty if the connected line
  update did not update a number but the name.  It should be run if there
  was an AST_CONTROL_CONNECTED_LINE frame received for pending dials and
  queues.
  
  Renamed and added some more comments for some confusing identifiers
  directly connected to the related code.
  
  Also fixed a memory leak in app_queue.
  
  Review:	https://reviewboard.asterisk.org/r/669/
................
  r264711 | rmudgett | 2010-05-20 15:49:40 -0500 (Thu, 20 May 2010) | 2 lines
  
  Avoid crash in generic CC agent init if caller name or number is NULL.
................
  r264752 | tilghman | 2010-05-20 16:28:53 -0500 (Thu, 20 May 2010) | 7 lines
  
  Error message fix.
  
  (closes issue #17356)
   Reported by: kenner
   Patches: 
         app_stack.c.diff uploaded by kenner (license 1040)
................
  r264779 | tilghman | 2010-05-20 17:23:32 -0500 (Thu, 20 May 2010) | 8 lines
  
  Let ExtensionState resolve dynamic hints.
  
  (closes issue #16623)
   Reported by: tilghman
   Patches: 
         20100116__issue16623.diff.txt uploaded by tilghman (license 14)
   Tested by: lmadsen
................
  r264828 | rmudgett | 2010-05-20 18:29:43 -0500 (Thu, 20 May 2010) | 13 lines
  
  Merged revisions 264820 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r264820 | rmudgett | 2010-05-20 18:23:21 -0500 (Thu, 20 May 2010) | 6 lines
    
    ast_callerid_parse() had a path that left name uninitialized.
    
    Several callers of ast_callerid_parse() do not initialize the name
    parameter before calling thus there is the potential to use an
    uninitialized pointer.
  ........
................
  r264905 | twilson | 2010-05-20 20:00:44 -0500 (Thu, 20 May 2010) | 5 lines
  
  Take dup'd code for directmedia ACLs and make utility func
  
  The same code was repeated in lots of different places, so I made a utility
  fuction for it. This should make the merge in the v6-new branch easier.
................

Modified:
    team/group/v6-new/   (props changed)
    team/group/v6-new/CHANGES
    team/group/v6-new/apps/app_dial.c
    team/group/v6-new/apps/app_queue.c
    team/group/v6-new/apps/app_stack.c
    team/group/v6-new/channels/chan_sip.c
    team/group/v6-new/channels/sip/include/sip.h
    team/group/v6-new/configs/sip.conf.sample
    team/group/v6-new/main/callerid.c
    team/group/v6-new/main/ccss.c
    team/group/v6-new/main/pbx.c

Propchange: team/group/v6-new/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/v6-new/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/v6-new/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu May 20 20:23:24 2010
@@ -1,1 +1,1 @@
-/trunk:1-264552
+/trunk:1-264905

Modified: team/group/v6-new/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/CHANGES?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/CHANGES (original)
+++ team/group/v6-new/CHANGES Thu May 20 20:23:24 2010
@@ -59,6 +59,8 @@
  * When dialing SIP peers, a new component may be added to the end of the dialstring
    to indicate that a specific remote IP address or host should be used when dialing
    the particular peer. The dialstring format is SIP/peer/exten/host_or_IP.
+ * Added directmediapermit/directmediadeny to limit which peers can send direct media
+   to each other
 
 IAX2 Changes
 -----------

Modified: team/group/v6-new/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/apps/app_dial.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/apps/app_dial.c (original)
+++ team/group/v6-new/apps/app_dial.c Thu May 20 20:23:24 2010
@@ -551,7 +551,7 @@
 
 #define DIAL_STILLGOING      (1 << 31)
 #define DIAL_NOFORWARDHTML   ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
-#define DIAL_NOCONNECTEDLINE ((uint64_t)1 << 33)
+#define DIAL_CALLERID_ABSENT ((uint64_t)1 << 33) /* TRUE if caller id is not available for connected line. */
 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 34)
 #define OPT_PEER_H           ((uint64_t)1 << 35)
 #define OPT_CALLEE_GO_ON     ((uint64_t)1 << 36)
@@ -634,7 +634,10 @@
 	struct chanlist *next;
 	struct ast_channel *chan;
 	uint64_t flags;
+	/*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
 	struct ast_party_connected_line connected;
+	/*! TRUE if an AST_CONTROL_CONNECTED_LINE update was saved to the connected element. */
+	unsigned int pending_connected_update:1;
 };
 
 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
@@ -976,7 +979,7 @@
 			ast_channel_make_compatible(outgoing->chan, in);
 		}
 
-		if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_NOCONNECTEDLINE)) {
+		if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
 			ast_channel_lock(outgoing->chan);
 			ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
 			ast_channel_unlock(outgoing->chan);
@@ -1036,11 +1039,11 @@
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", c->name, in->name);
 					if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
-						if (o->connected.id.number) {
+						if (o->pending_connected_update) {
 							if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
 								ast_channel_update_connected_line(in, &o->connected);
 							}
-						} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
+						} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
 							ast_channel_lock(c);
 							ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
 							ast_channel_unlock(c);
@@ -1098,11 +1101,11 @@
 					if (!peer) {
 						ast_verb(3, "%s answered %s\n", c->name, in->name);
 						if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
-							if (o->connected.id.number) {
+							if (o->pending_connected_update) {
 								if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
 									ast_channel_update_connected_line(in, &o->connected);
 								}
-							} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
+							} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
 								ast_channel_lock(c);
 								ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
 								ast_channel_unlock(c);
@@ -1219,6 +1222,7 @@
 						ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
 						ast_party_connected_line_set(&o->connected, &connected);
 						ast_party_connected_line_free(&connected);
+						o->pending_connected_update = 1;
 					} else {
 						if (ast_channel_connected_line_macro(c, in, f, 1, 1)) {
 							ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
@@ -1918,14 +1922,13 @@
 
 		ast_channel_lock(chan);
 		datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
-		/* If the incoming channel has previously had connected line information
-		 * set on it (perhaps through the CONNECTED_LINE dialplan function) then
-		 * seed the calllist's connected line information with this previously
-		 * acquired info
+		/*
+		 * Seed the chanlist's connected line information with previously
+		 * acquired connected line info from the incoming channel.  The
+		 * previously acquired connected line info could have been set
+		 * through the CONNECTED_LINE dialplan function.
 		 */
-		if (chan->connected.id.number) {
-			ast_party_connected_line_copy(&tmp->connected, &chan->connected);
-		}
+		ast_party_connected_line_copy(&tmp->connected, &chan->connected);
 		ast_channel_unlock(chan);
 
 		if (datastore)
@@ -2034,7 +2037,7 @@
 			} else if (!ast_strlen_zero(S_OR(chan->macroexten, chan->exten))) {
 				ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), NULL, NULL);
 			}
-			ast_set_flag64(tmp, DIAL_NOCONNECTEDLINE);
+			ast_set_flag64(tmp, DIAL_CALLERID_ABSENT);
 		}
 
 		if (ast_test_flag64(peerflags, OPT_FORCECLID) && !ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {

Modified: team/group/v6-new/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/apps/app_queue.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/apps/app_queue.c (original)
+++ team/group/v6-new/apps/app_queue.c Thu May 20 20:23:24 2010
@@ -814,8 +814,12 @@
 	time_t lastcall;
 	struct call_queue *lastqueue;
 	struct member *member;
-	unsigned int update_connectedline:1;
+	/*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
 	struct ast_party_connected_line connected;
+	/*! TRUE if an AST_CONTROL_CONNECTED_LINE update was saved to the connected element. */
+	unsigned int pending_connected_update:1;
+	/*! TRUE if caller id is not available for connected line */
+	unsigned int dial_callerid_absent:1;
 };
 
 
@@ -2613,6 +2617,24 @@
 	queue_t_unref(q, "Expire copied reference");
 }
 
+/*!
+ * \internal
+ * \brief Destroy the given callattempt structure and free it.
+ * \since 1.8
+ *
+ * \param doomed callattempt structure to destroy.
+ *
+ * \return Nothing
+ */
+static void callattempt_free(struct callattempt *doomed)
+{
+	if (doomed->member) {
+		ao2_ref(doomed->member, -1);
+	}
+	ast_party_connected_line_free(&doomed->connected);
+	ast_free(doomed);
+}
+
 /*! \brief Hang up a list of outgoing calls */
 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception, int cancel_answered_elsewhere)
 {
@@ -2628,9 +2650,7 @@
 		}
 		oo = outgoing;
 		outgoing = outgoing->q_next;
-		if (oo->member)
-			ao2_ref(oo->member, -1);
-		ast_free(oo);
+		callattempt_free(oo);
 	}
 }
 
@@ -2870,7 +2890,7 @@
 		} else if (!ast_strlen_zero(S_OR(qe->chan->macroexten, qe->chan->exten))) {
 			ast_set_callerid(tmp->chan, S_OR(qe->chan->macroexten, qe->chan->exten), NULL, NULL); 
 		}
-		tmp->update_connectedline = 0;
+		tmp->dial_callerid_absent = 1;
 	}
 
 	ast_party_redirecting_copy(&tmp->chan->redirecting, &qe->chan->redirecting);
@@ -3188,7 +3208,8 @@
 }
 
 #define AST_MAX_WATCHERS 256
-/*! \brief Wait for a member to answer the call
+/*!
+ * \brief Wait for a member to answer the call
  *
  * \param[in] qe the queue_ent corresponding to the caller in the queue
  * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
@@ -3197,6 +3218,7 @@
  * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
  * \param[in] caller_disconnect if the 'H' option is used when calling Queue(), this is used to detect if the caller pressed * to disconnect the call
  * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
+ * \param[in] update_connectedline Allow connected line and redirecting updates to pass through.
  *
  * \todo eventually all call forward logic should be intergerated into and replaced by ast_call_forward()
  */
@@ -3296,11 +3318,11 @@
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
 					if (update_connectedline) {
-						if (o->connected.id.number) {
+						if (o->pending_connected_update) {
 							if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 								ast_channel_update_connected_line(in, &o->connected);
 							}
-						} else if (o->update_connectedline) {
+						} else if (!o->dial_callerid_absent) {
 							ast_channel_lock(o->chan);
 							ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
 							ast_channel_unlock(o->chan);
@@ -3415,11 +3437,11 @@
 							if (!peer) {
 								ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
 								if (update_connectedline) {
-									if (o->connected.id.number) {
+									if (o->pending_connected_update) {
 										if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 											ast_channel_update_connected_line(in, &o->connected);
 										}
-									} else if (o->update_connectedline) {
+									} else if (!o->dial_callerid_absent) {
 										ast_channel_lock(o->chan);
 										ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
 										ast_channel_unlock(o->chan);
@@ -3490,6 +3512,7 @@
 								ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
 								ast_party_connected_line_set(&o->connected, &connected);
 								ast_party_connected_line_free(&connected);
+								o->pending_connected_update = 1;
 							} else {
 								if (ast_channel_connected_line_macro(o->chan, in, f, 1, 1)) {
 									ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
@@ -4200,7 +4223,7 @@
 				ao2_iterator_destroy(&memi);
 				if (need_weight)
 					ao2_unlock(queues);
-				free(tmp);
+				callattempt_free(tmp);
 				goto out;
 			}
 			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
@@ -4210,7 +4233,7 @@
 				ao2_iterator_destroy(&memi);
 				if (need_weight)
 					ao2_unlock(queues);
-				free(tmp);
+				callattempt_free(tmp);
 				goto out;
 			}
 			datastore->data = dialed_interfaces;
@@ -4232,19 +4255,8 @@
 		}
 		AST_LIST_UNLOCK(dialed_interfaces);
 
-		ast_channel_lock(qe->chan);
-		/* If any pre-existing connected line information exists on this
-		 * channel, like from the CONNECTED_LINE dialplan function, use this
-		 * to seed the connected line information. It may, of course, be updated
-		 * during the call
-		 */
-		if (qe->chan->connected.id.number) {
-			ast_party_connected_line_copy(&tmp->connected, &qe->chan->connected);
-		}
-		ast_channel_unlock(qe->chan);
-		
 		if (di) {
-			free(tmp);
+			callattempt_free(tmp);
 			continue;
 		}
 
@@ -4259,7 +4271,7 @@
 				ao2_iterator_destroy(&memi);
 				if (need_weight)
 					ao2_unlock(queues);
-				free(tmp);
+				callattempt_free(tmp);
 				goto out;
 			}
 			strcpy(di->interface, cur->interface);
@@ -4269,11 +4281,20 @@
 			AST_LIST_UNLOCK(dialed_interfaces);
 		}
 
+		ast_channel_lock(qe->chan);
+		/*
+		 * Seed the callattempt's connected line information with previously
+		 * acquired connected line info from the queued channel.  The
+		 * previously acquired connected line info could have been set
+		 * through the CONNECTED_LINE dialplan function.
+		 */
+		ast_party_connected_line_copy(&tmp->connected, &qe->chan->connected);
+		ast_channel_unlock(qe->chan);
+
 		tmp->stillgoing = -1;
-		tmp->member = cur;
+		tmp->member = cur;/* Place the reference for cur into callattempt. */
 		tmp->lastcall = cur->lastcall;
 		tmp->lastqueue = cur->lastqueue;
-		tmp->update_connectedline = 1;
 		ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
 		/* Special case: If we ring everyone, go ahead and ring them, otherwise
 		   just calculate their metric for the appropriate strategy */
@@ -4287,8 +4308,7 @@
 			if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
 				break;
 		} else {
-			ao2_ref(cur, -1);
-			ast_free(tmp);
+			callattempt_free(tmp);
 		}
 	}
 	ao2_iterator_destroy(&memi);

Modified: team/group/v6-new/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/apps/app_stack.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/apps/app_stack.c (original)
+++ team/group/v6-new/apps/app_stack.c Thu May 20 20:23:24 2010
@@ -415,7 +415,7 @@
 
 	if (!ast_exists_extension(chan, chan->context, chan->exten, ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP) ? chan->priority + 1 : chan->priority, chan->cid.cid_num)) {
 		ast_log(LOG_ERROR, "Attempt to reach a non-existent destination for gosub: (Context:%s, Extension:%s, Priority:%d)\n",
-				chan->context, chan->exten, chan->priority);
+				chan->context, chan->exten, ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP) ? chan->priority + 1 : chan->priority);
 		ast_copy_string(chan->context, newframe->context, sizeof(chan->context));
 		ast_copy_string(chan->exten, newframe->extension, sizeof(chan->exten));
 		chan->priority = newframe->priority;

Modified: team/group/v6-new/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/chan_sip.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/channels/chan_sip.c (original)
+++ team/group/v6-new/channels/chan_sip.c Thu May 20 20:23:24 2010
@@ -4202,6 +4202,7 @@
 	
 	register_peer_exten(peer, FALSE);
 	ast_free_ha(peer->ha);
+	ast_free_ha(peer->directmediaha);
 	if (peer->selfdestruct)
 		ast_atomic_fetchadd_int(&apeerobjs, -1);
 	else if (peer->is_realtime) {
@@ -4812,6 +4813,7 @@
 		dialog->noncodeccapability |= AST_RTP_DTMF;
 	else
 		dialog->noncodeccapability &= ~AST_RTP_DTMF;
+	dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha);
 	if (peer->call_limit)
 		ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
 	if (!dialog->portinuri)
@@ -5192,6 +5194,11 @@
 	if (p->chanvars) {
 		ast_variables_destroy(p->chanvars);
 		p->chanvars = NULL;
+	}
+
+	if (p->directmediaha) {
+		ast_free_ha(p->directmediaha);
+		p->directmediaha = NULL;
 	}
 
 	ast_string_field_free_memory(p);
@@ -15491,6 +15498,7 @@
 		ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
 		ast_cli(fd, "  Force rport  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
 		ast_cli(fd, "  ACL          : %s\n", AST_CLI_YESNO(peer->ha != NULL));
+		ast_cli(fd, "  DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL));
 		ast_cli(fd, "  T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
 		ast_cli(fd, "  T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
 		ast_cli(fd, "  T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram);
@@ -24835,6 +24843,7 @@
 {
 	struct sip_peer *peer = NULL;
 	struct ast_ha *oldha = NULL;
+	struct ast_ha *olddirectmediaha = NULL;
 	int found = 0;
 	int firstpass = 1;
 	uint16_t port = 0;
@@ -24891,6 +24900,8 @@
 		peer->lastmsgssent = -1;
 		oldha = peer->ha;
 		peer->ha = NULL;
+		olddirectmediaha = peer->directmediaha;
+		peer->directmediaha = NULL;
 		set_peer_defaults(peer);	/* Set peer defaults */
 		peer->type = 0;
 	}
@@ -25047,6 +25058,12 @@
 				}
 				if (ha_error) {
 					ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
+				}
+			} else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) {
+				int ha_error = 0;
+				peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error);
+				if (ha_error) {
+					ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value);
 				}
 			} else if (!strcasecmp(v->name, "port")) {
 				peer->portinuri = 1;
@@ -25392,6 +25409,7 @@
 	peer->the_mark = 0;
 
 	ast_free_ha(oldha);
+	ast_free_ha(olddirectmediaha);
 	if (!ast_strlen_zero(callback)) { /* build string from peer info */
 		char *reg_string;
 		if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) < 0) {
@@ -26353,6 +26371,30 @@
 	return 0;
 }
 
+static int apply_directmedia_ha(struct sip_pvt *p, const char *op)
+{
+	struct ast_sockaddr us, them;
+	struct sockaddr_in them_sin;
+	int res = AST_SENSE_ALLOW;
+
+	ast_rtp_instance_get_remote_address(p->rtp, &them);
+	ast_rtp_instance_get_local_address(p->rtp, &us);
+
+	/* Currently ast_apply_ha doesn't support IPv6 */
+	if (ast_sockaddr_is_ipv6(&them)) {
+		return res;
+	}
+
+	ast_sockaddr_to_sin(&them, &them_sin);
+
+	if ((res = ast_apply_ha(p->directmediaha, &them_sin) == AST_SENSE_DENY)) {
+		ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
+			op, ast_sockaddr_stringify(&them), ast_sockaddr_stringify(&us));
+	}
+
+	return res;
+}
+
 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
 {
 	struct sip_pvt *p;
@@ -26363,8 +26405,11 @@
 		return NULL;
 	
 	sip_pvt_lock(p);
-	if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA))
-		udptl = p->udptl;
+	if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
+		if (apply_directmedia_ha(p, "UDPTL T.38 data")) {
+			udptl = p->udptl;
+		}
+	}
 	sip_pvt_unlock(p);
 	return udptl;
 }
@@ -26401,31 +26446,36 @@
 
 static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
-        struct sip_pvt *p = NULL;
-        enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
-
-        if (!(p = chan->tech_pvt)) {
-                return AST_RTP_GLUE_RESULT_FORBID;
-	}
-
-        sip_pvt_lock(p);
-        if (!(p->rtp)) {
-                sip_pvt_unlock(p);
-                return AST_RTP_GLUE_RESULT_FORBID;
-        }
+	struct sip_pvt *p = NULL;
+	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
+
+	if (!(p = chan->tech_pvt)) {
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	sip_pvt_lock(p);
+	if (!(p->rtp)) {
+		sip_pvt_unlock(p);
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
 
 	ao2_ref(p->rtp, +1);
 	*instance = p->rtp;
 
-	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT)) {
-                res = AST_RTP_GLUE_RESULT_REMOTE;
+	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
+		res = AST_RTP_GLUE_RESULT_REMOTE;
+		if (!apply_directmedia_ha(p, "audio")) {
+			res = AST_RTP_GLUE_RESULT_FORBID;
+		}
+	} else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
+		res = AST_RTP_GLUE_RESULT_REMOTE;
 	} else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
-                res = AST_RTP_GLUE_RESULT_FORBID;
-	}
-
-        sip_pvt_unlock(p);
-
-        return res;
+		res = AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	sip_pvt_unlock(p);
+
+	return res;
 }
 
 static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
@@ -26448,6 +26498,9 @@
 
 	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
 		res = AST_RTP_GLUE_RESULT_REMOTE;
+		if (!apply_directmedia_ha(p, "video")) {
+			res = AST_RTP_GLUE_RESULT_FORBID;
+		}
 	}
 
 	sip_pvt_unlock(p);
@@ -26457,105 +26510,108 @@
 
 static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
-        struct sip_pvt *p = NULL;
-        enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
-
-        if (!(p = chan->tech_pvt)) {
-                return AST_RTP_GLUE_RESULT_FORBID;
-        }
-
-        sip_pvt_lock(p);
-        if (!(p->trtp)) {
-                sip_pvt_unlock(p);
-                return AST_RTP_GLUE_RESULT_FORBID;
-        }
+	struct sip_pvt *p = NULL;
+	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
+
+	if (!(p = chan->tech_pvt)) {
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	sip_pvt_lock(p);
+	if (!(p->trtp)) {
+		sip_pvt_unlock(p);
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
 
 	ao2_ref(p->trtp, +1);
-        *instance = p->trtp;
-
-        if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
-                res = AST_RTP_GLUE_RESULT_REMOTE;
-        }
-
-        sip_pvt_unlock(p);
-
-        return res;
+	*instance = p->trtp;
+
+	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
+		res = AST_RTP_GLUE_RESULT_REMOTE;
+		if (!apply_directmedia_ha(p, "text")) {
+			res = AST_RTP_GLUE_RESULT_FORBID;
+		}
+	}
+
+	sip_pvt_unlock(p);
+
+	return res;
 }
 
 static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active)
 {
-        struct sip_pvt *p;
-        int changed = 0;
-
-        p = chan->tech_pvt;
-        if (!p)
-                return -1;
+	struct sip_pvt *p;
+	int changed = 0;
+
+	p = chan->tech_pvt;
+	if (!p)
+		return -1;
 
 	/* Disable early RTP bridge  */
 	if (!ast_bridged_channel(chan) && !sip_cfg.directrtpsetup) 	/* We are in early state */
 		return 0;
 
-        sip_pvt_lock(p);
-        if (p->alreadygone) {
-                /* If we're destroyed, don't bother */
-                sip_pvt_unlock(p);
-                return 0;
-        }
-
-        /* if this peer cannot handle reinvites of the media stream to devices
-           that are known to be behind a NAT, then stop the process now
+	sip_pvt_lock(p);
+	if (p->alreadygone) {
+		/* If we're destroyed, don't bother */
+		sip_pvt_unlock(p);
+		return 0;
+	}
+
+	/* if this peer cannot handle reinvites of the media stream to devices
+	   that are known to be behind a NAT, then stop the process now
 	*/
-        if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
-                sip_pvt_unlock(p);
-                return 0;
-        }
-
-        if (instance) {
-                changed |= ast_rtp_instance_get_remote_address(instance, &p->redirip);
-        } else if (!ast_sockaddr_isnull(&p->redirip)) {
-                memset(&p->redirip, 0, sizeof(p->redirip));
-                changed = 1;
-        }
-        if (vinstance) {
-                changed |= ast_rtp_instance_get_remote_address(vinstance, &p->vredirip);
-        } else if (!ast_sockaddr_isnull(&p->vredirip)) {
-                memset(&p->vredirip, 0, sizeof(p->vredirip));
-                changed = 1;
-        }
-        if (tinstance) {
-                changed |= ast_rtp_instance_get_remote_address(tinstance, &p->tredirip);
-        } else if (!ast_sockaddr_isnull(&p->tredirip)) {
-                memset(&p->tredirip, 0, sizeof(p->tredirip));
-                changed = 1;
-        }
-        if (codecs && (p->redircodecs != codecs)) {
-                p->redircodecs = codecs;
-                changed = 1;
-        }
-        if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
-                if (chan->_state != AST_STATE_UP) {     /* We are in early state */
-                        if (p->do_history)
-                                append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
-                        ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
-                } else if (!p->pendinginvite) {         /* We are up, and have no outstanding invite */
-                        ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
-                        transmit_reinvite_with_sdp(p, FALSE, FALSE);
-                } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
-                        ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
-                        /* We have a pending Invite. Send re-invite when we're done with the invite */
-                        ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
-                }
-        }
-        /* Reset lastrtprx timer */
-        p->lastrtprx = p->lastrtptx = time(NULL);
-        sip_pvt_unlock(p);
-        return 0;
+	if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
+		sip_pvt_unlock(p);
+		return 0;
+	}
+
+	if (instance) {
+		changed |= ast_rtp_instance_get_remote_address(instance, &p->redirip);
+	} else if (!ast_sockaddr_isnull(&p->redirip)) {
+		memset(&p->redirip, 0, sizeof(p->redirip));
+		changed = 1;
+	}
+	if (vinstance) {
+		changed |= ast_rtp_instance_get_remote_address(vinstance, &p->vredirip);
+	} else if (!ast_sockaddr_isnull(&p->vredirip)) {
+		memset(&p->vredirip, 0, sizeof(p->vredirip));
+		changed = 1;
+	}
+	if (tinstance) {
+		changed |= ast_rtp_instance_get_remote_address(tinstance, &p->tredirip);
+	} else if (!ast_sockaddr_isnull(&p->tredirip)) {
+		memset(&p->tredirip, 0, sizeof(p->tredirip));
+		changed = 1;
+	}
+	if (codecs && (p->redircodecs != codecs)) {
+		p->redircodecs = codecs;
+		changed = 1;
+	}
+	if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
+		if (chan->_state != AST_STATE_UP) {     /* We are in early state */
+			if (p->do_history)
+				append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
+			ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
+		} else if (!p->pendinginvite) {	 /* We are up, and have no outstanding invite */
+			ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
+			transmit_reinvite_with_sdp(p, FALSE, FALSE);
+		} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
+			ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
+			/* We have a pending Invite. Send re-invite when we're done with the invite */
+			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
+		}
+	}
+	/* Reset lastrtprx timer */
+	p->lastrtprx = p->lastrtptx = time(NULL);
+	sip_pvt_unlock(p);
+	return 0;
 }
 
 static format_t sip_get_codec(struct ast_channel *chan)
 {
 	struct sip_pvt *p = chan->tech_pvt;
-        return p->peercapability ? p->peercapability : p->capability;
+	return p->peercapability ? p->peercapability : p->capability;
 }
 
 static struct ast_rtp_glue sip_rtp_glue = {

Modified: team/group/v6-new/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/sip/include/sip.h?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/channels/sip/include/sip.h (original)
+++ team/group/v6-new/channels/sip/include/sip.h Thu May 20 20:23:24 2010
@@ -997,6 +997,7 @@
 	time_t lastrtprx;                   /*!< Last RTP received */
 	time_t lastrtptx;                   /*!< Last RTP sent */
 	int rtptimeout;                     /*!< RTP timeout time */
+	struct ast_ha *directmediaha;		/*!< Which IPs are allowed to interchange direct media with this peer - copied from sip_peer */
 	struct ast_sockaddr recv;            /*!< Received as */
 	struct ast_sockaddr ourip;           /*!< Our IP (as seen from the outside) */
 	enum transfermodes allowtransfer;   /*!< REFER: restriction scheme */
@@ -1196,6 +1197,7 @@
 	struct ast_sockaddr defaddr;     /*!<  Default IP address, used until registration */
 	struct ast_ha *ha;              /*!<  Access control list */
 	struct ast_ha *contactha;       /*!<  Restrict what IPs are allowed in the Contact header (for registration) */
+	struct ast_ha *directmediaha;   /*!<  Restrict what IPs are allowed to interchange direct media with */
 	struct ast_variable *chanvars;  /*!<  Variables to set for channel created by user */
 	struct sip_pvt *mwipvt;         /*!<  Subscription for MWI */
 	struct sip_st_cfg stimer;       /*!<  SIP Session-Timers */

Modified: team/group/v6-new/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/configs/sip.conf.sample?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/configs/sip.conf.sample (original)
+++ team/group/v6-new/configs/sip.conf.sample Thu May 20 20:23:24 2010
@@ -785,6 +785,13 @@
                                 ; RTP payloads and fmtp headers in the 200 OK that does not match the
                                 ; callers INVITE. This will also fail if directmedia is enabled when
                                 ; the device is actually behind NAT.
+
+;directmediadeny=0.0.0.0/0      ; Use directmediapermit and directmediadeny to restrict 
+;directmediapermit=172.16.0.0/16; which peers should be able to pass directmedia to each other
+                                ; (There is no default setting, this is just an example)
+                                ; Use this if some of your phones are on IP addresses that
+                                ; can not reach each other directly. This way you can force 
+                                ; RTP to always flow through asterisk in such cases.
 
 ;ignoresdpversion=yes           ; By default, Asterisk will honor the session version
                                 ; number in SDP packets and will only modify the SDP
@@ -1017,6 +1024,8 @@
 ; contactdeny           ; is to register at the same IP as a SIP provider,
 ;                       ; then call oneself, and get redirected to that
 ;                       ; same location).
+; directmediapermit
+; directmediadeny
 ; unsolicited_mailbox
 ; use_q850_reason
 

Modified: team/group/v6-new/main/callerid.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/main/callerid.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/main/callerid.c (original)
+++ team/group/v6-new/main/callerid.c Thu May 20 20:23:24 2010
@@ -1008,6 +1008,8 @@
 				*ns = '\0';
 				*name = ns + 1;
 				ast_trim_blanks(*name);
+			} else {
+				*name = NULL;
 			}
 		} else { /* no quotes, trim off leading and trailing spaces */
 			*name = ast_skip_blanks(instr);

Modified: team/group/v6-new/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/main/ccss.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/main/ccss.c (original)
+++ team/group/v6-new/main/ccss.c Thu May 20 20:23:24 2010
@@ -2339,8 +2339,12 @@
 	}
 
 	generic_pvt->offer_timer_id = -1;
-	ast_copy_string(generic_pvt->cid_num, chan->cid.cid_num, sizeof(generic_pvt->cid_num));
-	ast_copy_string(generic_pvt->cid_name, chan->cid.cid_name, sizeof(generic_pvt->cid_name));
+	if (chan->cid.cid_num) {
+		ast_copy_string(generic_pvt->cid_num, chan->cid.cid_num, sizeof(generic_pvt->cid_num));
+	}
+	if (chan->cid.cid_name) {
+		ast_copy_string(generic_pvt->cid_name, chan->cid.cid_name, sizeof(generic_pvt->cid_name));
+	}
 	ast_copy_string(generic_pvt->exten, S_OR(chan->macroexten, chan->exten), sizeof(generic_pvt->exten));
 	ast_copy_string(generic_pvt->context, S_OR(chan->macrocontext, chan->context), sizeof(generic_pvt->context));
 	agent->private_data = generic_pvt;

Modified: team/group/v6-new/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/main/pbx.c?view=diff&rev=264930&r1=264929&r2=264930
==============================================================================
--- team/group/v6-new/main/pbx.c (original)
+++ team/group/v6-new/main/pbx.c Thu May 20 20:23:24 2010
@@ -4195,6 +4195,17 @@
 		return -1;                   /* No hint, return -1 */
 	}
 
+	if (e->exten[0] == '_') {
+		/* Create this hint on-the-fly */
+		ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
+			e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
+			e->registrar);
+		if (!(e = ast_hint_extension(c, context, exten))) {
+			/* Improbable, but not impossible */
+			return -1;
+		}
+	}
+
 	return ast_extension_state2(e);  /* Check all devices in the hint */
 }
 




More information about the asterisk-commits mailing list