Module: sip-router Branch: 4.0 Commit: a7e7d9277f503ab42055b4b3be130e3f4a6fcae1 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a7e7d927...
Author: Hugh Waite hugh.waite@crocodile-rcs.com Committer: Hugh Waite hugh.waite@crocodile-rcs.com Date: Mon Sep 30 10:44:27 2013 +0100
modules/websocket: Fix connection leaks
- Decrease the TCP connection reference count after each use (cherry picked from commit 27474179bdeef0ddaba05389f510446a387d85e1)
Resolved conflicts due to new feeatures in master:
modules/websocket/ws_conn.c modules/websocket/ws_handshake.c
---
modules/websocket/ws_conn.c | 5 +++++ modules/websocket/ws_frame.c | 5 +++++ modules/websocket/ws_handshake.c | 21 +++++++++++++-------- 3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/modules/websocket/ws_conn.c b/modules/websocket/ws_conn.c index 9f9069f..57c2119 100644 --- a/modules/websocket/ws_conn.c +++ b/modules/websocket/ws_conn.c @@ -325,6 +325,7 @@ void wsconn_close_now(ws_connection_t *wsc) return; }
+ tcpconn_put(con); con->send_flags.f |= SND_F_CON_CLOSE; con->state = S_CONN_BAD; con->timeout = get_ticks_raw(); @@ -383,8 +384,12 @@ static int add_node(struct mi_root *tree, ws_connection_t *wsc) wsconn_state_str[wsc->state], pong, interval) == 0) + { + tcpconn_put(con); return -1; + }
+ tcpconn_put(con); return 1; } else diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c index e54a830..124a2fc 100644 --- a/modules/websocket/ws_frame.c +++ b/modules/websocket/ws_frame.c @@ -231,6 +231,7 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close) if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0) { LM_ERR("removing WebSocket connection\n"); + tcpconn_put(con); pkg_free(send_buf); return -1; } @@ -243,6 +244,7 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close) STATS_TX_DROPS; LM_WARN("TCP disabled\n"); pkg_free(send_buf); + tcpconn_put(con); return -1; } } @@ -254,6 +256,7 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close) STATS_TX_DROPS; LM_WARN("TLS disabled\n"); pkg_free(send_buf); + tcpconn_put(con); return -1; } } @@ -280,12 +283,14 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close) update_stat(ws_failed_connections, 1); if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0) LM_ERR("removing WebSocket connection\n"); + tcpconn_put(con); return -1; }
update_stat(ws_transmitted_frames, 1);
pkg_free(send_buf); + tcpconn_put(con); return 0; }
diff --git a/modules/websocket/ws_handshake.c b/modules/websocket/ws_handshake.c index c959ae8..94b7280 100644 --- a/modules/websocket/ws_handshake.c +++ b/modules/websocket/ws_handshake.c @@ -146,7 +146,7 @@ int ws_handle_handshake(struct sip_msg *msg) if (con->type != PROTO_TCP && con->type != PROTO_TLS) { LM_ERR("unsupported transport: %d", con->type); - return 0; + goto end; }
if (parse_headers(msg, HDR_EOH_F, 0) < 0) @@ -154,7 +154,7 @@ int ws_handle_handshake(struct sip_msg *msg) LM_ERR("error parsing headers\n"); ws_send_reply(msg, 500, &str_status_internal_server_error, NULL); - return 0; + goto end; }
/* Process HTTP headers */ @@ -201,7 +201,7 @@ int ws_handle_handshake(struct sip_msg *msg) ws_send_reply(msg, 400, &str_status_bad_request, NULL); - return 0; + goto end; }
LM_DBG("found %.*s: %.*s\n", @@ -245,7 +245,7 @@ int ws_handle_handshake(struct sip_msg *msg) ws_send_reply(msg, 400, &str_status_bad_request, NULL); - return 0; + goto end; }
str2sint(&hdr->body, &version); @@ -263,7 +263,7 @@ int ws_handle_handshake(struct sip_msg *msg) ws_send_reply(msg, 426, &str_status_upgrade_required, &headers); - return 0; + goto end; }
LM_DBG("found %.*s: %.*s\n", @@ -308,7 +308,7 @@ int ws_handle_handshake(struct sip_msg *msg) str_hdr_sec_websocket_version.s, WS_VERSION); ws_send_reply(msg, 400, &str_status_bad_request, &headers); - return 0; + goto end; }
/* Construct reply_key */ @@ -319,7 +319,7 @@ int ws_handle_handshake(struct sip_msg *msg) LM_ERR("allocating pkg memory\n"); ws_send_reply(msg, 500, &str_status_internal_server_error, NULL); - return 0; + goto end; } memcpy(reply_key.s, key.s, key.len); memcpy(reply_key.s + key.len, str_ws_guid.s, str_ws_guid.len); @@ -380,10 +380,15 @@ int ws_handle_handshake(struct sip_msg *msg) if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) != NULL) wsconn_rm(wsc, WSCONN_EVENTROUTE_NO);
- return 0; + goto end; }
+ tcpconn_put(con); return 1; +end: + if (con) + tcpconn_put(con); + return 0; }
struct mi_root *ws_mi_disable(struct mi_root *cmd, void *param)