1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

listen: network filter: provide a struct with client info to the FILTER cb

For backwards compatibility, keep the cast fd on in and pass an info struct
to the callback by overloading user_data.
This commit is contained in:
Andy Green 2020-08-20 07:15:17 +01:00
parent 1b1c3099f0
commit b17243bb5d
2 changed files with 43 additions and 23 deletions

View file

@ -80,6 +80,17 @@ struct lws_acme_cert_aging_args {
const char *element_overrides[LWS_TLS_TOTAL_COUNT]; /* NULL = use pvo */
};
/*
* With LWS_CALLBACK_FILTER_NETWORK_CONNECTION callback, user_data pointer
* points to one of these
*/
struct lws_filter_network_conn_args {
struct sockaddr_storage cli_addr;
socklen_t clilen;
lws_sockfd_type accept_fd;
};
/*
* NOTE: These public enums are part of the abi. If you want to add one,
* add it at where specified so existing users are unaffected.
@ -581,9 +592,17 @@ enum lws_callback_reasons {
/**< called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. in contains the connection
* socket's descriptor. Since the client connection information is
* not available yet, wsi still pointing to the main server socket.
* or not, based on the client IP.
*
* user_data in the callback points to a
* struct lws_filter_network_conn_args that is prepared with the
* sockfd, and the peer's address information.
*
* in contains the connection socket's descriptor.
*
* Since the client connection information is not available yet,
* wsi still pointing to the main server socket.
*
* Return non-zero to terminate the connection before sending or
* receiving anything. Because this happens immediately after the
* network connection from the client, there's no websocket protocol

View file

@ -29,12 +29,10 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
struct lws_pollfd *pollfd)
{
struct lws_context *context = wsi->a.context;
lws_sockfd_type accept_fd;
struct lws_filter_network_conn_args filt;
lws_sock_file_fd_type fd;
struct sockaddr_storage cli_addr;
socklen_t clilen;
memset(&cli_addr, 0, sizeof(cli_addr));
memset(&filt, 0, sizeof(filt));
/* if our vhost is going down, ignore it */
@ -74,7 +72,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
#endif
/* listen socket got an unencrypted connection... */
clilen = sizeof(cli_addr);
filt.clilen = sizeof(filt.cli_addr);
/*
* We cannot identify the peer who is in the listen
@ -83,38 +81,41 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
* block the connect queue for other legit peers.
*/
accept_fd = accept((int)pollfd->fd,
(struct sockaddr *)&cli_addr, &clilen);
if (accept_fd == LWS_SOCK_INVALID) {
filt.accept_fd = accept((int)pollfd->fd,
(struct sockaddr *)&filt.cli_addr,
&filt.clilen);
if (filt.accept_fd == LWS_SOCK_INVALID) {
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK) {
break;
}
lwsl_err("accept: errno %d\n", LWS_ERRNO);
return LWS_HPI_RET_HANDLED;
}
if (context->being_destroyed) {
compatible_close(accept_fd);
compatible_close(filt.accept_fd);
return LWS_HPI_RET_PLEASE_CLOSE_ME;
}
lws_plat_set_socket_options(wsi->a.vhost, accept_fd, 0);
lws_plat_set_socket_options(wsi->a.vhost, filt.accept_fd, 0);
#if defined(LWS_WITH_IPV6)
lwsl_debug("accepted new conn port %u on fd=%d\n",
((cli_addr.ss_family == AF_INET6) ?
ntohs(((struct sockaddr_in6 *) &cli_addr)->sin6_port) :
ntohs(((struct sockaddr_in *) &cli_addr)->sin_port)),
accept_fd);
((filt.cli_addr.ss_family == AF_INET6) ?
ntohs(((struct sockaddr_in6 *) &filt.cli_addr)->sin6_port) :
ntohs(((struct sockaddr_in *) &filt.cli_addr)->sin_port)),
filt.accept_fd);
#else
{
struct sockaddr_in sain;
memcpy(&sain, &cli_addr, sizeof(sain));
memcpy(&sain, &filt.cli_addr, sizeof(sain));
lwsl_debug("accepted new conn port %u on fd=%d\n",
ntohs(sain.sin_port),
accept_fd);
filt.accept_fd);
}
#endif
@ -126,10 +127,10 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
*/
if ((wsi->a.vhost->protocols[0].callback)(wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
NULL,
(void *)(lws_intptr_t)accept_fd, 0)) {
(void *)&filt,
(void *)(lws_intptr_t)filt.accept_fd, 0)) {
lwsl_debug("Callback denied net connection\n");
compatible_close(accept_fd);
compatible_close(filt.accept_fd);
return LWS_HPI_RET_HANDLED;
}
@ -142,7 +143,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
#endif
opts &= ~LWS_ADOPT_ALLOW_SSL;
fd.sockfd = accept_fd;
fd.sockfd = filt.accept_fd;
cwsi = lws_adopt_descriptor_vhost(wsi->a.vhost, opts, fd,
wsi->a.vhost->listen_accept_protocol, NULL);
if (!cwsi) {