[asterisk-commits] mmichelson: trunk r78186 - in /trunk: ./ channels/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Aug 6 11:54:51 CDT 2007


Author: mmichelson
Date: Mon Aug  6 11:54:51 2007
New Revision: 78186

URL: http://svn.digium.com/view/asterisk?view=rev&rev=78186
Log:
Merged revisions 78103 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78103 | mmichelson | 2007-08-03 15:25:22 -0500 (Fri, 03 Aug 2007) | 7 lines

Changed the behavior of sip's realtime_peer function to match the corresponding way of matching for non-realtime peers.
Now matches are made on both the IP address and port number, or if the insecure setting is set to "port" then just match on the
IP address.

In order to accomplish this, I also added a new API call, ast_category_root, which returns the first variable of an ast_category struct


........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c
    trunk/include/asterisk/config.h
    trunk/main/config.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=78186&r1=78185&r2=78186
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Mon Aug  6 11:54:51 2007
@@ -1651,12 +1651,15 @@
 static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
 static void reg_source_db(struct sip_peer *peer);
 static void destroy_association(struct sip_peer *peer);
+static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
 
 /* Realtime device support */
 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
 static struct sip_user *realtime_user(const char *username);
 static void update_peer(struct sip_peer *p, int expiry);
+static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
+static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername);
 static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
 static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
@@ -2933,12 +2936,36 @@
 	}
 }
 
+static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config)
+{
+	struct ast_variable *var;
+	struct ast_flags flags = {0};
+	char *cat = NULL;
+	const char *insecure;
+	while ((cat = ast_category_browse(config, cat))) {
+		insecure = ast_variable_retrieve(config, cat, "insecure");
+		set_insecure_flags(&flags, insecure, -1);
+		if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
+			var = ast_category_root(config, cat);
+			break;
+		}
+	}
+	return var;
+}
+
+static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername)
+{
+	struct ast_variable *tmp;
+	for (tmp = var; tmp; tmp = tmp->next) {
+		if (!newpeername && !strcasecmp(tmp->name, "name"))
+			newpeername = tmp->value;
+	}
+	return newpeername;
+}
 
 /*! \brief  realtime_peer: Get peer from realtime storage
  * Checks the "sippeers" realtime family from extconfig.conf 
  * Checks the "sipregs" realtime family from extconfig.conf if it's configured.
- * \todo Consider adding check of port address when matching here to follow the same
- * 	algorithm as for static peers. Will we break anything by adding that?
 */
 static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin)
 {
@@ -2946,7 +2973,11 @@
 	struct ast_variable *var = NULL;
 	struct ast_variable *varregs = NULL;
 	struct ast_variable *tmp;
+	struct ast_config *peerlist = NULL;
 	char ipaddr[INET_ADDRSTRLEN];
+	char portstring[6]; /*up to 5 digits plus null terminator*/
+	char *cat = NULL;
+	unsigned short portnum;
 	int realtimeregs = ast_check_realtime("sipregs");
 
 	/* First check on peer name */
@@ -2956,39 +2987,87 @@
 			varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
 	} else if (sin) {	/* Then check on IP address for dynamic peers */
 		ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
-		var = ast_load_realtime("sippeers", "host", ipaddr, NULL);	/* First check for fixed IP hosts */
+		portnum = ntohs(sin->sin_port);
+		sprintf(portstring, "%u", portnum);
+		var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, NULL);	/* First check for fixed IP hosts */
 		if (var) {
 			if (realtimeregs) {
-				for (tmp = var; tmp; tmp = tmp->next) {
-					if (!newpeername && !strcasecmp(tmp->name, "name"))
-						newpeername = tmp->value;
-				}
+				newpeername = get_name_from_variable(var, newpeername);
 				varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
 			}
 		} else {
 			if (realtimeregs)
-				varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, NULL); /* Then check for registered hosts */
+				varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, NULL); /* Then check for registered hosts */
 			else
-				var = ast_load_realtime("sippeers", "ipaddr", ipaddr, NULL); /* Then check for registered hosts */
+				var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, NULL); /* Then check for registered hosts */
 			if (varregs) {
-				for (tmp = varregs; tmp; tmp = tmp->next) {
-					if (!newpeername && !strcasecmp(tmp->name, "name"))
-						newpeername = tmp->value;
-				}
+				newpeername = get_name_from_variable(varregs, newpeername);
 				var = ast_load_realtime("sippeers", "name", newpeername, NULL);
 			}
 		}
