Skip to content

Commit

Permalink
freeswitch: Avoid dangling socket structs in reactor
Browse files Browse the repository at this point in the history
Should reactor_del_reader() ever fail, retry it using index "-1" in
order to guarantee removal of the file descriptor from the EPOLL
controller.

Also fix several occurences of bad 3rd parameter (IO_WATCH_READ instead
of IO_FD_CLOSING, which was probably the intended argument).

(cherry picked from commit 26a9e3a)
  • Loading branch information
liviuchircu committed Dec 18, 2023
1 parent 34fe057 commit 6d0ac4f
Showing 1 changed file with 12 additions and 21 deletions.
33 changes: 12 additions & 21 deletions modules/freeswitch/fs_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,24 @@ extern void fs_api_set_proc_no(void);
extern void evs_free(fs_evs *sock);
extern struct fs_event *get_event(fs_evs *sock, const str *name);

static int destroy_fs_evs(fs_evs *sock, int idx)
static void destroy_fs_evs(fs_evs *sock, int idx)
{
esl_status_t rc;
int ret = 0;

LM_DBG("destroying sock %s:%d\n", sock->host.s, sock->port);

if (reactor_del_reader(sock->handle->sock, idx, IO_WATCH_READ) != 0) {
LM_ERR("del failed for sock %d\n", sock->handle->sock);
ret = 1;
if (idx > 0 && reactor_del_reader(sock->handle->sock, idx, IO_FD_CLOSING) != 0) {
LM_ERR("failed to delete sock %d, idx %d\n", sock->handle->sock, idx);
idx = -1;
}

if (idx < 0 && reactor_del_reader(sock->handle->sock, -1, IO_FD_CLOSING) != 0)
LM_DBG("failed to delete sock %d, idx -1\n", sock->handle->sock);

rc = esl_disconnect(sock->handle);
if (rc != ESL_SUCCESS) {
if (rc != ESL_SUCCESS)
LM_ERR("disconnect error %d on FS sock %.*s:%d\n",
rc, sock->host.len, sock->host.s, sock->port);
ret = 1;
}

list_del(&sock->list);

Expand All @@ -86,8 +86,6 @@ static int destroy_fs_evs(fs_evs *sock, int idx)
}

evs_free(sock);

return ret;
}

int fs_renew_stats(fs_evs *sock, const cJSON *ev)
Expand Down Expand Up @@ -210,9 +208,7 @@ inline static int handle_io(struct fd_map *fm, int idx, int event_type)
/* ignore the event: nobody's using this socket anymore, close it */
lock_start_write(sockets_lock);
if (sock->ref == 0) {
if (destroy_fs_evs(sock, idx) != 0)
LM_ERR("failed to destroy FS evs!\n");

destroy_fs_evs(sock, idx);
lock_stop_write(sockets_lock);
return 0;
}
Expand All @@ -226,7 +222,7 @@ inline static int handle_io(struct fd_map *fm, int idx, int event_type)
rc, sock->host.len, sock->host.s, sock->port);

if (reactor_del_reader(sock->handle->sock, idx,
IO_WATCH_READ) != 0) {
IO_FD_CLOSING) != 0) {
LM_ERR("del failed for sock %d\n", sock->handle->sock);
return 0;
}
Expand Down Expand Up @@ -478,16 +474,11 @@ void handle_reconnects(void)
if (sock->handle) {
if (sock->handle->connected && sock->handle->sock != ESL_SOCK_INVALID) {
if (!SHOULD_KEEP_EVS(sock)) {
/*
* TODO: implement clean up for unused ESL connections here.
* Currently not immediately possible because:
* - reactor_del_reader() can only be called under handle_io()
* - esl_disconnect() closes the fd, so handle_io() is skipped
*/
destroy_fs_evs(sock, -1);
continue;
}

LM_DBG("fake disconnect on %s:%d\n", sock->host.s, sock->port);
LM_DBG("outdated reconnect on %s:%d, skipping\n", sock->host.s, sock->port);
list_del(&sock->reconnect_list);
INIT_LIST_HEAD(&sock->reconnect_list);
continue;
Expand Down

0 comments on commit 6d0ac4f

Please sign in to comment.