From b18d98708cef03dc3871a4db0a6c774a972ee16b Mon Sep 17 00:00:00 2001 From: markmaker Date: Mon, 22 Jan 2024 07:31:04 +0100 Subject: [PATCH] Feature / Adopt externally accepted sockets into libusockets (#214) * Adopt externally accepted sockets into libusockets. * Oops, typo. --------- Co-authored-by: markus --- src/crypto/openssl.c | 5 +++++ src/internal/internal.h | 3 +++ src/libusockets.h | 4 ++++ src/loop.c | 46 ++++++++++++++++++++++++++--------------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/crypto/openssl.c b/src/crypto/openssl.c index 9bc81a8..4473679 100644 --- a/src/crypto/openssl.c +++ b/src/crypto/openssl.c @@ -694,6 +694,11 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(struct us_ return us_socket_context_listen_unix(0, &context->sc, path, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size); } +struct us_internal_ssl_socket_t *us_internal_ssl_adopt_accepted_socket(struct us_internal_ssl_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR accepted_fd, + unsigned int socket_ext_size, char *addr_ip, int addr_ip_length) { + return (struct us_internal_ssl_socket_t *) us_adopt_accepted_socket(0, &context->sc, accepted_fd, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size, addr_ip, addr_ip_length); +} + struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect(struct us_internal_ssl_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size) { return (struct us_internal_ssl_socket_t *) us_socket_context_connect(0, &context->sc, host, port, source_host, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size); } diff --git a/src/internal/internal.h b/src/internal/internal.h index f9e5ed5..be002d2 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -194,6 +194,9 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen(struct us_inter struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(struct us_internal_ssl_socket_context_t *context, const char *path, int options, int socket_ext_size); +struct us_internal_ssl_socket_t *us_internal_ssl_adopt_accepted_socket(struct us_internal_ssl_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR accepted_fd, + unsigned int socket_ext_size, char *addr_ip, int addr_ip_length); + struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect(struct us_internal_ssl_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size); diff --git a/src/libusockets.h b/src/libusockets.h index c9bd2c2..d16624a 100644 --- a/src/libusockets.h +++ b/src/libusockets.h @@ -190,6 +190,10 @@ struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_sock /* listen_socket.c/.h */ void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls); +/* Adopt a socket which was accepted either internally, or from another accept() outside libusockets */ +struct us_socket_t *us_adopt_accepted_socket(int ssl, struct us_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR client_fd, + unsigned int socket_ext_size, char *addr_ip, int addr_ip_length); + /* Land in on_open or on_connection_error or return null or return socket */ struct us_socket_t *us_socket_context_connect(int ssl, struct us_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size); diff --git a/src/loop.c b/src/loop.c index 2f225d9..886f124 100644 --- a/src/loop.c +++ b/src/loop.c @@ -194,6 +194,32 @@ void us_internal_loop_post(struct us_loop_t *loop) { loop->data.post_cb(loop); } +struct us_socket_t *us_adopt_accepted_socket(int ssl, struct us_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR accepted_fd, + unsigned int socket_ext_size, char *addr_ip, int addr_ip_length) { + if (ssl) { + return (struct us_socket_t *)us_internal_ssl_adopt_accepted_socket((struct us_internal_ssl_socket_context_t *)context, accepted_fd, + socket_ext_size, addr_ip, addr_ip_length); + } + struct us_poll_t *accepted_p = us_create_poll(context->loop, 0, sizeof(struct us_socket_t) - sizeof(struct us_poll_t) + socket_ext_size); + us_poll_init(accepted_p, accepted_fd, POLL_TYPE_SOCKET); + us_poll_start(accepted_p, context->loop, LIBUS_SOCKET_READABLE); + + struct us_socket_t *s = (struct us_socket_t *) accepted_p; + + s->context = context; + s->timeout = 255; + s->long_timeout = 255; + s->low_prio_state = 0; + + /* We always use nodelay */ + bsd_socket_nodelay(accepted_fd, 1); + + us_internal_socket_context_link_socket(context, s); + + context->on_open(s, 0, addr_ip, addr_ip_length); + return s; +} + void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int events) { switch (us_internal_poll_type(p)) { case POLL_TYPE_CALLBACK: { @@ -247,23 +273,9 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int events) /* Todo: stop timer if any */ do { - struct us_poll_t *accepted_p = us_create_poll(us_socket_context(0, &listen_socket->s)->loop, 0, sizeof(struct us_socket_t) - sizeof(struct us_poll_t) + listen_socket->socket_ext_size); - us_poll_init(accepted_p, client_fd, POLL_TYPE_SOCKET); - us_poll_start(accepted_p, listen_socket->s.context->loop, LIBUS_SOCKET_READABLE); - - struct us_socket_t *s = (struct us_socket_t *) accepted_p; - - s->context = listen_socket->s.context; - s->timeout = 255; - s->long_timeout = 255; - s->low_prio_state = 0; - - /* We always use nodelay */ - bsd_socket_nodelay(client_fd, 1); - - us_internal_socket_context_link_socket(listen_socket->s.context, s); - - listen_socket->s.context->on_open(s, 0, bsd_addr_get_ip(&addr), bsd_addr_get_ip_length(&addr)); + /* adopt the newly accepted socket */ + us_adopt_accepted_socket(0, us_socket_context(0, &listen_socket->s), + client_fd, listen_socket->socket_ext_size, bsd_addr_get_ip(&addr), bsd_addr_get_ip_length(&addr)); /* Exit accept loop if listen socket was closed in on_open handler */ if (us_socket_is_closed(0, &listen_socket->s)) {