diff --git a/example/multi_process_server_reuseport.c b/example/multi_process_server_reuseport.c index 0018d1a..785495c 100644 --- a/example/multi_process_server_reuseport.c +++ b/example/multi_process_server_reuseport.c @@ -77,6 +77,8 @@ static void start_server(const char *addr, const char *docroot) if (!srv) return; + srv->reuse_port(srv, true); + if (srv->listen(srv, addr, false) < 0) return; diff --git a/src/uhttpd.c b/src/uhttpd.c index 66bed63..7460da1 100644 --- a/src/uhttpd.c +++ b/src/uhttpd.c @@ -344,6 +344,13 @@ static void uh_set_loop(struct uh_server *srv, struct ev_loop *loop) srvi->loop = loop; } +static void uh_reuse_port(struct uh_server *srv, bool val) +{ + struct uh_server_internal *srvi = (struct uh_server_internal *)srv; + + srvi->reuse_port = val; +} + static int parse_address(const char *addr, char **host, char **port) { static char buf[256]; @@ -420,11 +427,14 @@ static int uh_server_listen(struct uh_server *srv, const char *addr, bool ssl) /* required to get parallel v4 + v6 working */ if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(int)) < 0) { - log_err("setsockopt: %s\n", strerror(errno)); + log_err("setsockopt: IPV6_V6ONLY: %s\n", strerror(errno)); goto err; } - setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int)); + if (srvi->reuse_port && setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int))) { + log_err("setsockopt: SO_REUSEPORT: %s\n", strerror(errno)); + goto err; + } if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) { log_err("bind: %s\n", strerror(errno)); @@ -492,6 +502,7 @@ void uh_server_init(struct uh_server *srv, struct ev_loop *loop) srv->set_loop = uh_set_loop; srv->free = uh_server_free; + srv->reuse_port = uh_reuse_port; srv->listen = uh_server_listen; #ifdef SSL_SUPPORT diff --git a/src/uhttpd.h b/src/uhttpd.h index 66b85f2..edbc999 100644 --- a/src/uhttpd.h +++ b/src/uhttpd.h @@ -155,6 +155,7 @@ struct uh_server { /* Replace the existing loop. Can only be called before calling the listen */ void (*set_loop)(struct uh_server *srv, struct ev_loop *loop); void (*free)(struct uh_server *srv); + void (*reuse_port)(struct uh_server *srv, bool val); /* ** listen an address, multiple call allowed ** returns the number of successful listen diff --git a/src/uhttpd_internal.h b/src/uhttpd_internal.h index 43b22b5..9e9a523 100644 --- a/src/uhttpd_internal.h +++ b/src/uhttpd_internal.h @@ -66,6 +66,7 @@ struct uh_server_internal { struct uh_server com; char *docroot; char *index_page; + bool reuse_port; bool https_redirect; struct ev_loop *loop; void (*conn_closed_cb)(struct uh_connection *conn);