aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2025-10-06 21:03:59 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2025-10-06 21:03:59 +0200
commitdb9cb051c4ee05c07ab32dfed5bae8b7dc0916bd (patch)
tree44e1efae86af612923ec5486c00eb2c56019c865
parent4918cf87d3cf5d3dd8425fe10d97a06282472df6 (diff)
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.
-rw-r--r--doc/man7/libweb_handler.717
-rw-r--r--handler.c2
-rw-r--r--include/libweb/handler.h1
-rw-r--r--include/libweb/server.h3
-rw-r--r--server.c16
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 <stdbool.h>
#include <stddef.h>
-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 <poll.h>
#include <unistd.h>
#include <errno.h>
+#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
@@ -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;