-	}
-
-	if (!var)
+		if(!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/
+			peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, NULL);
+			if (peerlist) {
+				var = get_insecure_variable_from_config(peerlist);
+				if(var) {
+					if (realtimeregs) {
+						newpeername = get_name_from_variable(var, newpeername);
+						varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
+					}
+				} else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/
+					peerlist = NULL;
+					cat = NULL;
+					peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, NULL);
+					if(peerlist) {
+						var = get_insecure_variable_from_config(peerlist);
+						if(var) {
+							if (realtimeregs) {
+								newpeername = get_name_from_variable(var, newpeername);
+								varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
+							}
+						}
+					}
+				}
+			} else {
+				if(realtimeregs) {
+					peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, NULL);
+					if (peerlist) {
+						varregs = get_insecure_variable_from_config(peerlist);
+						if (varregs) {
+							newpeername = get_name_from_variable(varregs, newpeername);
+							var = ast_load_realtime("sippeers", "name", newpeername, NULL);
+						}
+					}
+				} else {
+					peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, NULL);
+					if (peerlist) {
+						var = get_insecure_variable_from_config(peerlist);
+						if (var) {
+							newpeername = get_name_from_variable(var, newpeername);
+							varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (!var) {
+		if (peerlist)
+			ast_config_destroy(peerlist);
 		return NULL;
+	}
 
 	for (tmp = var; tmp; tmp = tmp->next) {
 		/* If this is type=user, then skip this object. */
 		if (!strcasecmp(tmp->name, "type") &&
 		    !strcasecmp(tmp->value, "user")) {
-			ast_variables_destroy(var);
-			ast_variables_destroy(varregs);
+			if(peerlist)
+				ast_config_destroy(peerlist);
+			else {
+				ast_variables_destroy(var);
+				ast_variables_destroy(varregs);
+			}
 			return NULL;
 		} else if (!newpeername && !strcasecmp(tmp->name, "name")) {
 			newpeername = tmp->value;
@@ -2997,7 +3076,10 @@
 	
 	if (!newpeername) {	/* Did not find peer in realtime */
 		ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
-		ast_variables_destroy(var);
+		if(peerlist)
+			ast_config_destroy(peerlist);
+		else
+			ast_variables_destroy(var);
 		return NULL;
 	}
 
@@ -3005,8 +3087,12 @@
 	/* Peer found in realtime, now build it in memory */
 	peer = build_peer(newpeername, var, varregs, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
 	if (!peer) {
-		ast_variables_destroy(var);
-		ast_variables_destroy(varregs);
+		if(peerlist)
+			ast_config_destroy(peerlist);
+		else {
+			ast_variables_destroy(var);
+			ast_variables_destroy(varregs);
+		}
 		return NULL;
 	}
 
@@ -3025,8 +3111,12 @@
 	} else {
 		peer->is_realtime = 1;
 	}
-	ast_variables_destroy(var);
-	ast_variables_destroy(varregs);
+	if (peerlist)
+		ast_config_destroy(peerlist);
+	else {
+		ast_variables_destroy(var);
+		ast_variables_destroy(varregs);
+	}
 
 	return peer;
 }
@@ -16656,6 +16746,25 @@
 	return tmpc;
 }
 
+static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
+{
+	if (!ast_false(value)) {
+		char buf[64];
+		char *word, *next;
+
+		ast_copy_string(buf, value, sizeof(buf));
+		next = buf;
+		while ((word = strsep(&next, ","))) {
+			if (!strcasecmp(word, "port"))
+				ast_set_flag(&flags[0], SIP_INSECURE_PORT);
+			else if (!strcasecmp(word, "invite"))
+				ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
+			else
+				ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
+		}
+	}
+}
+
 /*!
   \brief Handle flag-type options common to configuration of devices - users and peers
   \param flags array of two struct ast_flags
@@ -16729,21 +16838,7 @@
 	} else if (!strcasecmp(v->name, "insecure")) {
 		ast_set_flag(&mask[0], SIP_INSECURE);
 		ast_clear_flag(&flags[0], SIP_INSECURE);
-		if (!ast_false(v->value)) {
-			char buf[64];
-			char *word, *next;
-
-			ast_copy_string(buf, v->value, sizeof(buf));
-			next = buf;
-			while ((word = strsep(&next, ","))) {
-				if (!strcasecmp(word, "port"))
-					ast_set_flag(&flags[0], SIP_INSECURE_PORT);
-				else if (!strcasecmp(word, "invite"))
-					ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
-				else
-					ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
-			}
-		}
+		set_insecure_flags(&flags[0], v->value, v->lineno);	
 	} else if (!strcasecmp(v->name, "progressinband")) {
 		ast_set_flag(&mask[0], SIP_PROG_INBAND);
 		ast_clear_flag(&flags[0], SIP_PROG_INBAND);

Modified: trunk/include/asterisk/config.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/config.h?view=diff&rev=78186&r1=78185&r2=78186
==============================================================================
--- trunk/include/asterisk/config.h (original)
+++ trunk/include/asterisk/config.h Mon Aug  6 11:54:51 2007
@@ -83,8 +83,15 @@
  */
 void ast_config_destroy(struct ast_config *config);
 
-/*! 
- * \brief Goes through categories 
+/*! \brief returns the root ast_variable of a config
+ * \param config pointer to an ast_config data structure
+ * \param cat name of the category for which you want the root
+ *
+ * Returns the category specified
+ */
+struct ast_variable *ast_category_root(struct ast_config *config, char *cat);
+
+/*! \brief Goes through categories 
  * \param config Which config structure you wish to "browse"
  * \param prev A pointer to a previous category.
  * This funtion is kind of non-intuitive in it's use.  To begin, one passes NULL as the second arguement.  It will return a pointer to the string of the first category in the file.  From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.

Modified: trunk/main/config.c
URL: http://svn.digium.com/view/asterisk/trunk/main/config.c?view=diff&rev=78186&r1=78185&r2=78186
==============================================================================
--- trunk/main/config.c (original)
+++ trunk/main/config.c Mon Aug  6 11:54:51 2007
@@ -354,6 +354,14 @@
 	for (; cat && cat->ignored; cat = cat->next);
 
 	return cat;
+}
+
+struct ast_variable *ast_category_root(struct ast_config *config, char *cat)
+{
+	struct ast_category *category = ast_category_get(config, cat);
+	if (category)
+		return category->root;
+	return NULL;
 }
 
 char *ast_category_browse(struct ast_config *config, const char *prev)




More information about the asterisk-commits mailing list