2
0
Эх сурвалжийг харах

modules/websocket: added lots more SIP/MSRP specific statistics

- also updated output of dump MI command to include sub-protocol information
Peter Dunkley 12 жил өмнө
parent
commit
21fa34f61b

+ 43 - 4
modules/websocket/ws_conn.c

@@ -48,6 +48,10 @@ ws_connection_used_list_t *wsconn_used_list = NULL;
 
 
 stat_var *ws_current_connections;
 stat_var *ws_current_connections;
 stat_var *ws_max_concurrent_connections;
 stat_var *ws_max_concurrent_connections;
+stat_var *ws_sip_current_connections;
+stat_var *ws_sip_max_concurrent_connections;
+stat_var *ws_msrp_current_connections;
+stat_var *ws_msrp_max_concurrent_connections;
 
 
 char *wsconn_state_str[] =
 char *wsconn_state_str[] =
 {
 {
@@ -126,9 +130,15 @@ error:
 static inline void _wsconn_rm(ws_connection_t *wsc)
 static inline void _wsconn_rm(ws_connection_t *wsc)
 {
 {
 	wsconn_listrm(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);
 	wsconn_listrm(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);
+
+	update_stat(ws_current_connections, -1);
+	if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
+		update_stat(ws_sip_current_connections, -1);
+	else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+		update_stat(ws_msrp_current_connections, -1);
+
 	shm_free(wsc);
 	shm_free(wsc);
 	wsc = NULL;
 	wsc = NULL;
-	update_stat(ws_current_connections, -1);
 }
 }
 
 
 void wsconn_destroy(void)
 void wsconn_destroy(void)
@@ -215,11 +225,32 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
 
 
 	/* Update connection statistics */
 	/* Update connection statistics */
 	lock_get(wsstat_lock);
 	lock_get(wsstat_lock);
+
 	update_stat(ws_current_connections, 1);
 	update_stat(ws_current_connections, 1);
 	cur_cons = get_stat_val(ws_current_connections);
 	cur_cons = get_stat_val(ws_current_connections);
 	max_cons = get_stat_val(ws_max_concurrent_connections);
 	max_cons = get_stat_val(ws_max_concurrent_connections);
 	if (max_cons < cur_cons)
 	if (max_cons < cur_cons)
 		update_stat(ws_max_concurrent_connections, cur_cons - max_cons);
 		update_stat(ws_max_concurrent_connections, cur_cons - max_cons);
+
+	if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
+	{
+		update_stat(ws_sip_current_connections, 1);
+		cur_cons = get_stat_val(ws_sip_current_connections);
+		max_cons = get_stat_val(ws_sip_max_concurrent_connections);
+		if (max_cons < cur_cons)
+			update_stat(ws_sip_max_concurrent_connections,
+					cur_cons - max_cons);
+	}
+	else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+	{
+		update_stat(ws_msrp_current_connections, 1);
+		cur_cons = get_stat_val(ws_msrp_current_connections);
+		max_cons = get_stat_val(ws_msrp_max_concurrent_connections);
+		if (max_cons < cur_cons)
+			update_stat(ws_msrp_max_concurrent_connections,
+					cur_cons - max_cons);
+	}
+
 	lock_release(wsstat_lock);
 	lock_release(wsstat_lock);
 
 
 	return 0;
 	return 0;
@@ -352,7 +383,7 @@ ws_connection_t *wsconn_get(int id)
 static int add_node(struct mi_root *tree, ws_connection_t *wsc)
 static int add_node(struct mi_root *tree, ws_connection_t *wsc)
 {
 {
 	int interval;
 	int interval;
-	char *src_proto, *dst_proto, *pong;
+	char *src_proto, *dst_proto, *pong, *sub_protocol;
 	char src_ip[IP6_MAX_STR_SIZE + 1], dst_ip[IP6_MAX_STR_SIZE + 1];
 	char src_ip[IP6_MAX_STR_SIZE + 1], dst_ip[IP6_MAX_STR_SIZE + 1];
 	struct tcp_connection *con = tcpconn_get(wsc->id, 0, 0, 0, 0);
 	struct tcp_connection *con = tcpconn_get(wsc->id, 0, 0, 0, 0);
 
 
@@ -369,10 +400,17 @@ static int add_node(struct mi_root *tree, ws_connection_t *wsc)
 		pong = wsc->awaiting_pong ? "awaiting Pong, " : "";
 		pong = wsc->awaiting_pong ? "awaiting Pong, " : "";
 
 
 		interval = (int)time(NULL) - wsc->last_used;
 		interval = (int)time(NULL) - wsc->last_used;
+		if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
+			sub_protocol = "sip";
+		else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+			sub_protocol = "msrp";
+		else
+			sub_protocol = "**UNKNOWN**";
 
 
 		if (addf_mi_node_child(&tree->node, 0, 0, 0,
 		if (addf_mi_node_child(&tree->node, 0, 0, 0,
 					"%d: %s:%s:%hu -> %s:%s:%hu (state: %s"
 					"%d: %s:%s:%hu -> %s:%s:%hu (state: %s"
-					", %slast used %ds ago)",
+					", %s last used %ds ago"
+					", sub-protocol: %s)",
 					wsc->id,
 					wsc->id,
 					src_proto,
 					src_proto,
 					strlen(src_ip) ? src_ip : "*",
 					strlen(src_ip) ? src_ip : "*",
@@ -382,7 +420,8 @@ static int add_node(struct mi_root *tree, ws_connection_t *wsc)
 					con->rcv.dst_port,
 					con->rcv.dst_port,
 					wsconn_state_str[wsc->state],
 					wsconn_state_str[wsc->state],
 					pong,
 					pong,
-					interval) == 0)
+					interval,
+					sub_protocol) == 0)
 			return -1;
 			return -1;
 
 
 		return 1;
 		return 1;

+ 4 - 0
modules/websocket/ws_conn.h

@@ -72,6 +72,10 @@ extern char *wsconn_state_str[];
 
 
 extern stat_var *ws_current_connections;
 extern stat_var *ws_current_connections;
 extern stat_var *ws_max_concurrent_connections;
 extern stat_var *ws_max_concurrent_connections;
+extern stat_var *ws_sip_current_connections;
+extern stat_var *ws_sip_max_concurrent_connections;
+extern stat_var *ws_msrp_current_connections;
+extern stat_var *ws_msrp_max_concurrent_connections;
 
 
 int wsconn_init(void);
 int wsconn_init(void);
 void wsconn_destroy(void);
 void wsconn_destroy(void);

+ 39 - 1
modules/websocket/ws_frame.c

@@ -103,6 +103,16 @@ stat_var *ws_local_closed_connections;
 stat_var *ws_received_frames;
 stat_var *ws_received_frames;
 stat_var *ws_remote_closed_connections;
 stat_var *ws_remote_closed_connections;
 stat_var *ws_transmitted_frames;
 stat_var *ws_transmitted_frames;
+stat_var *ws_sip_failed_connections;
+stat_var *ws_sip_local_closed_connections;
+stat_var *ws_sip_received_frames;
+stat_var *ws_sip_remote_closed_connections;
+stat_var *ws_sip_transmitted_frames;
+stat_var *ws_msrp_failed_connections;
+stat_var *ws_msrp_local_closed_connections;
+stat_var *ws_msrp_received_frames;
+stat_var *ws_msrp_remote_closed_connections;
+stat_var *ws_msrp_transmitted_frames;
 
 
 /* WebSocket status text */
 /* WebSocket status text */
 static str str_status_normal_closure = str_init("Normal closure");
 static str str_status_normal_closure = str_init("Normal closure");
@@ -274,13 +284,26 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
 		LM_ERR("sending WebSocket frame\n");
 		LM_ERR("sending WebSocket frame\n");
 		pkg_free(send_buf);
 		pkg_free(send_buf);
 		update_stat(ws_failed_connections, 1);
 		update_stat(ws_failed_connections, 1);
+		if (frame->wsc->sub_protocol == SUB_PROTOCOL_SIP)
+			update_stat(ws_sip_failed_connections, 1);
+		else if (frame->wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+			update_stat(ws_msrp_failed_connections, 1);
 		if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
 		if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
 			LM_ERR("removing WebSocket connection\n");
 			LM_ERR("removing WebSocket connection\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
 	update_stat(ws_transmitted_frames, 1);
 	update_stat(ws_transmitted_frames, 1);
-
+	switch (frame->opcode)
+	{
+	case OPCODE_TEXT_FRAME:
+	case OPCODE_BINARY_FRAME:
+		if (frame->wsc->sub_protocol == SUB_PROTOCOL_SIP)
+			update_stat(ws_sip_transmitted_frames, 1);
+		else if (frame->wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+			update_stat(ws_msrp_transmitted_frames, 1);
+	}
+	
 	pkg_free(send_buf);
 	pkg_free(send_buf);
 	return 0;
 	return 0;
 }
 }
@@ -326,9 +349,22 @@ static int close_connection(ws_connection_t *wsc, ws_close_type_t type,
 		{
 		{
 			frame.wsc->state = WS_S_CLOSING;
 			frame.wsc->state = WS_S_CLOSING;
 			update_stat(ws_local_closed_connections, 1);
 			update_stat(ws_local_closed_connections, 1);
+			if (frame.wsc->sub_protocol == SUB_PROTOCOL_SIP)
+				update_stat(ws_sip_local_closed_connections, 1);
+			else if (frame.wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+				update_stat(ws_msrp_local_closed_connections,
+						1);
 		}
 		}
 		else
 		else
+		{
 			update_stat(ws_remote_closed_connections, 1);
 			update_stat(ws_remote_closed_connections, 1);
+			if (frame.wsc->sub_protocol == SUB_PROTOCOL_SIP)
+				update_stat(ws_sip_remote_closed_connections,
+						1);
+			else if (frame.wsc->sub_protocol == SUB_PROTOCOL_MSRP)
+				update_stat(ws_msrp_remote_closed_connections,
+						1);
+		}
 	}
 	}
 	else /* if (frame->wsc->state == WS_S_CLOSING) */
 	else /* if (frame->wsc->state == WS_S_CLOSING) */
 		wsconn_close_now(wsc);
 		wsconn_close_now(wsc);
@@ -578,6 +614,7 @@ int ws_frame_receive(void *data)
 		{
 		{
 			LM_DBG("Rx SIP message:\n%.*s\n", frame.payload_len,
 			LM_DBG("Rx SIP message:\n%.*s\n", frame.payload_len,
 				frame.payload_data);
 				frame.payload_data);
+			update_stat(ws_sip_received_frames, 1);
 			return receive_msg(frame.payload_data,
 			return receive_msg(frame.payload_data,
 						frame.payload_len,
 						frame.payload_len,
 						tcpinfo->rcv);
 						tcpinfo->rcv);
@@ -586,6 +623,7 @@ int ws_frame_receive(void *data)
 		{
 		{
 			LM_DBG("Rx MSRP frame:\n%.*s\n", frame.payload_len,
 			LM_DBG("Rx MSRP frame:\n%.*s\n", frame.payload_len,
 				frame.payload_data);
 				frame.payload_data);
+			update_stat(ws_msrp_received_frames, 1);
 			if (likely(sr_event_enabled(SREV_TCP_MSRP_FRAME)))
 			if (likely(sr_event_enabled(SREV_TCP_MSRP_FRAME)))
 			{
 			{
 				tcp_event_info_t tev;
 				tcp_event_info_t tev;

+ 10 - 0
modules/websocket/ws_frame.h

@@ -57,6 +57,16 @@ extern stat_var *ws_local_closed_connections;
 extern stat_var *ws_received_frames;
 extern stat_var *ws_received_frames;
 extern stat_var *ws_remote_closed_connections;
 extern stat_var *ws_remote_closed_connections;
 extern stat_var *ws_transmitted_frames;
 extern stat_var *ws_transmitted_frames;
+extern stat_var *ws_sip_failed_connections;
+extern stat_var *ws_sip_local_closed_connections;
+extern stat_var *ws_sip_received_frames;
+extern stat_var *ws_sip_remote_closed_connections;
+extern stat_var *ws_sip_transmitted_frames;
+extern stat_var *ws_msrp_failed_connections;
+extern stat_var *ws_msrp_local_closed_connections;
+extern stat_var *ws_msrp_received_frames;
+extern stat_var *ws_msrp_remote_closed_connections;
+extern stat_var *ws_msrp_transmitted_frames;
 
 
 int ws_frame_receive(void *data);
 int ws_frame_receive(void *data);
 int ws_frame_transmit(void *data);
 int ws_frame_transmit(void *data);

+ 10 - 10
modules/websocket/ws_handshake.c

@@ -46,8 +46,8 @@ int ws_sub_protocols = DEFAULT_SUB_PROTOCOLS;
 
 
 stat_var *ws_failed_handshakes;
 stat_var *ws_failed_handshakes;
 stat_var *ws_successful_handshakes;
 stat_var *ws_successful_handshakes;
-stat_var *ws_sip_handshakes;
-stat_var *ws_msrp_handshakes;
+stat_var *ws_sip_successful_handshakes;
+stat_var *ws_msrp_successful_handshakes;
 
 
 static str str_sip = str_init("sip");
 static str str_sip = str_init("sip");
 static str str_msrp = str_init("msrp");
 static str str_msrp = str_init("msrp");
@@ -308,14 +308,7 @@ int ws_handle_handshake(struct sip_msg *msg)
 					str_hdr_sec_websocket_version.len,
 					str_hdr_sec_websocket_version.len,
 					str_hdr_sec_websocket_version.s,
 					str_hdr_sec_websocket_version.s,
 					WS_VERSION);
 					WS_VERSION);
-		if (ws_send_reply(msg, 400, &str_status_bad_request, &headers)
-				== 0)
-		{
-			if (ws_sub_protocols & SUB_PROTOCOL_SIP)
-				update_stat(ws_sip_handshakes, 1);
-			else if (ws_sub_protocols & SUB_PROTOCOL_MSRP)
-				update_stat(ws_msrp_handshakes, 1);
-		}
+		ws_send_reply(msg, 400, &str_status_bad_request, &headers);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -390,6 +383,13 @@ int ws_handle_handshake(struct sip_msg *msg)
 
 
 		return 0;
 		return 0;
 	}
 	}
+	else
+	{
+		if (sub_protocol & SUB_PROTOCOL_SIP)
+			update_stat(ws_sip_successful_handshakes, 1);
+		else if (sub_protocol & SUB_PROTOCOL_MSRP)
+			update_stat(ws_msrp_successful_handshakes, 1);
+	}
 
 
 	return 1;
 	return 1;
 }
 }

+ 3 - 7
modules/websocket/ws_handshake.h

@@ -26,20 +26,16 @@
 
 
 #include "../../sr_module.h"
 #include "../../sr_module.h"
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
+#include "ws_mod.h"
 
 
-enum
-{
-	SUB_PROTOCOL_SIP  = (1 << 0),
-	SUB_PROTOCOL_MSRP = (1 << 1)
-};
 #define DEFAULT_SUB_PROTOCOLS	(SUB_PROTOCOL_SIP | SUB_PROTOCOL_MSRP)
 #define DEFAULT_SUB_PROTOCOLS	(SUB_PROTOCOL_SIP | SUB_PROTOCOL_MSRP)
 #define SUB_PROTOCOL_ALL	(SUB_PROTOCOL_SIP | SUB_PROTOCOL_MSRP)
 #define SUB_PROTOCOL_ALL	(SUB_PROTOCOL_SIP | SUB_PROTOCOL_MSRP)
 extern int ws_sub_protocols;
 extern int ws_sub_protocols;
 
 
 extern stat_var *ws_failed_handshakes;
 extern stat_var *ws_failed_handshakes;
 extern stat_var *ws_successful_handshakes;
 extern stat_var *ws_successful_handshakes;
-extern stat_var *ws_sip_handshakes;
-extern stat_var *ws_msrp_handshakes;
+extern stat_var *ws_sip_successful_handshakes;
+extern stat_var *ws_msrp_successful_handshakes;
 
 
 int ws_handle_handshake(struct sip_msg *msg);
 int ws_handle_handshake(struct sip_msg *msg);
 struct mi_root *ws_mi_disable(struct mi_root *cmd, void *param);
 struct mi_root *ws_mi_disable(struct mi_root *cmd, void *param);

+ 25 - 11
modules/websocket/ws_mod.c

@@ -85,21 +85,35 @@ static param_export_t params[]=
 static stat_export_t stats[] =
 static stat_export_t stats[] =
 {
 {
 	/* ws_conn.c */
 	/* ws_conn.c */
-	{ "ws_current_connections",       0, &ws_current_connections },
-	{ "ws_max_concurrent_connections",0, &ws_max_concurrent_connections },
+	{ "ws_current_connections",            0, &ws_current_connections },
+	{ "ws_max_concurrent_connections",     0, &ws_max_concurrent_connections },
+	{ "ws_sip_current_connections",        0, &ws_sip_current_connections },
+        { "ws_sip_max_concurrent_connectons",  0, &ws_sip_max_concurrent_connections },
+        { "ws_msrp_current_connections",       0, &ws_msrp_current_connections },
+        { "ws_msrp_max_concurrent_connectons", 0, &ws_sip_max_concurrent_connections },
 
 
 	/* ws_frame.c */
 	/* ws_frame.c */
-	{ "ws_failed_connections",        0, &ws_failed_connections },
-	{ "ws_local_closed_connections",  0, &ws_local_closed_connections },
-	{ "ws_received_frames",           0, &ws_received_frames },
-	{ "ws_remote_closed_connections", 0, &ws_remote_closed_connections },
-	{ "ws_transmitted_frames",        0, &ws_transmitted_frames },
+	{ "ws_failed_connections",             0, &ws_failed_connections },
+	{ "ws_local_closed_connections",       0, &ws_local_closed_connections },
+	{ "ws_received_frames",                0, &ws_received_frames },
+	{ "ws_remote_closed_connections",      0, &ws_remote_closed_connections },
+	{ "ws_transmitted_frames",             0, &ws_transmitted_frames },
+	{ "ws_sip_failed_connections",         0, &ws_sip_failed_connections },
+	{ "ws_sip_local_closed_connections",   0, &ws_sip_local_closed_connections },
+	{ "ws_sip_received_frames",            0, &ws_sip_received_frames },
+	{ "ws_sip_remote_closed_connections",  0, &ws_sip_remote_closed_connections },
+	{ "ws_sip_transmitted_frames",         0, &ws_sip_transmitted_frames },
+	{ "ws_msrp_failed_connections",        0, &ws_msrp_failed_connections },
+	{ "ws_msrp_local_closed_connections",  0, &ws_msrp_local_closed_connections },
+	{ "ws_msrp_received_frames",           0, &ws_msrp_received_frames },
+	{ "ws_msrp_remote_closed_connections", 0, &ws_msrp_remote_closed_connections },
+	{ "ws_msrp_transmitted_frames",        0, &ws_msrp_transmitted_frames },
 
 
 	/* ws_handshake.c */
 	/* ws_handshake.c */
-	{ "ws_failed_handshakes",         0, &ws_failed_handshakes },
-	{ "ws_successful_handshakes",     0, &ws_successful_handshakes },
-	{ "ws_sip_handshakes",            0, &ws_sip_handshakes },
-	{ "ws_msrp_handshakes",           0, &ws_msrp_handshakes },
+	{ "ws_failed_handshakes",              0, &ws_failed_handshakes },
+	{ "ws_successful_handshakes",          0, &ws_successful_handshakes },
+	{ "ws_sip_successful_handshakes",      0, &ws_sip_successful_handshakes },
+	{ "ws_msrp_successful_handshakes",     0, &ws_msrp_successful_handshakes },
 
 
 	{ 0, 0, 0 }
 	{ 0, 0, 0 }
 };
 };

+ 6 - 0
modules/websocket/ws_mod.h

@@ -28,6 +28,12 @@
 #include "../../kstats_types.h"
 #include "../../kstats_types.h"
 #include "../sl/sl.h"
 #include "../sl/sl.h"
 
 
+enum
+{
+	SUB_PROTOCOL_SIP  = (1 << 0),
+	SUB_PROTOCOL_MSRP = (1 << 1)
+};
+
 extern sl_api_t ws_slb;
 extern sl_api_t ws_slb;
 extern int *ws_enabled;
 extern int *ws_enabled;
 extern gen_lock_t *ws_stats_lock;
 extern gen_lock_t *ws_stats_lock;