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 <[email protected]>
Committer: Peter Dunkley <[email protected]>
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 &quot;1000&quot; and &quot;Normal
+               closure&quot; 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;
+       }
+}


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to