X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=07326d56f0642e644628346cbf5a06779e5c830c;hb=c9d86e1054b888c2b0223925db531ff9831b01cc;hp=9aca06779a699e17bc667b233571861f507c3b36;hpb=91169c529883e08d7a0245b709483a22a83245ad;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 9aca0677..07326d56 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -154,7 +154,9 @@ static int socket_in_netns(int domain, int type, int protocol, int netns) { pthread_t thr; if(pthread_create(&thr, NULL, socket_in_netns_thread, ¶ms) == 0) { - pthread_join(thr, NULL); + if(pthread_join(thr, NULL) != 0) { + abort(); + } } return params.fd; @@ -268,6 +270,11 @@ char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int fami int s = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns); +#ifdef SO_NOSIGPIPE + int nosigpipe = 1; + setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); +#endif + if(s >= 0) { set_timeout(s, 5000); @@ -337,6 +344,52 @@ static bool is_localaddr(sockaddr_t *sa) { } } +#ifdef HAVE_GETIFADDRS +struct getifaddrs_in_netns_params { + struct ifaddrs **ifa; + int netns; +}; + +#ifdef HAVE_SETNS +static void *getifaddrs_in_netns_thread(void *arg) { + struct getifaddrs_in_netns_params *params = arg; + + if(setns(params->netns, CLONE_NEWNET) == -1) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(getifaddrs(params->ifa) != 0) { + *params->ifa = NULL; + } + + return NULL; +} +#endif // HAVE_SETNS + +static int getifaddrs_in_netns(struct ifaddrs **ifa, int netns) { + if(netns == -1) { + return getifaddrs(ifa); + } + +#ifdef HAVE_SETNS + struct getifaddrs_in_netns_params params = {ifa, netns}; + pthread_t thr; + + if(pthread_create(&thr, NULL, getifaddrs_in_netns_thread, ¶ms) == 0) { + if(pthread_join(thr, NULL) != 0) { + abort(); + } + } + + return *params.ifa ? 0 : -1; +#else + return -1; +#endif // HAVE_SETNS + +} +#endif + char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) { (void)mesh; @@ -354,12 +407,12 @@ char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) if(!success) { struct ifaddrs *ifa = NULL; - getifaddrs(&ifa); + getifaddrs_in_netns(&ifa, mesh->netns); for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) { sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr; - if(sa->sa.sa_family != family) { + if(!sa || sa->sa.sa_family != family) { continue; } @@ -1213,7 +1266,9 @@ bool meshlink_encrypted_key_rotate(meshlink_handle_t *mesh, const void *new_key, return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } // Create hash for the new key void *new_config_key; @@ -1291,10 +1346,10 @@ void meshlink_open_params_free(meshlink_open_params_t *params) { /// Device class traits static const dev_class_traits_t default_class_traits[DEV_CLASS_COUNT] = { - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 1, .max_connects = 1, .edge_weight = 9 }, // DEV_CLASS_UNKNOWN + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 1, .max_connects = 1, .edge_weight = 9 }, // DEV_CLASS_UNKNOWN }; meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) { @@ -1456,11 +1511,21 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { } } - // initialize mutex + // initialize mutexes and conds pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) { + abort(); + } + pthread_mutex_init(&mesh->mutex, &attr); + pthread_cond_init(&mesh->cond, NULL); + + pthread_mutex_init(&mesh->discovery_mutex, NULL); + pthread_cond_init(&mesh->discovery_cond, NULL); + + pthread_cond_init(&mesh->adns_cond, NULL); mesh->threadstarted = false; event_loop_init(&mesh->loop); @@ -1560,7 +1625,9 @@ meshlink_submesh_t *meshlink_submesh_open(meshlink_handle_t *mesh, const char * } //lock mesh->nodes - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } s = (meshlink_submesh_t *)create_submesh(mesh, submesh); @@ -1594,7 +1661,9 @@ static void *meshlink_main_loop(void *arg) { #endif - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } logger(mesh, MESHLINK_DEBUG, "Starting main_loop...\n"); pthread_cond_broadcast(&mesh->cond); @@ -1623,7 +1692,9 @@ bool meshlink_start(meshlink_handle_t *mesh) { logger(mesh, MESHLINK_DEBUG, "meshlink_start called\n"); - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } assert(mesh->self); assert(mesh->private_key); @@ -1642,6 +1713,11 @@ bool meshlink_start(meshlink_handle_t *mesh) { return false; } + // Reset node connection timers + for splay_each(node_t, n, mesh->nodes) { + n->last_connect_try = 0; + } + // TODO: open listening sockets first //Check that a valid name is set @@ -1689,7 +1765,10 @@ void meshlink_stop(meshlink_handle_t *mesh) { return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n"); // Shut down the main thread @@ -1713,8 +1792,14 @@ void meshlink_stop(meshlink_handle_t *mesh) { if(mesh->threadstarted) { // Wait for the main thread to finish pthread_mutex_unlock(&mesh->mutex); - pthread_join(mesh->thread, NULL); - pthread_mutex_lock(&mesh->mutex); + + if(pthread_join(mesh->thread, NULL) != 0) { + abort(); + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } mesh->threadstarted = false; } @@ -1759,7 +1844,9 @@ void meshlink_close(meshlink_handle_t *mesh) { meshlink_stop(mesh); // lock is not released after this - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } // Close and free all resources used. @@ -1880,7 +1967,10 @@ void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->receive_cb = cb; pthread_mutex_unlock(&mesh->mutex); } @@ -1891,7 +1981,10 @@ void meshlink_set_connection_try_cb(meshlink_handle_t *mesh, meshlink_connection return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->connection_try_cb = cb; pthread_mutex_unlock(&mesh->mutex); } @@ -1902,7 +1995,10 @@ void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_c return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->node_status_cb = cb; pthread_mutex_unlock(&mesh->mutex); } @@ -1913,7 +2009,10 @@ void meshlink_set_node_pmtu_cb(meshlink_handle_t *mesh, meshlink_node_pmtu_cb_t return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->node_pmtu_cb = cb; pthread_mutex_unlock(&mesh->mutex); } @@ -1924,14 +2023,20 @@ void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_dupli return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->node_duplicate_cb = cb; pthread_mutex_unlock(&mesh->mutex); } void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) { if(mesh) { - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->log_cb = cb; mesh->log_level = cb ? level : 0; pthread_mutex_unlock(&mesh->mutex); @@ -1947,7 +2052,10 @@ void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->error_cb = cb; pthread_mutex_unlock(&mesh->mutex); } @@ -2067,7 +2175,9 @@ ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) return -1; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = (node_t *)destination; @@ -2090,7 +2200,9 @@ char *meshlink_get_fingerprint(meshlink_handle_t *mesh, meshlink_node_t *node) { return NULL; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = (node_t *)node; @@ -2127,7 +2239,10 @@ meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) { node_t *n = NULL; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + n = lookup_node(mesh, (char *)name); // TODO: make lookup_node() use const pthread_mutex_unlock(&mesh->mutex); @@ -2146,7 +2261,10 @@ meshlink_submesh_t *meshlink_get_submesh(meshlink_handle_t *mesh, const char *na meshlink_submesh_t *submesh = NULL; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + submesh = (meshlink_submesh_t *)lookup_submesh(mesh, name); pthread_mutex_unlock(&mesh->mutex); @@ -2166,7 +2284,9 @@ meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_ meshlink_node_t **result; //lock mesh->nodes - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } *nmemb = mesh->nodes->count; result = realloc(nodes, *nmemb * sizeof(*nodes)); @@ -2191,7 +2311,9 @@ meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_ static meshlink_node_t **meshlink_get_all_nodes_by_condition(meshlink_handle_t *mesh, const void *condition, meshlink_node_t **nodes, size_t *nmemb, search_node_by_condition_t search_node) { meshlink_node_t **result; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } *nmemb = 0; @@ -2308,7 +2430,9 @@ dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t dev_class_t devclass; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } devclass = ((node_t *)node)->devclass; @@ -2341,7 +2465,10 @@ bool meshlink_get_node_reachability(struct meshlink_handle *mesh, struct meshlin node_t *n = (node_t *)node; bool reachable; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + reachable = n->status.reachable && !n->status.blacklisted; if(last_reachable) { @@ -2368,7 +2495,9 @@ bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void * return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(!ecdsa_sign(mesh->private_key, data, len, signature)) { meshlink_errno = MESHLINK_EINTERNAL; @@ -2392,7 +2521,9 @@ bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const voi return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } bool rval = false; @@ -2410,7 +2541,9 @@ bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const voi } static bool refresh_invitation_key(meshlink_handle_t *mesh) { - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } size_t count = invitation_purge_old(mesh, time(NULL) - mesh->invitation_timeout); @@ -2456,7 +2589,9 @@ bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *no canonical_address = xstrdup(address); } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = (node_t *)node; free(n->canonical_address); @@ -2498,7 +2633,9 @@ bool meshlink_add_invitation_address(struct meshlink_handle *mesh, const char *a combo = xstrdup(address); } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(!mesh->invitation_addresses) { mesh->invitation_addresses = list_alloc((list_action_t)free); @@ -2516,7 +2653,9 @@ void meshlink_clear_invitation_addresses(struct meshlink_handle *mesh) { return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(mesh->invitation_addresses) { list_delete_list(mesh->invitation_addresses); @@ -2561,7 +2700,10 @@ int meshlink_get_port(meshlink_handle_t *mesh) { int port; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + port = atoi(mesh->myport); pthread_mutex_unlock(&mesh->mutex); @@ -2587,7 +2729,9 @@ bool meshlink_set_port(meshlink_handle_t *mesh, int port) { bool rval = false; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(mesh->threadstarted) { meshlink_errno = MESHLINK_EINVAL; @@ -2657,7 +2801,9 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, c s = (meshlink_submesh_t *)mesh->self->submesh; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } // Check validity of the new node's name if(!check_id(name)) { @@ -2799,7 +2945,9 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { //TODO: think of a better name for this variable, or of a different way to tokenize the invitation URL. char copy[strlen(invitation) + 1]; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } //Before doing meshlink_join make sure we are not connected to another mesh if(mesh->threadstarted) { @@ -2899,6 +3047,11 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { continue; } +#ifdef SO_NOSIGPIPE + int nosigpipe = 1; + setsockopt(state.sock, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); +#endif + set_timeout(state.sock, 5000); if(connect(state.sock, aip->ai_addr, aip->ai_addrlen)) { @@ -3050,7 +3203,9 @@ char *meshlink_export(meshlink_handle_t *mesh) { packmsg_add_str(&out, mesh->name); packmsg_add_str(&out, CORE_MESH); - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } packmsg_add_int32(&out, mesh->self->devclass); packmsg_add_bool(&out, mesh->self->status.blacklisted); @@ -3138,7 +3293,9 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } while(count--) { const void *data2; @@ -3262,7 +3419,9 @@ bool meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(!blacklist(mesh, (node_t *)node)) { pthread_mutex_unlock(&mesh->mutex); @@ -3281,7 +3440,9 @@ bool meshlink_blacklist_by_name(meshlink_handle_t *mesh, const char *name) { return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = lookup_node(mesh, (char *)name); @@ -3330,7 +3491,9 @@ bool meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(!whitelist(mesh, (node_t *)node)) { pthread_mutex_unlock(&mesh->mutex); @@ -3349,7 +3512,9 @@ bool meshlink_whitelist_by_name(meshlink_handle_t *mesh, const char *name) { return false; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = lookup_node(mesh, (char *)name); @@ -3382,7 +3547,9 @@ bool meshlink_forget_node(meshlink_handle_t *mesh, meshlink_node_t *node) { node_t *n = (node_t *)node; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Check that the node is not reachable */ if(n->status.reachable || n->connection) { @@ -3439,7 +3606,9 @@ void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = (node_t *)node; @@ -3753,7 +3922,10 @@ void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *c return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + channel->poll_cb = cb; utcp_set_poll_cb(channel->c, (cb || channel->aio_send) ? channel_poll : NULL); pthread_mutex_unlock(&mesh->mutex); @@ -3765,7 +3937,10 @@ void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_ac return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->channel_accept_cb = cb; mesh->receive_cb = channel_receive; @@ -3788,7 +3963,10 @@ void meshlink_set_channel_sndbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + utcp_set_sndbuf(channel->c, size); pthread_mutex_unlock(&mesh->mutex); } @@ -3801,7 +3979,10 @@ void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + utcp_set_rcvbuf(channel->c, size); pthread_mutex_unlock(&mesh->mutex); } @@ -3816,7 +3997,9 @@ meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_n return NULL; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } node_t *n = (node_t *)node; @@ -3871,7 +4054,10 @@ void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *chan return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + utcp_shutdown(channel->c, direction); pthread_mutex_unlock(&mesh->mutex); } @@ -3882,7 +4068,9 @@ void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(channel->c) { utcp_close(channel->c); @@ -3922,7 +4110,9 @@ ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *chann ssize_t retval; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Disallow direct calls to utcp_send() while we still have AIO active. */ if(channel->aio_send) { @@ -3957,7 +4147,9 @@ bool meshlink_channel_aio_send(meshlink_handle_t *mesh, meshlink_channel_t *chan aio->cb.buffer = cb; aio->priv = priv; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Append the AIO buffer descriptor to the end of the chain */ meshlink_aio_buffer_t **p = &channel->aio_send; @@ -3998,7 +4190,9 @@ bool meshlink_channel_aio_fd_send(meshlink_handle_t *mesh, meshlink_channel_t *c aio->cb.fd = cb; aio->priv = priv; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Append the AIO buffer descriptor to the end of the chain */ meshlink_aio_buffer_t **p = &channel->aio_send; @@ -4039,7 +4233,9 @@ bool meshlink_channel_aio_receive(meshlink_handle_t *mesh, meshlink_channel_t *c aio->cb.buffer = cb; aio->priv = priv; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Append the AIO buffer descriptor to the end of the chain */ meshlink_aio_buffer_t **p = &channel->aio_receive; @@ -4072,7 +4268,9 @@ bool meshlink_channel_aio_fd_receive(meshlink_handle_t *mesh, meshlink_channel_t aio->cb.fd = cb; aio->priv = priv; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } /* Append the AIO buffer descriptor to the end of the chain */ meshlink_aio_buffer_t **p = &channel->aio_receive; @@ -4132,7 +4330,9 @@ void meshlink_set_node_channel_timeout(meshlink_handle_t *mesh, meshlink_node_t node_t *n = (node_t *)node; - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(!n->utcp) { n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n); @@ -4186,7 +4386,9 @@ void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) { return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } if(mesh->discovery == enable) { goto end; @@ -4222,7 +4424,10 @@ void meshlink_set_dev_class_timeouts(meshlink_handle_t *mesh, dev_class_t devcla return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->dev_class_traits[devclass].pinginterval = pinginterval; mesh->dev_class_traits[devclass].pingtimeout = pingtimeout; pthread_mutex_unlock(&mesh->mutex); @@ -4239,18 +4444,56 @@ void meshlink_set_dev_class_fast_retry_period(meshlink_handle_t *mesh, dev_class return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->dev_class_traits[devclass].fast_retry_period = fast_retry_period; pthread_mutex_unlock(&mesh->mutex); } -extern void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first) { +void meshlink_set_dev_class_maxtimeout(struct meshlink_handle *mesh, dev_class_t devclass, int maxtimeout) { + if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) { + meshlink_errno = EINVAL; + return; + } + + if(maxtimeout < 0) { + meshlink_errno = EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + mesh->dev_class_traits[devclass].maxtimeout = maxtimeout; + pthread_mutex_unlock(&mesh->mutex); +} + +void meshlink_reset_timers(struct meshlink_handle *mesh) { + if(!mesh) { + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + handle_network_change(mesh, true); + pthread_mutex_unlock(&mesh->mutex); +} + +void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first) { if(!mesh) { meshlink_errno = EINVAL; return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + mesh->inviter_commits_first = inviter_commits_first; pthread_mutex_unlock(&mesh->mutex); } @@ -4266,7 +4509,10 @@ void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, c return; } - pthread_mutex_lock(&mesh->mutex); + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + free(mesh->external_address_url); mesh->external_address_url = url ? xstrdup(url) : NULL; pthread_mutex_unlock(&mesh->mutex); @@ -4289,6 +4535,7 @@ void handle_network_change(meshlink_handle_t *mesh, bool online) { } retry(mesh); + signal_trigger(&mesh->loop, &mesh->datafromapp); } void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t cb_errno) {