[asterisk-commits] mmichelson: branch group/pimp_my_sip r380141 - in /team/group/pimp_my_sip: in...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 25 16:49:38 CST 2013


Author: mmichelson
Date: Fri Jan 25 16:49:34 2013
New Revision: 380141

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380141
Log:
Add an endpoint identifier that matches based on IP address.

This adds a primitive version of endpoint location in order to
get an IP address for an endpoint and to get an endpoint based
on an IP address.

Some potential improvements:
1) The sorcery object for retrieving an endpoint by IP address
may be better suited to living in res_sip_endpoint_identifier_ip.c
since it is unknown whether other services will find this sort of
thing useful.
2) When you are looking for the location of a particular endpoint,
getting an IP address has limited use. Getting A SIP URI or some
other sort of FQDN would be much more useful.
3) There is no method at the moment to set endpoint location
information aside from when it is read from the configuration
file. Such a method will be necessary when it comes time to
write a registrar

Still, this means that we can now recognize incoming calls by
the source IP address, which is pretty cool.


Added:
    team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c   (with props)
Modified:
    team/group/pimp_my_sip/include/asterisk/res_sip.h
    team/group/pimp_my_sip/res/res_sip.c
    team/group/pimp_my_sip/res/res_sip.exports.in

Modified: team/group/pimp_my_sip/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/include/asterisk/res_sip.h?view=diff&rev=380141&r1=380140&r2=380141
==============================================================================
--- team/group/pimp_my_sip/include/asterisk/res_sip.h (original)
+++ team/group/pimp_my_sip/include/asterisk/res_sip.h Fri Jan 25 16:49:34 2013
@@ -164,6 +164,31 @@
 	/*! List of outbound registrations */
 	AST_LIST_HEAD_NOLOCK(, ast_sip_registration) registrations;
 };
+
+/*!
+ * \brief Given an endpoint, get its IP address
+ *
+ * \param endpoint The endpoint whose location is desired
+ * \param[out] location_buf The IP address and port of the endpoint, as a string
+ * \param size The size of the location buffer
+ * \return void
+ *
+ * XXX The usefulness of retrieving an IP address is limited. It's more
+ * useful to get a hostname or FQDN so that the location can be resolved.
+ */
+void ast_sip_endpoint_get_location(const struct ast_sip_endpoint *endpoint, char *location_buf, size_t size);
+
+/*!
+ * \brief Given an IP address, get the SIP endpoint that is located there.
+ *
+ * The returned endpoint will need to have its reference count decremented with ao2_ref()
+ * once the caller has finished using it.
+ *
+ * \param addr The IP address
+ * \retval NULL Could not find an endpoint with this IP address
+ * \retval non-NULL The endpoint with this IP address
+ */
+struct ast_sip_endpoint *ast_sip_get_endpoint_from_location(const char *addr);
  
 /*!
  * \brief Data used for creating authentication challenges.

Modified: team/group/pimp_my_sip/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip.c?view=diff&rev=380141&r1=380140&r2=380141
==============================================================================
--- team/group/pimp_my_sip/res/res_sip.c (original)
+++ team/group/pimp_my_sip/res/res_sip.c Fri Jan 25 16:49:34 2013
@@ -47,6 +47,82 @@
 
 static struct ast_sorcery *sip_sorcery;
 
+/*!
+ * \brief Structure used to map an IP address to an endpoint.
+ *
+ * This is useful for determining if an incoming request
+ * is coming from a particular endpoint.
+ */
+struct sip_location_to_endpoint {
+	SORCERY_OBJECT(details);
+	const char *endpoint_name;
+};
+
+static void sip_location_to_endpoint_destroy(void *obj)
+{
+	struct sip_location_to_endpoint *location_to_endpoint = obj;
+	ast_free((char *)location_to_endpoint->endpoint_name);
+}
+
+static void *sip_location_to_endpoint_alloc(const char *name)
+{
+	return ao2_alloc(sizeof(struct sip_location_to_endpoint), sip_location_to_endpoint_destroy);
+}
+/*!
+ * \brief Structure used to map an endpoint name to its location
+ *
+ * Location is stored as a string so that a FQDN may be stored
+ * and the location may be resolved.
+ *
+ * This is useful for determining the destination for an outgoing
+ * request to a specific endpoint
+ */
+struct sip_endpoint_to_location {
+	SORCERY_OBJECT(details);
+	const char *host;
+};
+
+static void sip_endpoint_to_location_destroy(void *obj)
+{
+	struct sip_endpoint_to_location *endpoint_to_location = obj;
+	ast_free((char *) endpoint_to_location->host);
+}
+
+static void *sip_endpoint_to_location_alloc(const char *name)
+{
+	return ao2_alloc(sizeof(struct sip_endpoint_to_location), sip_endpoint_to_location_destroy);
+}
+
+static int host_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	RAII_VAR(struct sip_location_to_endpoint *, location_to_endpoint, NULL, ao2_cleanup);
+	RAII_VAR(struct sip_endpoint_to_location *, endpoint_to_location, NULL, ao2_cleanup);
+	const char *host = var->value;
+	const char *name = ast_sorcery_object_get_id(obj);
+
+	location_to_endpoint = ast_sorcery_alloc(sip_sorcery, "location_to_endpoint", host);
+	if (!location_to_endpoint) {
+		return -1;
+	}
+	endpoint_to_location = ast_sorcery_alloc(sip_sorcery, "endpoint_to_location", name);
+	if (!endpoint_to_location) {
+		return -1;
+	}
+
+	location_to_endpoint->endpoint_name = ast_strdup(name);
+	endpoint_to_location->host = ast_strdup(host);
+
+	if (ast_sorcery_create(sip_sorcery, location_to_endpoint)) {
+		return -1;
+	}
+	if (ast_sorcery_create(sip_sorcery, endpoint_to_location)) {
+		ast_sorcery_delete(sip_sorcery, location_to_endpoint);
+		return -1;
+	}
+
+	return 0;
+}
+
 static int sip_initialize_sorcery(void)
 {
 	if (!(sip_sorcery = ast_sorcery_open())) {
@@ -56,6 +132,9 @@
 
 	ast_sorcery_apply_config(sip_sorcery, "res_sip");
 	ast_sorcery_apply_default(sip_sorcery, "endpoint", "config", "res_sip.conf,criteria=type=endpoint");
+
+	ast_sorcery_apply_default(sip_sorcery, "location_to_endpoint", "memory", NULL);
+	ast_sorcery_apply_default(sip_sorcery, "endpoint_to_location", "memory", NULL);
 
 	if (ast_sorcery_object_register(sip_sorcery, "endpoint", ast_sip_endpoint_alloc, NULL, NULL)) {
 		ast_log(LOG_ERROR, "Failed to register SIP endpoint object with sorcery\n");
@@ -64,10 +143,14 @@
 		return -1;
 	}
 
+	ast_sorcery_object_register(sip_sorcery, "location_to_endpoint", sip_location_to_endpoint_alloc, NULL, NULL);
+	ast_sorcery_object_register(sip_sorcery, "endpoint_to_location", sip_endpoint_to_location_alloc, NULL, NULL);
+
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "type", "", OPT_NOOP_T, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "context", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, context));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disallow", "", OPT_CODEC_T, 0, FLDSET(struct ast_sip_endpoint, prefs, codecs));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow", "", OPT_CODEC_T, 1, FLDSET(struct ast_sip_endpoint, prefs, codecs));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "host", "", host_handler, NULL, 0, 0);
 
 	return 0;
 }
