From 977905f2f828e5f542fb6d4a00281b427146cac7 Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Sun, 2 Jul 2017 12:04:05 -0500 Subject: [PATCH] Choose client ports in a well-known range Instead of letting the kernel assign us a port number, request a specific port number and increment until one is available. This makes writing firewall rules easier, when a known number of clients will be in use. --- lib/ZOpenPort.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/ZOpenPort.c b/lib/ZOpenPort.c index b15ee286..f4680a7e 100644 --- a/lib/ZOpenPort.c +++ b/lib/ZOpenPort.c @@ -23,6 +23,7 @@ ZOpenPort(u_short *port) struct sockaddr_in bindin; unsigned int len; int val = 1; + int ret; (void) ZClosePort(); @@ -38,17 +39,20 @@ ZOpenPort(u_short *port) if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0) return errno; } else { - bindin.sin_port = 0; + bindin.sin_port = htons(60000); } bindin.sin_addr.s_addr = INADDR_ANY; - if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) { - if (errno == EADDRINUSE && port && *port) - return ZERR_PORTINUSE; - else - return errno; - } + do { + ret = bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)); + if (ret < 0 && !(port && *port)) + bindin.sin_port++; + } while (ret < 0 && errno == EADDRINUSE && !(port && *port)); + if (ret < 0 && errno == EADDRINUSE) + return ZERR_PORTINUSE; + else if (ret < 0) + return errno; if (port && *port) { /* turn SO_REUSEADDR back off so no one else can steal it */ @@ -57,12 +61,6 @@ ZOpenPort(u_short *port) return errno; } - if (!bindin.sin_port) { - len = sizeof(bindin); - if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len)) - return errno; - } - __Zephyr_port = bindin.sin_port; __Zephyr_open = 1;