From 1963c9aa7f9e07359daa4c0e3a35375df04660df Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 15 Oct 2015 07:39:33 +0800 Subject: [PATCH] improve callback close checking Signed-off-by: Andy Green --- lib/client-handshake.c | 3 ++- lib/libwebsockets.c | 1 + lib/pollfd.c | 52 +++++++++++++++++++++++++++++--------------------- lib/server.c | 8 ++++++-- lib/ssl.c | 3 ++- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/client-handshake.c b/lib/client-handshake.c index e5c1357..7293a41 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -152,7 +152,8 @@ struct libwebsocket *libwebsocket_client_connect_2( wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT; lws_libev_accept(context, wsi, wsi->sock); - insert_wsi_socket_into_fds(context, wsi); + if (insert_wsi_socket_into_fds(context, wsi)) + goto oom4; libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index cb6f389..f8e3ac6 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -236,6 +236,7 @@ just_kill_connection: lws_ssl_remove_wsi_from_buffered_list(context, wsi); + // checking return redundant since we anyway close remove_wsi_socket_from_fds(context, wsi); wsi->state = WSI_STATE_DEAD_SOCKET; diff --git a/lib/pollfd.c b/lib/pollfd.c index d4edb7e..a70f8e6 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -46,9 +46,9 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context, lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n", wsi, wsi->sock, context->fds_count); - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0)) + return -1; insert_wsi(context, wsi); wsi->position_in_fds_table = context->fds_count; @@ -58,13 +58,13 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context, lws_plat_insert_socket_into_fds(context, wsi); /* external POLL support via protocol 0 */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_ADD_POLL_FD, - wsi->user_space, (void *) &pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0)) + return -1; - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *)&pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0)) + return -1; return 0; } @@ -91,9 +91,9 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__, wsi, wsi->sock, wsi->position_in_fds_table); - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *)&pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *)&pa, 0)) + return -1; m = wsi->position_in_fds_table; /* replace the contents for this */ @@ -116,13 +116,16 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, /* remove also from external POLL support via protocol 0 */ if (wsi->sock) { - context->protocols[0].callback(context, wsi, + if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_DEL_POLL_FD, wsi->user_space, - (void *) &pa, 0); + (void *) &pa, 0)) + return -1; } - context->protocols[0].callback(context, wsi, + if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 0); + wsi->user_space, (void *) &pa, 0)) + return -1; + return 0; } @@ -145,15 +148,17 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) pfd = &context->fds[wsi->position_in_fds_table]; pa.fd = wsi->sock; - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0)) + return -1; pa.prev_events = pfd->events; pa.events = pfd->events = (pfd->events & ~_and) | _or; - context->protocols[0].callback(context, wsi, + if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_CHANGE_MODE_POLL_FD, - wsi->user_space, (void *) &pa, 0); + wsi->user_space, (void *) &pa, 0)) + return -1; /* * if we changed something in this pollfd... @@ -173,13 +178,16 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) if (sampled_tid) { tid = context->protocols[0].callback(context, NULL, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); + if (tid == -1) + return -1; if (tid != sampled_tid) libwebsocket_cancel_service(context); } } - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0); + if (context->protocols[0].callback(context, wsi, + LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0)) + return -1; return 0; } diff --git a/lib/server.c b/lib/server.c index 0e86867..fc49141 100644 --- a/lib/server.c +++ b/lib/server.c @@ -119,7 +119,10 @@ int lws_context_init_server(struct lws_context_creation_info *info, wsi->sock = sockfd; wsi->mode = LWS_CONNMODE_SERVER_LISTENER; - insert_wsi_socket_into_fds(context, wsi); + if (insert_wsi_socket_into_fds(context, wsi)) { + compatible_close(sockfd); + return 1; + } context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO; context->listen_service_count = 0; @@ -825,7 +828,8 @@ try_pollout: lwsl_debug("accepted new conn port %u on fd=%d\n", ntohs(cli_addr.sin_port), accept_fd); - insert_wsi_socket_into_fds(context, new_wsi); + if (insert_wsi_socket_into_fds(context, new_wsi)) + goto fail; } break; diff --git a/lib/ssl.c b/lib/ssl.c index 6f994d7..4fa5c49 100644 --- a/lib/ssl.c +++ b/lib/ssl.c @@ -579,7 +579,8 @@ lws_server_socket_service_ssl(struct libwebsocket_context *context, *pwsi = new_wsi; wsi = *pwsi; wsi->mode = LWS_CONNMODE_SSL_ACK_PENDING; - insert_wsi_socket_into_fds(context, wsi); + if (insert_wsi_socket_into_fds(context, wsi)) + goto fail; libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT, AWAITING_TIMEOUT); -- 2.7.4