[sr-dev] git:master: modules/websocket: Added ws_close() exported function

Peter Dunkley peter.dunkley at crocodile-rcs.com
Fri May 10 21:04:50 CEST 2013


Module: sip-router
Branch: master
Commit: 9af456f292e25be2c5689212ed097177a5a16338
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9af456f292e25be2c5689212ed097177a5a16338

Author: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Date:   Fri May 10 20:04:02 2013 +0100

modules/websocket: Added ws_close() exported function

- Enables immediate closure of a WebSocket connection from the configuration
  file.

---

 modules/websocket/README                  |   36 ++++++++++++++--
 modules/websocket/doc/websocket_admin.xml |   36 +++++++++++++++
 modules/websocket/ws_frame.c              |   67 +++++++++++++++++++++++++++++
 modules/websocket/ws_frame.h              |    3 +
 modules/websocket/ws_mod.c                |   26 +++++++++++
 5 files changed, 164 insertions(+), 4 deletions(-)

diff --git a/modules/websocket/README b/modules/websocket/README
index ef1bbf0..5888d63 100644
--- a/modules/websocket/README
+++ b/modules/websocket/README
@@ -36,6 +36,7 @@ Peter Dunkley
         5. Functions
 
               5.1. ws_handle_handshake()
+              5.2. ws_close([status, reason[, connection_id]])
 
         6. MI Commands
 
@@ -62,7 +63,8 @@ Peter Dunkley
    1.8. Set sub_protocols parameter
    1.9. Set cors_mode parameter
    1.10. ws_handle_handshake usage
-   1.11. event_route[websocket:closed] usage
+   1.11. ws_close usage
+   1.12. event_route[websocket:closed] usage
 
 Chapter 1. Admin Guide
 
@@ -93,6 +95,7 @@ Chapter 1. Admin Guide
    5. Functions
 
         5.1. ws_handle_handshake()
+        5.2. ws_close([status, reason[, connection_id]])
 
    6. MI Commands
 
