[asterisk-commits] kharwell: branch kharwell/pimp_my_sip r386042 - in /team/kharwell/pimp_my_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 18 17:31:10 CDT 2013


Author: kharwell
Date: Thu Apr 18 17:31:02 2013
New Revision: 386042

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386042
Log:
Multiple revisions 385967,386022

........
  r385967 | mmichelson | 2013-04-17 10:32:57 -0500 (Wed, 17 Apr 2013) | 11 lines
  
  This adds support for outbound authentication for outbound registrations.
  
  In order to facilitate the change, the outbound authentication API had to
  be modified not to be dependent on endpoints but rather to be given the
  names of auth IDs in sorcery to use. This way, outbound registration
  can be configured to point to an auth section in the configuration the
  same way that endpoints do.
  
  Review: https://reviewboard.asterisk.org/r/2431
........
  r386022 | root | 2013-04-18 13:17:43 -0500 (Thu, 18 Apr 2013) | 39 lines
  
  Multiple revisions 386019-386020
  
  ........
    r386019 | dlee | 2013-04-18 12:26:29 -0500 (Thu, 18 Apr 2013) | 17 lines
    
    Fix lock errors on startup.
    
    In messages.c, there are several places in the code where we create a
    tmp_tech_holder and pass that into an ao2_find call. Unfortunately, we
    weren't initializing the rwlock on the tmp_tech_holder, which the hash
    function was locking. It's apparently harmless, but still not the best
    code.
    
    This patch extracts all that copy/pasted code into two functions,
    msg_find_by_tech and msg_find_by_tech_name, which properly initialize
    and destroy the rwlock on the tmp_tech_holder.
    
    Review: https://reviewboard.asterisk.org/r/2454/
    ........
    
    Merged revisions 386006 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
    r386020 | dlee | 2013-04-18 12:30:28 -0500 (Thu, 18 Apr 2013) | 12 lines
    
    Allow WebSocket connections on more URL's
    
    This patch adds the concept of ast_websocket_server to
    res_http_websocket, allowing WebSocket connections on URL's more more
    than /ws.
    
    The existing funcitons for managing the WebSocket subprotocols on /ws
    still work, so this patch should be completely backward compatible.
    
    (closes issue ASTERISK-21279)
    Review: https://reviewboard.asterisk.org/r/2453/
  ........
  
  Merged revisions 386019-386020 from file:///srv/subversion/repos/asterisk/trunk
........

Merged revisions 385967,386022 from http://svn.asterisk.org/svn/asterisk/team/group/pimp_my_sip

Modified:
    team/kharwell/pimp_my_sip/   (props changed)
    team/kharwell/pimp_my_sip/include/asterisk/http_websocket.h
    team/kharwell/pimp_my_sip/main/message.c
    team/kharwell/pimp_my_sip/res/res_http_websocket.c

Propchange: team/kharwell/pimp_my_sip/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/kharwell/pimp_my_sip/
------------------------------------------------------------------------------
--- pimp_my_sip-integrated (original)
+++ pimp_my_sip-integrated Thu Apr 18 17:31:02 2013
@@ -1,1 +1,1 @@
-/team/group/pimp_my_sip:1-385967
+/team/group/pimp_my_sip:1-386041

Modified: team/kharwell/pimp_my_sip/include/asterisk/http_websocket.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/include/asterisk/http_websocket.h?view=diff&rev=386042&r1=386041&r2=386042
==============================================================================
--- team/kharwell/pimp_my_sip/include/asterisk/http_websocket.h (original)
+++ team/kharwell/pimp_my_sip/include/asterisk/http_websocket.h Thu Apr 18 17:31:02 2013
@@ -19,6 +19,7 @@
 #ifndef _ASTERISK_HTTP_WEBSOCKET_H
 #define _ASTERISK_HTTP_WEBSOCKET_H
 
+#include "asterisk/http.h"
 #include "asterisk/optional_api.h"
 
 /*!
@@ -40,7 +41,13 @@
 };
 
 /*!
- * \brief Opaque structure for WebSocket sessions
+ * \brief Opaque structure for WebSocket server.
+ * \since 12
+ */
+struct ast_websocket_server;
+
+/*!
+ * \brief Opaque structure for WebSocket sessions.
  */
 struct ast_websocket;
 
