commit 42275f8dca15fe53ddad85dc9c0c660f5af9004d
parent f8246f9a12e36930914c84ff0918ca94f707f0c9
Author: Robin Bron <robin.bron@yourhosting.nl>
Date: Sun, 8 Mar 2026 17:01:06 +0100
Prevent race conditions in port assignments
Diffstat:
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,7 +7,7 @@ SRC:=
# UNAME_SYSTEM=$(call lc,$(shell uname -s))
BIN?=udphole
-VERSION?=1.3.10
+VERSION?=1.3.11
CC:=gcc
CPP:=g++
diff --git a/src/domain/daemon/session.c b/src/domain/daemon/session.c
@@ -82,27 +82,32 @@ static socket_t *find_socket(session_t *s, const char *socket_id) {
return NULL;
}
+// port_cur = last-assigned-port
+int port_cur = 0;
static int alloc_port(void) {
resp_object *udphole = get_udphole_cfg();
if (!udphole) return 0;
const char *ports_str = resp_map_get_string(udphole, "ports");
- int port_low = 7000, port_high = 7999, port_cur = 7000;
+ int port_low = 7000, port_high = 7999;
if (ports_str) sscanf(ports_str, "%d-%d", &port_low, &port_high);
- const char *port_cur_str = resp_map_get_string(udphole, "_port_cur");
- if (port_cur_str) port_cur = atoi(port_cur_str);
- for (int i = 0; i < port_high - port_low; i++) {
- int port = port_cur + i;
- if (port > port_high) port = port_low;
- port_cur = port + 1;
+ // Limit port tries
+ for (int i = 0; i < (port_high - port_low); i++) {
+
+ // Select next port
+ port_cur++;
+ if (port_cur < port_low ) port_cur = port_low;
if (port_cur > port_high) port_cur = port_low;
+ int port = port_cur;
+ // Build sockaddr
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
+ // Check if the port is free
int udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_fd < 0) continue;
int ok = (bind(udp_fd, (struct sockaddr *)&addr, sizeof(addr)) == 0);
@@ -111,6 +116,8 @@ static int alloc_port(void) {
return port;
}
+
+ // Nothing found
return 0;
}