@@ -239,8 +242,7 @@ request_route {
                         fix_nated_register();
                 else {
                         if (!add_contact_alias()) {
-                                xlog("L_ERR", "Error aliasing contact <$ct>\n")
-;
+                                xlog("L_ERR", "Error aliasing contact <$ct>\n");
                                 sl_send_reply("400", "Bad Request");
                                 exit;
                         }
@@ -433,6 +435,7 @@ modparam("websocket", "cors_mode", 2)
 5. Functions
 
    5.1. ws_handle_handshake()
+   5.2. ws_close([status, reason[, connection_id]])
 
 5.1.  ws_handle_handshake()
 
@@ -453,6 +456,31 @@ Note
 ws_handle_handshake();
 ...
 
+5.2.  ws_close([status, reason[, connection_id]])
+
+   This function closes a WebSocket connection.
+
+   The function returns -1 if there is an error and 1 if it succeeds.
+
+   The meaning of the parameters is as follows:
+     * status - an integer indicating the reason for closure.
+     * reason - a string describing the reason for closure.
+     * connection_id - the connection to close. If not specified the
+       connection the current message arrived on will be closed.
+
+Note
+
+   status and reason values SHOULD correspond to the definitions in
+   section 7.4 of RFC 6455. If these parameters are not used the defaults
+   of "1000" and "Normal closure" will be used.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.11. ws_close usage
+...
+ws_close(4000, "Because I say so");
+...
+
 6. MI Commands
 
    6.1. ws.dump
@@ -560,7 +588,7 @@ Note
    connection closes. The connection may be identified using the the $si
    and $sp pseudo-variables.
 
-   Example 1.11. event_route[websocket:closed] usage
+   Example 1.12. event_route[websocket:closed] usage
 ...
 event_route[websocket:closed] {
         xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n");
diff --git a/modules/websocket/doc/websocket_admin.xml b/modules/websocket/doc/websocket_admin.xml
index bbdc62b..cdc3372 100644
--- a/modules/websocket/doc/websocket_admin.xml
+++ b/modules/websocket/doc/websocket_admin.xml
@@ -457,6 +457,42 @@ ws_handle_handshake();
 </programlisting>
 		</example>
 	</section>
+	<section id="websocket.f.ws_close">
+		<title>
+		<function moreinfo="none">ws_close([status,
+			reason[, connection_id]])</function>
+		</title>
+		<para>This function closes a WebSocket connection.</para>
+		<para>The function returns -1 if there is an error and 1 if
+		it succeeds.</para>
+		<para>The meaning of the parameters is as follows:</para>
+		<itemizedlist>
+			<listitem><para><emphasis>status</emphasis> - an
+			integer indicating the reason for closure.</para>
+			</listitem>
+			<listitem><para><emphasis>reason</emphasis> - a
+			string describing the reason for closure.</para>
+			</listitem>
+			<listitem><para><emphasis>connection_id</emphasis> - the
+			connection to close. If not specified the connection the
+			current message arrived on will be closed.</para>
+			</listitem>
+		</itemizedlist>
+		<note><para><emphasis>status</emphasis> and
+		<emphasis>reason</emphasis> values SHOULD correspond to the
+		definitions in section 7.4 of RFC 6455. If these parameters are
+		not used the defaults of "1000" and "Normal
+		closure" will be used.</para></note>
+		<para>This function can be used from ANY_ROUTE.</para>
+		<example>
+		<title><function>ws_close</function> usage</title>
+		<programlisting format="linespecific">
+...
+ws_close(4000, "Because I say so");
+...
+</programlisting>
+		</example>
+	</section>
 	</section>
 
 	<section>
diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c
index b6be135..7b76bac 100644
--- a/modules/websocket/ws_frame.c
+++ b/modules/websocket/ws_frame.c
@@ -831,3 +831,70 @@ void ws_keepalive(unsigned int ticks, void *param)
 	}
 	
 }
+
+int ws_close(sip_msg_t *msg)
+{
+	ws_connection_t *wsc;
+
+	if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
+		LM_ERR("failed to retrieve WebSocket connection\n");
+		return -1;
+	}
+
+	return (close_connection(wsc, LOCAL_CLOSE, 1000,
+				 str_status_normal_closure) == 0) ? 1: 0;
+}
+
+int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
+{
+	int status;
+	str reason;
+	ws_connection_t *wsc;
+
+	if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
+		LM_ERR("failed to get status code\n");
+		return -1;
+	}
+
+	if (get_str_fparam(&reason, msg, (fparam_t *) _reason) < 0) {
+		LM_ERR("failed to get reason string\n");
+		return -1;
+	}
+
+	if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
+		LM_ERR("failed to retrieve WebSocket connection\n");
+		return -1;
+	}
+
+	return (close_connection(wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
+}
+
+int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
+{
+	int status;
+	str reason;
+	int con;
+	ws_connection_t *wsc;
+
+	if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
+		LM_ERR("failed to get status code\n");
+		return -1;
+	}
+
+	if (get_str_fparam(&reason, msg, (fparam_t *) _reason) < 0) {
+		LM_ERR("failed to get reason string\n");
+		return -1;
+	}
+
+	if (get_int_fparam(&con, msg, (fparam_t *) _con) < 0) {
+		LM_ERR("failed to get connection ID\n");
+		return -1;
+	}
+
+	if ((wsc = wsconn_get(con)) == NULL) {
+		LM_ERR("failed to retrieve WebSocket connection\n");
+		return -1;
+	}
+
+	return (close_connection(wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
+}
diff --git a/modules/websocket/ws_frame.h b/modules/websocket/ws_frame.h
index e10d584..1210c6c 100644
--- a/modules/websocket/ws_frame.h
+++ b/modules/websocket/ws_frame.h
@@ -73,5 +73,8 @@ struct mi_root *ws_mi_close(struct mi_root *cmd, void *param);
 struct mi_root *ws_mi_ping(struct mi_root *cmd, void *param);
 struct mi_root *ws_mi_pong(struct mi_root *cmd, void *param);
 void ws_keepalive(unsigned int ticks, void *param);
+int ws_close(sip_msg_t *msg);
+int ws_close2(sip_msg_t *msg, char *_status, char *_reason);
+int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con);
 
 #endif /* _WS_FRAME_H */
diff --git a/modules/websocket/ws_mod.c b/modules/websocket/ws_mod.c
index 9a6ae66..9b82dea 100644
--- a/modules/websocket/ws_mod.c
+++ b/modules/websocket/ws_mod.c
@@ -32,6 +32,7 @@
 #include "../../lib/kcore/kstats_wrapper.h"
 #include "../../lib/kmi/mi.h"
 #include "../../mem/mem.h"
+#include "../../mod_fix.h"
 #include "../../parser/msg_parser.h"
 #include "ws_conn.h"
 #include "ws_handshake.h"
@@ -47,6 +48,7 @@ MODULE_VERSION
 static int mod_init(void);
 static int child_init(int rank);
 static void destroy(void);
+static int ws_close_fixup(void** param, int param_no);
 
 sl_api_t ws_slb;
 
@@ -60,6 +62,17 @@ static int ws_keepalive_processes = DEFAULT_KEEPALIVE_PROCESSES;
 
 static cmd_export_t cmds[]= 
 {
+	/* ws_frame.c */
+	{ "ws_close", (cmd_function) ws_close,
+	  0, 0, 0,
+	  ANY_ROUTE },
+	{ "ws_close", (cmd_function) ws_close2,
+	  2, ws_close_fixup, 0,
+	  ANY_ROUTE },
+	{ "ws_close", (cmd_function) ws_close3,
+	  3, ws_close_fixup, 0,
+	  ANY_ROUTE },
+
 	/* ws_handshake.c */
 	{ "ws_handle_handshake", (cmd_function) ws_handle_handshake,
 	  0, 0, 0,
@@ -295,3 +308,16 @@ static void destroy(void)
 {
 	wsconn_destroy();
 }
+
+static int ws_close_fixup(void** param, int param_no)
+{
+	switch(param_no) {
+	case 1:
+	case 3:
+		return fixup_var_int_1(param, 1);
+	case 2:
+		return fixup_spve_null(param, 1);
+	default:
+		return 0;
+	}
+}




More information about the sr-dev mailing list