From e306efba0aa513ae498b84b7f383b05365022092 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 28 Feb 2020 20:09:11 +0100 Subject: [PATCH] Avoid ports that are in use by not all address families. 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 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/meshlink.c b/src/meshlink.c index 4e32761f..c6b14b8f 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -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); -- 2.39.2