]> git.meshlink.io Git - meshlink/commitdiff
Avoid ports that are in use by not all address families.
authorGuus Sliepen <guus@meshlink.io>
Fri, 28 Feb 2020 19:09:11 +0000 (20:09 +0100)
committerGuus Sliepen <guus@meshlink.io>
Fri, 28 Feb 2020 19:09:11 +0000 (20:09 +0100)
It could happen that a port is bound by another application, but only
for some of the supported address families (ie, only IPv4 but not IPv6).
We don't want MeshLink to then bind to the other address familie(s), but
rather have it try another port altogether.

src/meshlink.c

index 4e32761fa1b30fcbf5713fa46db005383a517453..c6b14b8f043c1b0bdb4c38b6db8aa687651659b7 100644 (file)
@@ -540,6 +540,8 @@ static bool try_bind(int port) {
        bool success = false;
 
        for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
+               /* Try to bind to TCP. */
+
                int tcp_fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
 
                if(tcp_fd == -1) {
@@ -550,24 +552,33 @@ static bool try_bind(int port) {
                closesocket(tcp_fd);
 
                if(result) {
-                       continue;
+                       if(errno == EADDRINUSE) {
+                               /* If this port is in use for any address family, avoid it. */
+                               success = false;
+                               break;
+                       } else {
+                               continue;
+                       }
                }
 
+               /* If TCP worked, then we require that UDP works as well. */
+
                int udp_fd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP);
 
                if(udp_fd == -1) {
-                       continue;
+                       success = false;
+                       break;
                }
 
                result = bind(udp_fd, aip->ai_addr, aip->ai_addrlen);
                closesocket(udp_fd);
 
                if(result) {
-                       continue;
-               } else {
-                       success = true;
+                       success = false;
                        break;
                }
+
+               success = true;
        }
 
        freeaddrinfo(ai);