@@ -58,7 +65,24 @@
 typedef void (*ast_websocket_callback)(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers);
 
 /*!
- * \brief Add a sub-protocol handler to the server
+ * \brief Creates a \ref websocket_server
+ *
+ * \retval New \ref websocket_server instance
+ * \retval \c NULL on error
+ * \since 12
+ */
+struct ast_websocket_server *ast_websocket_server_create(void);
+
+/*!
+ * \brief Callback suitable for use with a \ref ast_http_uri.
+ *
+ * Set the data field of the ast_http_uri to \ref ast_websocket_server.
+ * \since 12
+ */
+int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers);
+
+/*!
+ * \brief Add a sub-protocol handler to the default /ws server
  *
  * \param name Name of the sub-protocol to register
  * \param callback Callback called when a new connection requesting the sub-protocol is established
@@ -69,7 +93,7 @@
 AST_OPTIONAL_API(int, ast_websocket_add_protocol, (const char *name, ast_websocket_callback callback), {return -1;});
 
 /*!
- * \brief Remove a sub-protocol handler from the server
+ * \brief Remove a sub-protocol handler from the default /ws server.
  *
  * \param name Name of the sub-protocol to unregister
  * \param callback Callback that was previously registered with the sub-protocol
@@ -78,6 +102,30 @@
  * \retval -1 if sub-protocol was not found or if callback did not match
  */
 AST_OPTIONAL_API(int, ast_websocket_remove_protocol, (const char *name, ast_websocket_callback callback), {return -1;});
+
+/*!
+ * \brief Add a sub-protocol handler to the given server.
+ *
+ * \param name Name of the sub-protocol to register
+ * \param callback Callback called when a new connection requesting the sub-protocol is established
+ *
+ * \retval 0 success
+ * \retval -1 if sub-protocol handler could not be registered
+ * \since 12
+ */
+AST_OPTIONAL_API(int, ast_websocket_server_add_protocol, (struct ast_websocket_server *server, const char *name, ast_websocket_callback callback), {return -1;});
+
+/*!
+ * \brief Remove a sub-protocol handler from the given server.
+ *
+ * \param name Name of the sub-protocol to unregister
+ * \param callback Callback that was previously registered with the sub-protocol
+ *
+ * \retval 0 success
+ * \retval -1 if sub-protocol was not found or if callback did not match
+ * \since 12
+ */
+AST_OPTIONAL_API(int, ast_websocket_server_remove_protocol, (struct ast_websocket_server *server, const char *name, ast_websocket_callback callback), {return -1;});
 
 /*!
  * \brief Read a WebSocket frame and handle it

Modified: team/kharwell/pimp_my_sip/main/message.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/main/message.c?view=diff&rev=386042&r1=386041&r2=386042
==============================================================================
--- team/kharwell/pimp_my_sip/main/message.c (original)
+++ team/kharwell/pimp_my_sip/main/message.c Thu Apr 18 17:31:02 2013
@@ -1041,6 +1041,27 @@
 	return res;
 }
 
+static struct ast_msg_tech_holder *msg_find_by_tech(const struct ast_msg_tech *msg_tech, int ao2_flags)
+{
+	struct ast_msg_tech_holder *tech_holder;
+	struct ast_msg_tech_holder tmp_tech_holder = {
+		.tech = msg_tech,
+	};
+
+	ast_rwlock_init(&tmp_tech_holder.tech_lock);
+	tech_holder = ao2_find(msg_techs, &tmp_tech_holder, ao2_flags);
+	ast_rwlock_destroy(&tmp_tech_holder.tech_lock);
+	return tech_holder;
+}
+
+static struct ast_msg_tech_holder *msg_find_by_tech_name(const char *tech_name, int ao2_flags)
+{
+	struct ast_msg_tech tmp_msg_tech = {
+		.name = tech_name,
+	};
+	return msg_find_by_tech(&tmp_msg_tech, ao2_flags);
+}
+
 /*!
  * \internal
  * \brief MessageSend() application
@@ -1089,16 +1110,7 @@
 	tech_name = ast_strdupa(args.to);
 	tech_name = strsep(&tech_name, ":");
 
-	{
-		struct ast_msg_tech tmp_msg_tech = {
-			.name = tech_name,
-		};
-		struct ast_msg_tech_holder tmp_tech_holder = {
-			.tech = &tmp_msg_tech,
-		};
-
-		tech_holder = ao2_find(msg_techs, &tmp_tech_holder, OBJ_POINTER);
-	}
+	tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
 
 	if (!tech_holder) {
 		ast_log(LOG_WARNING, "No message technology '%s' found.\n", tech_name);
@@ -1159,16 +1171,8 @@
 
 	tech_name = ast_strdupa(to);
 	tech_name = strsep(&tech_name, ":");
-	{
-		struct ast_msg_tech tmp_msg_tech = {
-			.name = tech_name,
-		};
-		struct ast_msg_tech_holder tmp_tech_holder = {
-			.tech = &tmp_msg_tech,
-		};
-
-		tech_holder = ao2_find(msg_techs, &tmp_tech_holder, OBJ_POINTER);
-	}
+
+	tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
 
 	if (!tech_holder) {
 		astman_send_error(s, m, "Message technology not found.");
@@ -1219,16 +1223,8 @@
 
 	tech_name = ast_strdupa(to);
 	tech_name = strsep(&tech_name, ":");
-	{
-		struct ast_msg_tech tmp_msg_tech = {
-			.name = tech_name,
-		};
-		struct ast_msg_tech_holder tmp_tech_holder = {
-			.tech = &tmp_msg_tech,
-		};
-
-		tech_holder = ao2_find(msg_techs, &tmp_tech_holder, OBJ_POINTER);
-	}
+
+	tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
 
 	if (!tech_holder) {
 		ao2_ref(msg, -1);
@@ -1249,12 +1245,9 @@
 
 int ast_msg_tech_register(const struct ast_msg_tech *tech)
 {
-	struct ast_msg_tech_holder tmp_tech_holder = {
-		.tech = tech,
-	};
 	struct ast_msg_tech_holder *tech_holder;
 
-	if ((tech_holder = ao2_find(msg_techs, &tmp_tech_holder, OBJ_POINTER))) {
+	if ((tech_holder = msg_find_by_tech(tech, OBJ_POINTER))) {
 		ao2_ref(tech_holder, -1);
 		ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
 				tech->name);
@@ -1280,12 +1273,9 @@
 
 int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
 {
-	struct ast_msg_tech_holder tmp_tech_holder = {
-		.tech = tech,
-	};
 	struct ast_msg_tech_holder *tech_holder;
 
-	tech_holder = ao2_find(msg_techs, &tmp_tech_holder, OBJ_POINTER | OBJ_UNLINK);
+	tech_holder = msg_find_by_tech(tech, OBJ_POINTER | OBJ_UNLINK);
 
 	if (!tech_holder) {
 		ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);

Modified: team/kharwell/pimp_my_sip/res/res_http_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/res/res_http_websocket.c?view=diff&rev=386042&r1=386041&r2=386042
==============================================================================
--- team/kharwell/pimp_my_sip/res/res_http_websocket.c (original)
+++ team/kharwell/pimp_my_sip/res/res_http_websocket.c Thu Apr 18 17:31:02 2013
@@ -77,9 +77,6 @@
 	ast_websocket_callback callback; /*!< Callback called when a new session is established */
 };
 
