[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