diff --git a/lib/core-net/adopt.c b/lib/core-net/adopt.c index a9d2d6d39..4b632ba1d 100644 --- a/lib/core-net/adopt.c +++ b/lib/core-net/adopt.c @@ -110,8 +110,8 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, struct lws *parent) { struct lws_context *context = vh->context; - struct lws *new_wsi; struct lws_context_per_thread *pt; + struct lws *new_wsi; int n; #if defined(LWS_WITH_PEER_LIMITS) @@ -133,7 +133,7 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, #endif /* - * Notice that in SMP case, the wsi may being being created on an + * Notice that in SMP case, the wsi may be being created on an * entirely different pt / tsi for load balancing. In that case as * we initialize it, it may become "live" concurrently unexpectedly... */ @@ -160,6 +160,21 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, parent->child_list = new_wsi; } + /* enforce that every fd is nonblocking */ + + if (type & LWS_ADOPT_SOCKET) { + if (lws_plat_set_nonblocking(fd.sockfd)) { + lwsl_err("%s: unable to set sockfd nonblocking\n", + __func__); + goto bail; + } + } else + if (lws_plat_set_nonblocking(fd.filefd)) { + lwsl_err("%s: unable to set filefd nonblocking\n", + __func__); + goto bail; + } + new_wsi->desc = fd; if (vh_prot_name) { diff --git a/lib/core-net/private.h b/lib/core-net/private.h index c67691379..887bbbd8e 100644 --- a/lib/core-net/private.h +++ b/lib/core-net/private.h @@ -728,6 +728,9 @@ user_callback_handle_rxflow(lws_callback_function, struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); +LWS_EXTERN int +lws_plat_set_nonblocking(int fd); + LWS_EXTERN int lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd, int unix_skt); diff --git a/lib/plat/esp32/esp32-sockets.c b/lib/plat/esp32/esp32-sockets.c index 060d72508..de7611a31 100644 --- a/lib/plat/esp32/esp32-sockets.c +++ b/lib/plat/esp32/esp32-sockets.c @@ -72,6 +72,11 @@ lws_plat_check_connection_error(struct lws *wsi) return 0; } +int +lws_plat_set_nonblocking(int fd) +{ + return fcntl(fd, F_SETFL, O_NONBLOCK) < 0; +} int lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) @@ -126,11 +131,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, optlen) < 0) return 1; - /* We are nonblocking... */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - return 1; - - return 0; + return lws_plat_set_nonblocking(fd); } /* cast a struct sockaddr_in6 * into addr for ipv6 */ diff --git a/lib/plat/optee/lws-plat-optee.c b/lib/plat/optee/lws-plat-optee.c index 7103adc16..58e83051c 100644 --- a/lib/plat/optee/lws-plat-optee.c +++ b/lib/plat/optee/lws-plat-optee.c @@ -101,6 +101,11 @@ void lwsl_emit_optee(int level, const char *line) EMSG("%c%s%s%s%c[0m", 27, colours[m], buf, linecp, 27); } +int +lws_plat_set_nonblocking(int fd) +{ + return 0; +} void lws_plat_drop_app_privileges(const struct lws_context_creation_info *info) diff --git a/lib/plat/unix/unix-sockets.c b/lib/plat/unix/unix-sockets.c index 693efd28e..2b5528677 100644 --- a/lib/plat/unix/unix-sockets.c +++ b/lib/plat/unix/unix-sockets.c @@ -66,6 +66,11 @@ lws_send_pipe_choked(struct lws *wsi) return 0; } +int +lws_plat_set_nonblocking(int fd) +{ + return fcntl(fd, F_SETFL, O_NONBLOCK) < 0; +} int lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) @@ -156,11 +161,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) return 1; #endif - /* We are nonblocking... */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - return 1; - - return 0; + return lws_plat_set_nonblocking(fd); } diff --git a/lib/plat/windows/windows-sockets.c b/lib/plat/windows/windows-sockets.c index 3772cfb7e..643e579a1 100644 --- a/lib/plat/windows/windows-sockets.c +++ b/lib/plat/windows/windows-sockets.c @@ -42,13 +42,20 @@ lws_poll_listen_fd(struct lws_pollfd *fd) return select(((int)fd->fd) + 1, &readfds, NULL, NULL, &tv); } +int +lws_plat_set_nonblocking(int fd) +{ + u_long optl = 1; + + return !!ioctlsocket(fd, FIONBIO, &optl); +} + int lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd, int unix_skt) { int optval = 1; int optlen = sizeof(optval); - u_long optl = 1; DWORD dwBytesRet; struct tcp_keepalive alive; int protonbr; @@ -87,10 +94,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd, setsockopt(fd, protonbr, TCP_NODELAY, (const char *)&optval, optlen); - /* We are nonblocking... */ - ioctlsocket(fd, FIONBIO, &optl); - - return 0; + return lws_plat_set_nonblocking(fd); }