-/*! \brief Container for registered protocols */
-static struct ao2_container *protocols;
-
 /*! \brief Hashing function for protocols */
 static int protocol_hash_fn(const void *obj, const int flags)
 {
@@ -103,6 +100,36 @@
 {
 	struct websocket_protocol *protocol = obj;
 	ast_free(protocol->name);
+}
+
+/*! \brief Structure for a WebSocket server */
+struct ast_websocket_server {
+	struct ao2_container *protocols; /*!< Container for registered protocols */
+};
+
+static void websocket_server_dtor(void *obj)
+{
+	struct ast_websocket_server *server = obj;
+	ao2_cleanup(server->protocols);
+	server->protocols = NULL;
+}
+
+struct ast_websocket_server *ast_websocket_server_create(void)
+{
+	RAII_VAR(struct ast_websocket_server *, server, NULL, ao2_cleanup);
+
+	server = ao2_alloc(sizeof(*server), websocket_server_dtor);
+	if (!server) {
+		return NULL;
+	}
+
+	server->protocols = ao2_container_alloc(MAX_PROTOCOL_BUCKETS, protocol_hash_fn, protocol_cmp_fn);
+	if (!server->protocols) {
+		return NULL;
+	}
+
+	ao2_ref(server, +1);
+	return server;
 }
 
 /*! \brief Destructor function for sessions */
@@ -118,38 +145,38 @@
 	ast_free(session->payload);
 }
 
