[asterisk-commits] mmichelson: branch 1.4 r78103 - in /branches/1.4: channels/ include/asterisk/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 3 15:25:22 CDT 2007


Author: mmichelson
Date: Fri Aug  3 15:25:22 2007
New Revision: 78103

URL: http://svn.digium.com/view/asterisk?view=rev&rev=78103
Log:
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:
    branches/1.4/channels/chan_sip.c
    branches/1.4/include/asterisk/config.h
    branches/1.4/main/config.c

Modified: branches/1.4/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_sip.c?view=diff&rev=78103&r1=78102&r2=78103
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Fri Aug  3 15:25:22 2007
@@ -1443,6 +1443,7 @@
 static int determine_firstline_parts(struct sip_request *req);
 static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
 static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
+static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
 static int find_sip_method(const char *msg);
 static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
 static void parse_request(struct sip_request *req);
@@ -2454,22 +2455,64 @@
 */
 static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin)
 {
-	struct sip_peer *peer;
-	struct ast_variable *var = NULL;
+	struct sip_peer *peer=NULL;
+	struct ast_variable *var;
+	struct ast_config *peerlist = NULL;
 	struct ast_variable *tmp;
-	char ipaddr[INET_ADDRSTRLEN];
+	struct ast_flags flags = {0};
+	const char *iabuf;
+	char portstring[6]; /*up to five digits plus null terminator*/
+	const char *insecure; 
+	char *cat = NULL;
+	unsigned short portnum;
 
 	/* First check on peer name */
 	if (newpeername) 
 		var = ast_load_realtime("sippeers", "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 */
+	else if (sin) {	/* Then check on IP address */
+		iabuf = ast_inet_ntoa(sin->sin_addr);
+		portnum = ntohs(sin->sin_port);
+		sprintf(portstring, "%d", portnum);
+		var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL);	/* First check for fixed IP hosts */
 		if (!var)
-			var = ast_load_realtime("sippeers", "ipaddr", ipaddr, NULL);	/* Then check for registred hosts */
-	}
+			var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL);	/* Then check for registered hosts */
+		if (!var) { 
+			peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
+			if(peerlist){ 
+				while((cat = ast_category_browse(peerlist, cat)))
+				{
+					insecure = ast_variable_retrieve(peerlist, cat, "insecure");
+					set_insecure_flags(&flags, insecure, -1);
+					if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
+						var = ast_category_root(peerlist, cat);
+						break;
+					}
+				}
+			}
+			if(!var) {
+				ast_config_destroy(peerlist);
+				peerlist = NULL; /*for safety's sake*/
+				cat = NULL;
+				peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
+				if(peerlist) {
+					while((cat = ast_category_browse(peerlist, cat)))
+					{
+						insecure = ast_variable_retrieve(peerlist, cat, "insecure");
+						set_insecure_flags(&flags, insecure, -1);
+						if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
+							var = ast_category_root(peerlist, cat);
+							break;
+						}
+					}
+				}
+			}
+		}
+	} else
+		return NULL;
 
 	if (!var)
+		if(peerlist)
+			ast_config_destroy(peerlist);
 		return NULL;
 
 	for (tmp = var; tmp; tmp = tmp->next) {
@@ -2484,15 +2527,21 @@
 	}
 	
 	if (!newpeername) {	/* Did not find peer in realtime */
-		ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
-		ast_variables_destroy(var);
+		ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
+		if(peerlist)
+			ast_config_destroy(peerlist);
+		else
+			ast_variables_destroy(var);
 		return NULL;
 	}
 
 	/* Peer found in realtime, now build it in memory */
 	peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
 	if (!peer) {
-		ast_variables_destroy(var);
+		if(peerlist)
+			ast_config_destroy(peerlist);
+		else
+			ast_variables_destroy(var);
 		return NULL;
 	}
 
@@ -2509,8 +2558,10 @@
 	} else {
 		ast_set_flag(&peer->flags[0], SIP_REALTIME);
 	}
-	ast_variables_destroy(var);
-
+	if(peerlist)
+		ast_config_destroy(peerlist);
+	else
+		ast_variables_destroy(var);
 	return peer;
 }
 
@@ -15622,6 +15673,34 @@
 }
 
 /*!
+ * \brief Parse the "insecure" setting from sip.conf or from realtime.
+ * \param flags a pointer to an ast_flags structure
+ * \param value the value of the SIP insecure setting
+ * \param lineno linenumber in sip.conf or -1 for realtime
+ */
+static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno)
+{
+	if (!strcasecmp(value, "very"))
+		ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
+	else if (ast_true(value))
+		ast_set_flag(flags, SIP_INSECURE_PORT);
+	else 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, SIP_INSECURE_PORT);
+			else if (!strcasecmp(word, "invite"))
+				ast_set_flag(flags, 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
   \param mask array of two struct ast_flags
@@ -15675,24 +15754,7 @@
 	} else if (!strcasecmp(v->name, "canreinvite")) {
 		ast_set_flag(&mask[0], SIP_REINVITE);
 		ast_clear_flag(&flags[0], SIP_REINVITE);
-		if (ast_true(v->value)) {
-			ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
-		} else if (!ast_false(v->value)) {
-			char buf[64];
-			char *word, *next = buf;
-
-			ast_copy_string(buf, v->value, sizeof(buf));
-			while ((word = strsep(&next, ","))) {
-				if (!strcasecmp(word, "update")) {
-					ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
-				} else if (!strcasecmp(word, "nonat")) {
-					ast_set_flag(&flags[0], SIP_CAN_REINVITE);
-					ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
-				} else {
-					ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
-				}
-			}
-		}
+		set_insecure_flags(flags, v->value, v->lineno);
 	} else if (!strcasecmp(v->name, "insecure")) {
 		ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
 		ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);

Modified: branches/1.4/include/asterisk/config.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/include/asterisk/config.h?view=diff&rev=78103&r1=78102&r2=78103
==============================================================================
--- branches/1.4/include/asterisk/config.h (original)
+++ branches/1.4/include/asterisk/config.h Fri Aug  3 15:25:22 2007
@@ -75,6 +75,14 @@
  */
 void ast_config_destroy(struct ast_config *config);
 
+/*! \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.

Modified: branches/1.4/main/config.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/config.c?view=diff&rev=78103&r1=78102&r2=78103
==============================================================================
--- branches/1.4/main/config.c (original)
+++ branches/1.4/main/config.c Fri Aug  3 15:25:22 2007
@@ -351,6 +351,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