]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Use the first working outgoing socket during meshlink_join().
[meshlink] / src / meshlink.c
index fbacfd4a4131a813d8f2119a11472303a00f4886..def3e6efc9557a7d83d7b4d587b223eb1e256ba1 100644 (file)
@@ -537,26 +537,52 @@ static bool try_bind(int port) {
                return false;
        }
 
-       //while(ai) {
+       bool success = false;
+
        for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
-               int fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
+               /* Try to bind to TCP. */
 
-               if(!fd) {
-                       freeaddrinfo(ai);
-                       return false;
+               int tcp_fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
+
+               if(tcp_fd == -1) {
+                       continue;
                }
 
-               int result = bind(fd, aip->ai_addr, aip->ai_addrlen);
-               closesocket(fd);
+               int result = bind(tcp_fd, aip->ai_addr, aip->ai_addrlen);
+               closesocket(tcp_fd);
 
                if(result) {
-                       freeaddrinfo(ai);
-                       return false;
+                       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) {
+                       success = false;
+                       break;
                }
+
+               result = bind(udp_fd, aip->ai_addr, aip->ai_addrlen);
+               closesocket(udp_fd);
+
+               if(result) {
+                       success = false;
+                       break;
+               }
+
+               success = true;
        }
 
        freeaddrinfo(ai);
-       return true;
+       return success;
 }
 
 static int check_port(meshlink_handle_t *mesh) {
@@ -2743,6 +2769,8 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) {
                                        state.sock = -1;
                                        continue;
                                }
+
+                               break;
                        }
 
                        freeaddrinfo(ai);