[svn-commits] mmichelson: branch group/CCSS r256507 - in /team/group/CCSS: ./ channels/ fun...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Apr 9 10:22:30 CDT 2010


Author: mmichelson
Date: Fri Apr  9 10:22:27 2010
New Revision: 256507

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=256507
Log:
Resolve conflict AND reset the auuo..mer


Added:
    team/group/CCSS/funcs/func_srv.c
      - copied unchanged from r256485, trunk/funcs/func_srv.c
Modified:
    team/group/CCSS/   (props changed)
    team/group/CCSS/CHANGES
    team/group/CCSS/channels/chan_sip.c
    team/group/CCSS/include/asterisk/srv.h
    team/group/CCSS/main/srv.c

Propchange: team/group/CCSS/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Apr  9 10:22:27 2010
@@ -1,1 +1,1 @@
-/trunk:1-256429
+/trunk:1-256505

Modified: team/group/CCSS/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/CHANGES?view=diff&rev=256507&r1=256506&r2=256507
==============================================================================
--- team/group/CCSS/CHANGES (original)
+++ team/group/CCSS/CHANGES Fri Apr  9 10:22:27 2010
@@ -56,6 +56,9 @@
  * Added 'use_q850_reason' configuration option for generating and parsing
    if available  Reason: Q.850;cause=<cause code> header. It is implemented
    in some gateways for better passing PRI/SS7 cause codes via SIP.
+ * 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.
 
 IAX2 Changes
 -----------
@@ -146,6 +149,10 @@
 
 Dialplan Functions
 ------------------
+ * SRVQUERY and SRVRESULT functions added. This can be used to query and iterate
+   over SRV records associated with a specific service. From the CLI, type
+   'core show function SRVQUERY' and 'core show function SRVRESULT' for more
+   details on how these may be used.
  * PITCH_SHIFT dialplan function added. This function can be used to modify the
    pitch of a channel's tx and rx audio streams.
  * Added new dialplan functions CONNECTEDLINE and REDIRECTING which permits

Modified: team/group/CCSS/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_sip.c?view=diff&rev=256507&r1=256506&r2=256507
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Fri Apr  9 10:22:27 2010
@@ -1518,7 +1518,7 @@
 static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
 static void build_via(struct sip_pvt *p);
 static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
-static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog);
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog, struct sockaddr_in *remote_address);
 static char *generate_random_string(char *buf, size_t size);
 static void build_callid_pvt(struct sip_pvt *pvt);
 static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
@@ -4820,7 +4820,7 @@
 /*! \brief create address structure from device name
  *      Or, if peer not found, find it in the global DNS
  *      returns TRUE (-1) on failure, FALSE on success */
-static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog)
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog, struct sockaddr_in *remote_address)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -4848,7 +4848,9 @@
 			set_socket_transport(&dialog->socket, 0);
 		}
 		res = create_addr_from_peer(dialog, peer);
-		if (!ast_strlen_zero(port)) {
+		if (remote_address && remote_address->sin_addr.s_addr) {
+			dialog->sa = dialog->recv = *remote_address;
+		} else if (!ast_strlen_zero(port)) {
 			if ((portno = atoi(port))) {
 				dialog->sa.sin_port = dialog->recv.sin_port = htons(portno);
 			}
@@ -10840,7 +10842,7 @@
 	}
 	
 	/* Setup the destination of our subscription */
-	if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) {
+	if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) {
 		dialog_unlink_all(mwi->call, TRUE, TRUE);
 		mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
 		return 0;
@@ -11278,7 +11280,7 @@
 		return 0;
 	}
 
