]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Make meshlink_set_port() return false if we didn't bind to the requested port.
[meshlink] / src / meshlink.c
index 6f83c22fbd762a8bc68fd0c71b01af1aa1cdd844..496e5d3c753763560bf173591a3aa8f883559dd6 100644 (file)
@@ -49,7 +49,6 @@ typedef struct {
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
 #endif
-
 __thread meshlink_errno_t meshlink_errno;
 meshlink_log_cb_t global_log_cb;
 meshlink_log_level_t global_log_level;
@@ -215,23 +214,27 @@ struct socket_in_netns_params {
        int fd;
 };
 
+#ifdef HAVE_SETNS
 static void *socket_in_netns_thread(void *arg) {
        struct socket_in_netns_params *params = arg;
 
        if(setns(params->netns, CLONE_NEWNET) == -1) {
                meshlink_errno = MESHLINK_EINVAL;
-       } else {
-               params->fd = socket(params->domain, params->type, params->protocol);
+               return NULL;
        }
 
+       params->fd = socket(params->domain, params->type, params->protocol);
+
        return NULL;
 }
+#endif // HAVE_SETNS
 
 static int socket_in_netns(int domain, int type, int protocol, int netns) {
        if(netns == -1) {
                return socket(domain, type, protocol);
        }
 
+#ifdef HAVE_SETNS
        struct socket_in_netns_params params = {domain, type, protocol, netns, -1};
 
        pthread_t thr;
@@ -241,6 +244,10 @@ static int socket_in_netns(int domain, int type, int protocol, int netns) {
        }
 
        return params.fd;
+#else
+       return -1;
+#endif // HAVE_SETNS
+
 }
 
 // Find out what local address a socket would use if we connect to the given address.
@@ -626,23 +633,22 @@ static bool try_bind(int port) {
                return false;
        }
 
-       while(ai) {
-               int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
+       //while(ai) {
+       for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
+               int fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
 
                if(!fd) {
                        freeaddrinfo(ai);
                        return false;
                }
 
-               int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
+               int result = bind(fd, aip->ai_addr, aip->ai_addrlen);
                closesocket(fd);
 
                if(result) {
                        freeaddrinfo(ai);
                        return false;
                }
-
-               ai = ai->ai_next;
        }
 
        freeaddrinfo(ai);
@@ -923,7 +929,7 @@ static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint
                return finalize_join(mesh);
 
        case 2:
-               logger(mesh, MESHLINK_DEBUG, "Invitation succesfully accepted.\n");
+               logger(mesh, MESHLINK_DEBUG, "Invitation successfully accepted.\n");
                shutdown(mesh->sock, SHUT_RDWR);
                mesh->success = true;
                break;
@@ -1173,6 +1179,7 @@ static bool meshlink_setup(meshlink_handle_t *mesh) {
        return true;
 }
 
+#ifdef HAVE_SETNS
 static void *setup_network_in_netns_thread(void *arg) {
        meshlink_handle_t *mesh = arg;
 
@@ -1184,6 +1191,7 @@ static void *setup_network_in_netns_thread(void *arg) {
        add_local_addresses(mesh);
        return success ? arg : NULL;
 }
+#endif // HAVE_SETNS
 
 meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
        if(!confbase || !*confbase) {
@@ -1247,7 +1255,8 @@ void meshlink_open_params_free(meshlink_open_params_t *params) {
 
 meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
        /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
-       meshlink_open_params_t params = {NULL};
+       meshlink_open_params_t params;
+       memset(&params, 0, sizeof(params));
 
        params.confbase = (char *)confbase;
        params.name = (char *)name;
@@ -1397,12 +1406,19 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
        bool success = false;
 
        if(mesh->netns != -1) {
+#ifdef HAVE_SETNS
                pthread_t thr;
 
                if(pthread_create(&thr, NULL, setup_network_in_netns_thread, mesh) == 0) {
                        void *retval = NULL;
                        success = pthread_join(thr, &retval) == 0 && retval;
                }
+
+#else
+               meshlink_errno = MESHLINK_EINTERNAL;
+               return NULL;
+
+#endif // HAVE_SETNS
        } else {
                success = setup_network(mesh);
                add_local_addresses(mesh);
@@ -1449,9 +1465,15 @@ static void *meshlink_main_loop(void *arg) {
        meshlink_handle_t *mesh = arg;
 
        if(mesh->netns != -1) {
+#ifdef HAVE_SETNS
+
                if(setns(mesh->netns, CLONE_NEWNET) != 0) {
                        return NULL;
                }
+
+#else
+               return NULL;
+#endif // HAVE_SETNS
        }
 
        pthread_mutex_lock(&(mesh->mesh_mutex));
@@ -1675,6 +1697,17 @@ void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb)
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
+void meshlink_set_connection_try_cb(meshlink_handle_t *mesh, meshlink_connection_try_cb_t cb) {
+       if(!mesh) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       pthread_mutex_lock(&(mesh->mesh_mutex));
+       mesh->connection_try_cb = cb;
+       pthread_mutex_unlock(&(mesh->mesh_mutex));
+}
+
 void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) {
        if(!mesh) {
                meshlink_errno = MESHLINK_EINVAL;
@@ -1853,6 +1886,20 @@ meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
        return node;
 }
 
+meshlink_submesh_t *meshlink_get_submesh(meshlink_handle_t *mesh, const char *name) {
+       if(!mesh || !name) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       meshlink_submesh_t *submesh = NULL;
+
+       pthread_mutex_lock(&(mesh->mesh_mutex));
+       submesh = (meshlink_submesh_t *)lookup_submesh(mesh, name);
+       pthread_mutex_unlock(&(mesh->mesh_mutex));
+       return submesh;
+}
+
 meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) {
        if(!mesh || !nmemb || (*nmemb && !nodes)) {
                meshlink_errno = MESHLINK_EINVAL;
@@ -2088,7 +2135,7 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) {
                }
 
                if(!stat(invname, &st)) {
-                       if(mesh->invitation_key && deadline < st.st_mtime) {
+                       if(mesh->invitation_key && deadline < (time_t)st.st_mtime) {
                                count++;
                        } else {
                                unlink(invname);
@@ -2292,7 +2339,7 @@ bool meshlink_set_port(meshlink_handle_t *mesh, int port) {
 done:
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 
-       return rval;
+       return rval && meshlink_get_port(mesh) == port;
 }
 
 void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) {
@@ -3137,7 +3184,7 @@ ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *chann
 
        // TODO: more finegrained locking.
        // Ideally we want to put the data into the UTCP connection's send buffer.
-       // Then, preferrably only if there is room in the receiver window,
+       // Then, preferably only if there is room in the receiver window,
        // kick the meshlink thread to go send packets.
 
        pthread_mutex_lock(&mesh->mesh_mutex);
@@ -3160,6 +3207,24 @@ uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t
        return channel->c->flags;
 }
 
+size_t meshlink_channel_get_sendq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+       if(!mesh || !channel) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return -1;
+       }
+
+       return utcp_get_sendq(channel->c);
+}
+
+size_t meshlink_channel_get_recvq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+       if(!mesh || !channel) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return -1;
+       }
+
+       return utcp_get_recvq(channel->c);
+}
+
 void update_node_status(meshlink_handle_t *mesh, node_t *n) {
        if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
                n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);