[asterisk-commits] file: branch file/pimp_sip_location r382737 - /team/file/pimp_sip_location/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 8 12:17:19 CST 2013


Author: file
Date: Fri Mar  8 12:17:16 2013
New Revision: 382737

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382737
Log:
Resurrect res_sip_endpoint_identifier_ip and make it configurable.

By configurable I mean you now specify in res_sip.conf specific addresses (or ranges)
that should match and to what endpoint. This is more flexible in that you can have a
single ITSP with multiple IPs all match back to a single endpoint, so less hassle in the end.

Modified:
    team/file/pimp_sip_location/res/res_sip_endpoint_identifier_ip.c

Modified: team/file/pimp_sip_location/res/res_sip_endpoint_identifier_ip.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip_endpoint_identifier_ip.c?view=diff&rev=382737&r1=382736&r2=382737
==============================================================================
--- team/file/pimp_sip_location/res/res_sip_endpoint_identifier_ip.c (original)
+++ team/file/pimp_sip_location/res/res_sip_endpoint_identifier_ip.c Fri Mar  8 12:17:16 2013
@@ -28,39 +28,113 @@
 
 #include "asterisk/res_sip.h"
 #include "asterisk/module.h"
+#include "asterisk/acl.h"
+
+/*! \brief Structure for an IP identification matching object */
+struct ip_identify_match {
+	/*! \brief Sorcery object details */
+	SORCERY_OBJECT(details);
+	/*! \brief Stringfields */
+	AST_DECLARE_STRING_FIELDS(
+		/*! The name of the endpoint */
+		AST_STRING_FIELD(endpoint_name);
+	);
+	/*! \brief Networks or addresses that should match this */
+	struct ast_ha *matches;
+};
+
+/*! \brief Destructor function for a matching object */
+static void ip_identify_destroy(void *obj)
+{
+	struct ip_identify_match *identify = obj;
+
+	ast_string_field_free_memory(identify);
+	ast_free_ha(identify->matches);
+}
+
+/*! \brief Allocator function for a matching object */
+static void *ip_identify_alloc(const char *name)
+{
+	struct ip_identify_match *identify = ao2_alloc(sizeof(*identify), ip_identify_destroy);
+
+	if (!identify || ast_string_field_init(identify, 256)) {
+		ao2_cleanup(identify);
+		return NULL;
+	}
+
+	return identify;
+}
+
+/*! \brief Comparator function for a matching object */
+static int ip_identify_match_check(void *obj, void *arg, int flags)
+{
+	struct ip_identify_match *identify = obj;
+	struct ast_sockaddr *addr = arg;
+
+	return (ast_apply_ha(identify->matches, addr) != AST_SENSE_ALLOW) ? CMP_MATCH | CMP_STOP : 0;
+}
 
 static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
 {
-	char *host;
-	struct ast_sip_endpoint *endpoint;
-	struct ast_sockaddr addr;
+	struct ast_sockaddr addr = { { 0, } };
+	RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
+	RAII_VAR(struct ip_identify_match *, match, NULL, ao2_cleanup);
 
-	memset(&addr, 0, sizeof(addr));
+	/* If no possibilities exist return early to save some time */
+	if (!(candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) ||
+		!ao2_container_count(candidates)) {
+		return NULL;
+	}
+
 	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
 	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
-	host = ast_sockaddr_stringify(&addr);
 
-	endpoint = ast_sip_get_endpoint_from_location(host);
-	if (endpoint) {
-		if (!(endpoint->ident_method & AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION)) {
-			ao2_ref(endpoint, -1);
-			return NULL;
-		}
-		ast_debug(3, "Retrieved endpoint %s for IP address %s\n", ast_sorcery_object_get_id(endpoint), host);
-	} else {
-		ast_debug(3, "Could not find endpoint based on IP address %s\n", host);
+	if (!(match = ao2_callback(candidates, 0, ip_identify_match_check, &addr))) {
+		return NULL;
 	}
-	return endpoint;
+
+	return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", match->endpoint_name);
 }
 
 static struct ast_sip_endpoint_identifier ip_identifier = {
 	.identify_endpoint = ip_identify,
 };
 
+/*! \brief Custom handler for match field */
+static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ip_identify_match *identify = obj;
+	int error = 0;
+
+	if (!(identify->matches = ast_append_ha("d", var->value, identify->matches, &error))) {
+		return -1;
+	}
+
+	return error;
+}
+
 static int load_module(void)
 {
+	ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "res_sip.conf,criteria=type=identify");
+
+	if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, NULL)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "identify", "match", "", ip_identify_match_handler, NULL, 0, 0);
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
+
 	ast_sip_register_endpoint_identifier(&ip_identifier);
+
 	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int reload_module(void)
+{
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
+	return 0;
 }
 
 static int unload_module(void)
@@ -71,6 +145,7 @@
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP IP endpoint identifier",
 		.load = load_module,
+		.reload = reload_module,
 		.unload = unload_module,
 		.load_pri = AST_MODPRI_APP_DEPEND,
 	       );




More information about the asterisk-commits mailing list