Have try_bind() reuse the setup_*_listen_socket() functions.
authorGuus Sliepen <guus@meshlink.io>
Sun, 15 Mar 2020 15:24:34 +0000 (16:24 +0100)
committerGuus Sliepen <guus@meshlink.io>
Sun, 15 Mar 2020 15:24:34 +0000 (16:24 +0100)
This ensures try_bind() configures sockets exactly the same as the actual
listening sockets.

src/meshlink.c
src/net.h
src/net_setup.c

index ab3ab7f..9f3b6ec 100644 (file)
@@ -577,7 +577,7 @@ static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
        return hostport;
 }
 
-static bool try_bind(int port) {
+static bool try_bind(meshlink_handle_t *mesh, int port) {
        struct addrinfo *ai = NULL;
        struct addrinfo hint = {
                .ai_flags = AI_PASSIVE,
@@ -598,16 +598,9 @@ static bool try_bind(int port) {
        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);
+               int tcp_fd = setup_tcp_listen_socket(mesh, aip);
 
                if(tcp_fd == -1) {
-                       continue;
-               }
-
-               int result = bind(tcp_fd, aip->ai_addr, aip->ai_addrlen);
-               closesocket(tcp_fd);
-
-               if(result) {
                        if(errno == EADDRINUSE) {
                                /* If this port is in use for any address family, avoid it. */
                                success = false;
@@ -619,21 +612,16 @@ static bool try_bind(int port) {
 
                /* If TCP worked, then we require that UDP works as well. */
 
-               int udp_fd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP);
+               int udp_fd = setup_udp_listen_socket(mesh, aip);
 
                if(udp_fd == -1) {
+                       closesocket(tcp_fd);
                        success = false;
                        break;
                }
 
-               result = bind(udp_fd, aip->ai_addr, aip->ai_addrlen);
+               closesocket(tcp_fd);
                closesocket(udp_fd);
-
-               if(result) {
-                       success = false;
-                       break;
-               }
-
                success = true;
        }
 
@@ -645,7 +633,7 @@ int check_port(meshlink_handle_t *mesh) {
        for(int i = 0; i < 1000; i++) {
                int port = 0x1000 + prng(mesh, 0x8000);
 
-               if(try_bind(port)) {
+               if(try_bind(mesh, port)) {
                        free(mesh->myport);
                        xasprintf(&mesh->myport, "%d", port);
                        return port;
@@ -2554,7 +2542,7 @@ bool meshlink_set_port(meshlink_handle_t *mesh, int port) {
                return true;
        }
 
-       if(!try_bind(port)) {
+       if(!try_bind(mesh, port)) {
                meshlink_errno = MESHLINK_ENETWORK;
                return false;
        }
index cdb0cca..cae63bf 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -84,6 +84,8 @@ extern void handle_incoming_vpn_data(struct event_loop_t *loop, void *, int);
 extern void finish_connecting(struct meshlink_handle *mesh, struct connection_t *);
 extern void do_outgoing_connection(struct meshlink_handle *mesh, struct outgoing_t *);
 extern void handle_new_meta_connection(struct event_loop_t *loop, void *, int);
+extern int setup_tcp_listen_socket(struct meshlink_handle *mesh, const struct addrinfo *aip) __attribute__((__warn_unused_result__));
+extern int setup_udp_listen_socket(struct meshlink_handle *mesh, const struct addrinfo *aip) __attribute__((__warn_unused_result__));
 extern bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len);
 extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) __attribute__((__warn_unused_result__));
 extern void send_packet(struct meshlink_handle *mesh, struct node_t *, struct vpn_packet_t *);
index d0e4500..238ae2d 100644 (file)
@@ -301,7 +301,7 @@ static bool load_node(meshlink_handle_t *mesh, const char *name, void *priv) {
        return true;
 }
 
-static int setup_tcp_listen_socket(meshlink_handle_t *mesh, const struct addrinfo *aip) {
+int setup_tcp_listen_socket(meshlink_handle_t *mesh, const struct addrinfo *aip) {
        int nfd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
 
        if(nfd == -1) {
@@ -339,7 +339,7 @@ static int setup_tcp_listen_socket(meshlink_handle_t *mesh, const struct addrinf
        return nfd;
 }
 
-static int setup_udp_socket(meshlink_handle_t *mesh, const struct addrinfo *aip) {
+int setup_udp_listen_socket(meshlink_handle_t *mesh, const struct addrinfo *aip) {
        int nfd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP);
 
        if(nfd == -1) {
@@ -470,7 +470,7 @@ static bool add_listen_sockets(meshlink_handle_t *mesh) {
 
                /* If TCP worked, then we require that UDP works as well. */
 
-               int udp_fd = setup_udp_socket(mesh, aip);
+               int udp_fd = setup_udp_listen_socket(mesh, aip);
 
                if(udp_fd == -1) {
                        closesocket(tcp_fd);