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:
parent
62c328244c
commit
28f4aae555
2 changed files with 43 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue