Skip to content
Permalink
Browse files

websocket: added new keepalive mechanism which checks TCP connection;…

… reverted wsconn_put function from 5.1.4; changed memory allocation method in wsconn_put_list and wsconn_get to shmem;
  • Loading branch information...
Andrey Deykunov
Andrey Deykunov committed Mar 15, 2019
1 parent 5c39551 commit b3e03d03574ff4ff076005bb8a01d7461af2f8f5
@@ -221,6 +221,7 @@ static int mod_init(void)
switch(ws_keepalive_mechanism) {
case KEEPALIVE_MECHANISM_PING:
case KEEPALIVE_MECHANISM_PONG:
case KEEPALIVE_MECHANISM_TCP_CONN_CHECK:
break;
default:
ws_keepalive_mechanism = DEFAULT_KEEPALIVE_MECHANISM;
@@ -439,9 +439,57 @@ int wsconn_put_mode(ws_connection_t *wsc, int mode)
/* must be called with unlocked WSCONN_LOCK */
int wsconn_put(ws_connection_t *wsc)
{
return wsconn_put_mode(wsc, 1);
int destroy = 0;

LM_DBG("wsconn_put start for [%p] refcnt [%d]\n", wsc,
atomic_get(&wsc->refcnt));

if(!wsc)
return -1;

WSCONN_LOCK;
/* refcnt == 0*/
if(wsconn_unref(wsc)) {
/* Remove from the WebSocket used list */
if(wsconn_used_list->head == wsc)
wsconn_used_list->head = wsc->used_next;
if(wsconn_used_list->tail == wsc)
wsconn_used_list->tail = wsc->used_prev;
if(wsc->used_prev)
wsc->used_prev->used_next = wsc->used_next;
if(wsc->used_next)
wsc->used_next->used_prev = wsc->used_prev;

/* remove from wsconn_id_hash */
wsconn_listrm(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);

/* stat */
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);

destroy = 1;
}
WSCONN_UNLOCK;

LM_DBG("wsconn_put end for [%p] refcnt [%d]\n", wsc,
atomic_get(&wsc->refcnt));

/* wsc is removed from all lists and can be destroyed safely */
if(destroy)
wsconn_dtor(wsc);

return 0;
}

/* must be called with unlocked WSCONN_LOCK */
// int wsconn_put(ws_connection_t *wsc)
// {
// return wsconn_put_mode(wsc, 1);
// }

ws_connection_t *wsconn_get(int id)
{
int id_hash = tcp_id_hash(id);
@@ -518,7 +566,7 @@ ws_connection_t **wsconn_get_list(void)

/* allocate a NULL terminated list of wsconn pointers */
list_size = (list_len + 1) * sizeof(ws_connection_t *);
list = pkg_malloc(list_size);
list = shm_malloc(list_size);
if(!list)
goto end;

@@ -569,7 +617,7 @@ int wsconn_put_list(ws_connection_t **list_head)
wsc = *(++list);
}

pkg_free(list_head);
shm_free(list_head);

return 0;
}
@@ -796,39 +796,42 @@ void ws_keepalive(unsigned int ticks, void *param)
int check_time =
(int)time(NULL) - cfg_get(websocket, ws_cfg, keepalive_timeout);

ws_connection_id_t *list_head = NULL;
ws_connection_t **list = NULL, **list_head = NULL;
ws_connection_t *wsc = NULL;
int i = 0;
int idx = (int)(long)param;

/* get an array of pointer to all ws connection */
list_head = wsconn_get_list_ids(idx);
list_head = wsconn_get_list();
if(!list_head)
return;

while(list_head[i].id!=-1) {
wsc = wsconn_get(list_head[i].id);
if(wsc && wsc->last_used < check_time) {
if(wsc->state == WS_S_CLOSING || wsc->awaiting_pong) {
LM_WARN("forcibly closing connection\n");
wsconn_close_now(wsc);
} else {
int opcode = (ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING)
? OPCODE_PING
: OPCODE_PONG;
ping_pong(wsc, opcode);
list = list_head;
wsc = *list_head;
while(wsc && wsc->last_used < check_time) {
if (ws_keepalive_mechanism == KEEPALIVE_MECHANISM_TCP_CONN_CHECK) {
struct tcp_connection *con = tcpconn_get(wsc->id, 0, 0, 0, 0);
if(!con) {
LM_INFO("tcp connection has lost\n");
wsc->state = WS_S_CLOSING;
}
}
if(wsc) {
wsconn_put_id(list_head[i].id);

if(wsc->state == WS_S_CLOSING || wsc->awaiting_pong) {
LM_INFO("forcibly closing connection\n");
wsconn_close_now(wsc);
} else {
int opcode = (ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING)
? OPCODE_PING
: OPCODE_PONG;
ping_pong(wsc, opcode);
}
i++;

wsc = *(++list);
}

wsconn_put_list_ids(list_head);
wsconn_put_list(list_head);
}


int ws_close(sip_msg_t *msg)
{
ws_connection_t *wsc;
@@ -40,7 +40,8 @@ enum
{
KEEPALIVE_MECHANISM_NONE = 0,
KEEPALIVE_MECHANISM_PING = 1,
KEEPALIVE_MECHANISM_PONG = 2
KEEPALIVE_MECHANISM_PONG = 2,
KEEPALIVE_MECHANISM_TCP_CONN_CHECK = 3
};
#define DEFAULT_KEEPALIVE_MECHANISM KEEPALIVE_MECHANISM_PING
extern int ws_keepalive_mechanism;

0 comments on commit b3e03d0

Please sign in to comment.
You can’t perform that action at this time.