udphole

Basic UDP wormhole proxy
git clone git://git.finwo.net/app/udphole
Log | Files | Refs | README | LICENSE

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:
MMakefile | 2+-
Msrc/domain/daemon/session.c | 21++++++++++++++-------
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; }