@@ -269,6 +352,30 @@
 		ao2_cleanup(endpoint);
 		return NULL;
 	}
+	return endpoint;
+}
+
+void ast_sip_endpoint_get_location(const struct ast_sip_endpoint *endpoint, char *location_buf, size_t size)
+{
+	struct sip_endpoint_to_location *endpoint_to_location;
+	endpoint_to_location = ast_sorcery_retrieve_by_id(sip_sorcery, "endpoint_to_location", ast_sorcery_object_get_id(endpoint));
+	if (!endpoint_to_location) {
+		return;
+	}
+	ast_copy_string(location_buf, endpoint_to_location->host, size);
+	ao2_ref(endpoint_to_location, -1);
+}
+
+struct ast_sip_endpoint *ast_sip_get_endpoint_from_location(const char *location)
+{
+	struct sip_location_to_endpoint *location_to_endpoint;
+	struct ast_sip_endpoint *endpoint;
+	location_to_endpoint = ast_sorcery_retrieve_by_id(sip_sorcery, "location_to_endpoint", location);
+	if (!location_to_endpoint) {
+		return NULL;
+	}
+	endpoint = ast_sorcery_retrieve_by_id(sip_sorcery, "endpoint", location_to_endpoint->endpoint_name);
+	ao2_ref(location_to_endpoint, -1);
 	return endpoint;
 }
 

Modified: team/group/pimp_my_sip/res/res_sip.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip.exports.in?view=diff&rev=380141&r1=380140&r2=380141
==============================================================================
--- team/group/pimp_my_sip/res/res_sip.exports.in (original)
+++ team/group/pimp_my_sip/res/res_sip.exports.in Fri Jan 25 16:49:34 2013
@@ -24,6 +24,8 @@
 		LINKER_SYMBOL_PREFIXast_sip_endpoint_alloc;
 		LINKER_SYMBOL_PREFIXast_copy_pj_str;
 		LINKER_SYMBOL_PREFIXast_sip_get_sorcery;
+		LINKER_SYMBOL_PREFIXast_sip_get_endpoint_from_location;
+		LINKER_SYMBOL_PREFIXast_sip_endpoint_get_location;
 		LINKER_SYMBOL_PREFIXpj_*;
 		LINKER_SYMBOL_PREFIXpjsip_*;
 		LINKER_SYMBOL_PREFIXpjmedia_*;

Added: team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c?view=auto&rev=380141
==============================================================================
--- team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c (added)
+++ team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c Fri Jan 25 16:49:34 2013
@@ -1,0 +1,70 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#undef bzero
+#define bzero bzero
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+
+static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
+{
+	char *host;
+	struct ast_sip_endpoint *endpoint;
+	struct ast_sockaddr addr;
+
+	memset(&addr, 0, sizeof(addr));
+	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) {
+		ast_debug(3, "Retrieved endpoint %s\n", ast_sorcery_object_get_id(endpoint));
+	}
+	return endpoint;
+}
+
+static struct ast_sip_endpoint_identifier ip_identifier = {
+	.identify_endpoint = ip_identify,
+};
+
+static int load_module(void)
+{
+	ast_sip_register_endpoint_identifier(&ip_identifier);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_endpoint_identifier(&ip_identifier);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP IP endpoint identifier",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );

Propchange: team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/pimp_my_sip/res/res_sip_endpoint_identifier_ip.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the asterisk-commits mailing list