-int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_websocket_callback callback)
+int AST_OPTIONAL_API_NAME(ast_websocket_server_add_protocol)(struct ast_websocket_server *server, const char *name, ast_websocket_callback callback)
 {
 	struct websocket_protocol *protocol;
 
-	if (!protocols) {
-		return -1;
-	}
-
-	ao2_lock(protocols);
+	if (!server->protocols) {
+		return -1;
+	}
+
+	ao2_lock(server->protocols);
 
 	/* Ensure a second protocol handler is not registered for the same protocol */
-	if ((protocol = ao2_find(protocols, name, OBJ_KEY | OBJ_NOLOCK))) {
+	if ((protocol = ao2_find(server->protocols, name, OBJ_KEY | OBJ_NOLOCK))) {
 		ao2_ref(protocol, -1);
-		ao2_unlock(protocols);
+		ao2_unlock(server->protocols);
 		return -1;
 	}
 
 	if (!(protocol = ao2_alloc(sizeof(*protocol), protocol_destroy_fn))) {
-		ao2_unlock(protocols);
+		ao2_unlock(server->protocols);
 		return -1;
 	}
 
 	if (!(protocol->name = ast_strdup(name))) {
 		ao2_ref(protocol, -1);
-		ao2_unlock(protocols);
+		ao2_unlock(server->protocols);
 		return -1;
 	}
 
 	protocol->callback = callback;
 
-	ao2_link_flags(protocols, protocol, OBJ_NOLOCK);
-	ao2_unlock(protocols);
+	ao2_link_flags(server->protocols, protocol, OBJ_NOLOCK);
+	ao2_unlock(server->protocols);
 	ao2_ref(protocol, -1);
 
 	ast_verb(2, "WebSocket registered sub-protocol '%s'\n", name);
@@ -157,15 +184,11 @@
 	return 0;
 }
 
-int AST_OPTIONAL_API_NAME(ast_websocket_remove_protocol)(const char *name, ast_websocket_callback callback)
+int AST_OPTIONAL_API_NAME(ast_websocket_server_remove_protocol)(struct ast_websocket_server *server, const char *name, ast_websocket_callback callback)
 {
 	struct websocket_protocol *protocol;
 
-	if (!protocols) {
-		return -1;
-	}
-
-	if (!(protocol = ao2_find(protocols, name, OBJ_KEY))) {
+	if (!(protocol = ao2_find(server->protocols, name, OBJ_KEY))) {
 		return -1;
 	}
 
@@ -174,7 +197,7 @@
 		return -1;
 	}
 
-	ao2_unlink(protocols, protocol);
+	ao2_unlink(server->protocols, protocol);
 	ao2_ref(protocol, -1);
 
 	ast_verb(2, "WebSocket unregistered sub-protocol '%s'\n", name);
@@ -474,20 +497,22 @@
 	return 0;
 }
 
-/*! \brief Callback that is executed everytime an HTTP request is received by this module */
-static int websocket_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
+int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
 {
 	struct ast_variable *v;
 	char *upgrade = NULL, *key = NULL, *key1 = NULL, *key2 = NULL, *protos = NULL, *requested_protocols = NULL, *protocol = NULL;
 	int version = 0, flags = 1;
 	struct websocket_protocol *protocol_handler = NULL;
 	struct ast_websocket *session;
+	struct ast_websocket_server *server;
 
 	/* Upgrade requests are only permitted on GET methods */
 	if (method != AST_HTTP_GET) {
 		ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
 		return -1;
 	}
+
+	server = urih->data;
 
 	/* Get the minimum headers required to satisfy our needs */
 	for (v = headers; v; v = v->next) {
@@ -533,7 +558,7 @@
 
 	/* Iterate through the requested protocols trying to find one that we have a handler for */
 	while ((protocol = strsep(&requested_protocols, ","))) {
-		if ((protocol_handler = ao2_find(protocols, ast_strip(protocol), OBJ_KEY))) {
+		if ((protocol_handler = ao2_find(server->protocols, ast_strip(protocol), OBJ_KEY))) {
 			break;
 		}
 	}
@@ -619,7 +644,7 @@
 }
 
 static struct ast_http_uri websocketuri = {
-	.callback = websocket_callback,
+	.callback = ast_websocket_uri_cb,
 	.description = "Asterisk HTTP WebSocket",
 	.uri = "ws",
 	.has_subtree = 0,
@@ -664,9 +689,30 @@
 	ast_websocket_unref(session);
 }
 
+int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_websocket_callback callback)
+{
+	struct ast_websocket_server *ws_server = websocketuri.data;
+	if (!ws_server) {
+		return -1;
+	}
+	return ast_websocket_server_add_protocol(ws_server, name, callback);
+}
+
+int AST_OPTIONAL_API_NAME(ast_websocket_remove_protocol)(const char *name, ast_websocket_callback callback)
+{
+	struct ast_websocket_server *ws_server = websocketuri.data;
+	if (!ws_server) {
+		return -1;
+	}
+	return ast_websocket_server_remove_protocol(ws_server, name, callback);
+}
+
 static int load_module(void)
 {
-	protocols = ao2_container_alloc(MAX_PROTOCOL_BUCKETS, protocol_hash_fn, protocol_cmp_fn);
+	websocketuri.data = ast_websocket_server_create();
+	if (!websocketuri.data) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
 	ast_http_uri_link(&websocketuri);
 	ast_websocket_add_protocol("echo", websocket_echo_callback);
 
@@ -677,8 +723,8 @@
 {
 	ast_websocket_remove_protocol("echo", websocket_echo_callback);
 	ast_http_uri_unlink(&websocketuri);
-	ao2_ref(protocols, -1);
-	protocols = NULL;
+	ao2_ref(websocketuri.data, -1);
+	websocketuri.data = NULL;
 
 	return 0;
 }




More information about the asterisk-commits mailing list