From db9cb051c4ee05c07ab32dfed5bae8b7dc0916bd Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Mon, 6 Oct 2025 21:03:59 +0200 Subject: Allow custom backlog connections libweb calls listen(2) when setting up the HTTP server, and its backlog argument was hardcoded to 10. While probably not an issue for some applications, it can be too limiting for some others. Therefore, it is desirable to allow library users to set up their own limits. Otherwise, 10 is still chosen as a sane default. --- doc/man7/libweb_handler.7 | 17 ++++++++++++++++- handler.c | 2 +- include/libweb/handler.h | 1 + include/libweb/server.h | 3 ++- server.c | 16 ++++++++++++---- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/doc/man7/libweb_handler.7 b/doc/man7/libweb_handler.7 index 4b0c454..5398675 100644 --- a/doc/man7/libweb_handler.7 +++ b/doc/man7/libweb_handler.7 @@ -77,6 +77,7 @@ struct handler_cfg void *\fIuser\fP; size_t \fImax_headers\fP; struct http_cfg_post \fIpost\fP; + unsigned \fIbacklog\fP; }; .EE .in @@ -96,6 +97,19 @@ object. See .IR libweb_http (7) for further reference about these members. +On the other hand, +.I backlog +is passed directly to the call to +.IR listen (2) +done internally by +.IR libweb , +and must not exceed +.IR INT_MAX . +If +.I backlog +equals zero, +it shall default to 10. + However, a .I "struct handler" object as returned by @@ -235,7 +249,8 @@ end: .BR handler_free (3), .BR handler_listen (3), .BR handler_loop (3), -.BR libweb_http (7). +.BR libweb_http (7), +.BR listen (2). .SH COPYRIGHT Copyright (C) 2023-2024 libweb contributors diff --git a/handler.c b/handler.c index 98e6118..63ef726 100644 --- a/handler.c +++ b/handler.c @@ -220,7 +220,7 @@ int handler_notify_close(struct handler *const h) int handler_listen(struct handler *const h, const unsigned short port, unsigned short *const outport) { - if (!(h->server = server_init(port, outport))) + if (!(h->server = server_init(port, outport, h->cfg.backlog))) { fprintf(stderr, "%s: server_init failed\n", __func__); return -1; diff --git a/include/libweb/handler.h b/include/libweb/handler.h index 7e0b601..97fdca0 100644 --- a/include/libweb/handler.h +++ b/include/libweb/handler.h @@ -15,6 +15,7 @@ struct handler_cfg void *user; size_t max_headers; struct http_cfg_post post; + unsigned backlog; }; struct handler *handler_alloc(const struct handler_cfg *cfg); diff --git a/include/libweb/server.h b/include/libweb/server.h index 08e0f34..42af6e6 100644 --- a/include/libweb/server.h +++ b/include/libweb/server.h @@ -4,7 +4,8 @@ #include #include -struct server *server_init(unsigned short port, unsigned short *outport); +struct server *server_init(unsigned short port, unsigned short *outport, + unsigned backlog); struct server_client *server_poll(struct server *s, bool *io, bool *exit); int server_read(void *buf, size_t n, struct server_client *c); int server_write(const void *buf, size_t n, struct server_client *c); diff --git a/server.c b/server.c index a77d7d2..3f7eb04 100644 --- a/server.c +++ b/server.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -299,10 +300,13 @@ end: } struct server *server_init(const unsigned short port, - unsigned short *const outport) + unsigned short *const outport, const unsigned ubacklog) { struct server *const s = malloc(sizeof *s); int fds[2] = {-1, -1}, fd = -1; + /* Ensure default value if not set. */ + enum {QUEUE_LEN = 10}; + const unsigned backlog = ubacklog ? ubacklog : QUEUE_LEN; if (!s) { @@ -326,14 +330,18 @@ struct server *server_init(const unsigned short port, .sin_port = htons(port) }; - enum {QUEUE_LEN = 10}; - if (bind(fd, (const struct sockaddr *)&addr, sizeof addr)) { fprintf(stderr, "%s: bind(2): %s\n", __func__, strerror(errno)); goto failure; } - else if (listen(fd, QUEUE_LEN)) + else if (backlog > INT_MAX) + { + fprintf(stderr, "%s: backlog (%u) exceeds maximum (%d)\n", + __func__, backlog, INT_MAX); + goto failure; + } + else if (listen(fd, backlog)) { fprintf(stderr, "%s: listen(2): %s\n", __func__, strerror(errno)); goto failure; -- cgit v1.2.3