-	if (create_addr(p, channame, NULL, 0)) {
+	if (create_addr(p, channame, NULL, 0, NULL)) {
 		/* Maybe they're not registered, etc. */
 		dialog_unlink_all(p, TRUE, TRUE);
 		dialog_unref(p, "unref dialog inside for loop" );
@@ -11581,7 +11583,7 @@
 			r->us.sin_port = htons(r->portno);
 
 		/* Find address to hostname */
-		if (create_addr(p, r->hostname, &r->us, 0)) {
+		if (create_addr(p, r->hostname, &r->us, 0, NULL)) {
 			/* we have what we hope is a temporary network error,
 			 * probably DNS.  We need to reschedule a registration try */
 			dialog_unlink_all(p, TRUE, TRUE);
@@ -16976,7 +16978,7 @@
 			return CLI_FAILURE;
 		}
 
-		if (create_addr(p, a->argv[i], NULL, 1)) {
+		if (create_addr(p, a->argv[i], NULL, 1, NULL)) {
 			/* Maybe they're not registered, etc. */
 			dialog_unlink_all(p, TRUE, TRUE);
 			dialog_unref(p, "unref dialog inside for loop" );
@@ -24091,13 +24093,20 @@
 	char tmp[256];
 	char *dest = data;
 	char *dnid;
- 	char *secret = NULL;
- 	char *md5secret = NULL;
- 	char *authname = NULL;
+	char *secret = NULL;
+	char *md5secret = NULL;
+	char *authname = NULL;
 	char *trans = NULL;
 	char dialstring[256];
+	char *remote_address;
 	enum sip_transport transport = 0;
+	struct sockaddr_in remote_address_sin = { .sin_family = AF_INET };
 	format_t oldformat = format;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(peerorhost);
+		AST_APP_ARG(exten);
+		AST_APP_ARG(remote_address);
+	);
 
 	/* mask request with some set of allowed formats.
 	 * XXX this needs to be fixed.
@@ -24137,7 +24146,6 @@
 	/* Save the destination, the SIP dial string */
 	ast_copy_string(tmp, dest, sizeof(tmp));
 
-
 	/* Find DNID and take it away */
 	dnid = strchr(tmp, '!');
 	if (dnid != NULL) {
@@ -24145,11 +24153,14 @@
 		ast_string_field_set(p, todnid, dnid);
 	}
 
+	/* Divvy up the items separated by slashes */
+	AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
+
 	/* Find at sign - @ */
-	host = strchr(tmp, '@');
+	host = strchr(args.peerorhost, '@');
 	if (host) {
 		*host++ = '\0';
-		ext = tmp;
+		ext = args.peerorhost;
 		secret = strchr(ext, ':');
 	}
 	if (secret) {
@@ -24180,10 +24191,37 @@
 	}
 
 	if (!host) {
-		ext = strchr(tmp, '/');
-		if (ext)
-			*ext++ = '\0';
-		host = tmp;
+		ext = args.exten;
+		host = args.peerorhost;
+		remote_address = args.remote_address;
+	} else {
+		remote_address = args.remote_address;
+		if (!ast_strlen_zero(args.exten)) {
+			ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten);
+		}
+	}
+
+	if (!ast_strlen_zero(remote_address)) {
+		struct hostent *hp;
+		struct ast_hostent ahp;
+		char *port;
+		unsigned short port_num = transport & SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+
+		port = strchr(remote_address, ':');
+		if (port) {
+			*port++ = '\0';
+			if (sscanf(port, "%hu", &port_num) != 1) {
+				ast_log(LOG_WARNING, "Invalid port number provided in remote address. Using %hu\n", port_num);
+			}
+		}
+
+		hp = ast_gethostbyname(remote_address, &ahp);
+		if (!hp) {
+			ast_log(LOG_WARNING, "Unable to find IP address for host %s. We will not use this remote IP address\n", remote_address);
+		} else {
+			memcpy(&remote_address_sin.sin_addr, hp->h_addr, sizeof(remote_address_sin.sin_addr));
+			remote_address_sin.sin_port = htons(port_num);
+		}
 	}
 
 	set_socket_transport(&p->socket, transport);
@@ -24193,7 +24231,7 @@
 		ext = extension (user part of URI)
 		dnid = destination of the call (applies to the To: header)
 	*/
-	if (create_addr(p, host, NULL, 1)) {
+	if (create_addr(p, host, NULL, 1, &remote_address_sin)) {
 		*cause = AST_CAUSE_UNREGISTERED;
 		ast_debug(3, "Cant create SIP call - target device not registered\n");
 		dialog_unlink_all(p, TRUE, TRUE);

Modified: team/group/CCSS/include/asterisk/srv.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/srv.h?view=diff&rev=256507&r1=256506&r2=256507
==============================================================================
--- team/group/CCSS/include/asterisk/srv.h (original)
+++ team/group/CCSS/include/asterisk/srv.h Fri Apr  9 10:22:27 2010
@@ -61,4 +61,39 @@
 */
 extern int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service);
 
+/*!
+ * \brief Get the number of records for a given SRV context
+ *
+ * \details
+ * This is meant to be used after calling ast_srv_lookup, so that
+ * one may retrieve the number of records returned during a specific
+ * SRV lookup.
+ *
+ * \param context The context returned by ast_srv_lookup
+ * \return Number of records in context
+ */
+unsigned int ast_srv_get_record_count(struct srv_context *context);
+
+/*!
+ * \brief Retrieve details from a specific SRV record
+ *
+ * \details
+ * After calling ast_srv_lookup, the srv_context will contain
+ * the data from several records. You can retrieve the data
+ * of a specific one by asking for a specific record number. The
+ * records are sorted based on priority and secondarily based on
+ * weight. See RFC 2782 for the exact sorting rules.
+ *
+ * \param context The context returned by ast_srv_lookup
+ * \param record_num The 1-indexed record number to retrieve
+ * \param[out] host The host portion of the record
+ * \param[out] port The port portion of the record
+ * \param[out] priority The priority portion of the record
+ * \param[out] weight The weight portion of the record
+ * \retval -1 Failed to retrieve information. Likely due to an out of
+ * range record_num
+ * \retval 0 Success
+ */
+int ast_srv_get_nth_record(struct srv_context *context, int record_num, const char **host,
+		unsigned short *port, unsigned short *priority, unsigned short *weight);
 #endif /* _ASTERISK_SRV_H */

Modified: team/group/CCSS/main/srv.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/srv.c?view=diff&rev=256507&r1=256506&r2=256507
==============================================================================
--- team/group/CCSS/main/srv.c (original)
+++ team/group/CCSS/main/srv.c Fri Apr  9 10:22:27 2010
@@ -65,6 +65,7 @@
 struct srv_context {
 	unsigned int have_weights:1;
 	struct srv_entry *prev;
+	unsigned int num_records;
 	AST_LIST_HEAD_NOLOCK(srv_entries, srv_entry) entries;
 };
 
@@ -221,6 +222,9 @@
 		(*context)->prev = AST_LIST_FIRST(&(*context)->entries);
 		*host = (*context)->prev->host;
 		*port = (*context)->prev->port;
+		AST_LIST_TRAVERSE(&(*context)->entries, cur, list) {
+			++((*context)->num_records);
+		}
 		return 0;
 	}
 
@@ -286,3 +290,34 @@
 
 	return ret;
 }
+
+unsigned int ast_srv_get_record_count(struct srv_context *context)
+{
+	return context->num_records;
+}
+
+int ast_srv_get_nth_record(struct srv_context *context, int record_num, const char **host,
+		unsigned short *port, unsigned short *priority, unsigned short *weight)
+{
+	int i = 1;
+	int res = -1;
+	struct srv_entry *entry;
+
+	if (record_num < 1 || record_num > context->num_records) {
+		return res;
+	}
+
+	AST_LIST_TRAVERSE(&context->entries, entry, list) {
+		if (i == record_num) {
+			*host = entry->host;
+			*port = entry->port;
+			*priority = entry->priority;
+			*weight = entry->weight;
+			res = 0;
+			break;
+		}
+		++i;
+	}
+
+	return res;
+}




More information about the svn-commits mailing list