X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=fe11af2cc44966a309afea3e224ca9935d2b2229;hb=325d837df2ec867c668b6a911b97e719f196ba0e;hp=d9bd0146e94cedaf4b6dc5967e28f6a4f00483c9;hpb=eba5b30f09f91d95c56efb8f1d8613152c176856;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index d9bd0146..fe11af2c 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1,6 +1,6 @@ /* meshlink.c -- Implementation of the MeshLink API. - Copyright (C) 2014-2018 Guus Sliepen + Copyright (C) 2014-2021 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1515,7 +1515,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { mesh->appname = xstrdup(params->appname); mesh->devclass = params->devclass; - mesh->discovery = true; + mesh->discovery.enabled = true; mesh->invitation_timeout = 604800; // 1 week mesh->netns = params->netns; mesh->submeshes = NULL; @@ -1556,9 +1556,6 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { 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; @@ -1693,7 +1690,7 @@ static void *meshlink_main_loop(void *arg) { #endif // HAVE_SETNS } - if(mesh->discovery) { + if(mesh->discovery.enabled) { discovery_start(mesh); } @@ -1709,7 +1706,7 @@ static void *meshlink_main_loop(void *arg) { pthread_mutex_unlock(&mesh->mutex); // Stop discovery - if(mesh->discovery) { + if(mesh->discovery.enabled) { discovery_stop(mesh); } @@ -3157,7 +3154,7 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { } // Connect to the meshlink daemon mentioned in the URL. - struct addrinfo *ai = adns_blocking_request(mesh, xstrdup(address), xstrdup(port), SOCK_STREAM, 5); + struct addrinfo *ai = adns_blocking_request(mesh, xstrdup(address), xstrdup(port), SOCK_STREAM, 30); if(ai) { for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { @@ -3402,6 +3399,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { if(!buflen) { logger(mesh, MESHLINK_DEBUG, "Invalid data\n"); + free(buf); meshlink_errno = MESHLINK_EPEER; return false; } @@ -3411,6 +3409,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { if(!count) { logger(mesh, MESHLINK_DEBUG, "Invalid data\n"); + free(buf); meshlink_errno = MESHLINK_EPEER; return false; } @@ -3467,6 +3466,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { if(!node_write_config(mesh, n, true)) { free_node(n); + free(buf); return false; } @@ -3517,7 +3517,7 @@ static bool blacklist(meshlink_handle_t *mesh, node_t *n) { } } - utcp_abort_all_connections(n->utcp); + utcp_reset_all_connections(n->utcp); n->mtu = 0; n->minmtu = 0; @@ -4255,6 +4255,32 @@ void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel pthread_mutex_unlock(&mesh->mutex); } +void meshlink_channel_abort(meshlink_handle_t *mesh, meshlink_channel_t *channel) { + if(!mesh || !channel) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + if(channel->c) { + utcp_abort(channel->c); + channel->c = NULL; + + /* Clean up any outstanding AIO buffers. */ + aio_abort(mesh, channel, &channel->aio_send); + aio_abort(mesh, channel, &channel->aio_receive); + } + + if(!channel->in_callback) { + free(channel); + } + + pthread_mutex_unlock(&mesh->mutex); +} + ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) { if(!mesh || !channel) { meshlink_errno = MESHLINK_EINVAL; @@ -4555,7 +4581,7 @@ void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) { abort(); } - if(mesh->discovery == enable) { + if(mesh->discovery.enabled == enable) { goto end; } @@ -4567,12 +4593,34 @@ void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) { } } - mesh->discovery = enable; + mesh->discovery.enabled = enable; end: pthread_mutex_unlock(&mesh->mutex); } +void meshlink_hint_network_change(struct meshlink_handle *mesh) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + if(mesh->discovery.enabled) { + scan_ifaddrs(mesh); + } + + if(mesh->loop.now.tv_sec > mesh->discovery.last_update + 5) { + mesh->discovery.last_update = mesh->loop.now.tv_sec; + handle_network_change(mesh, 1); + } + + pthread_mutex_unlock(&mesh->mutex); +} + void meshlink_set_dev_class_timeouts(meshlink_handle_t *mesh, dev_class_t devclass, int pinginterval, int pingtimeout) { if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) { meshlink_errno = EINVAL; @@ -4641,6 +4689,11 @@ void meshlink_reset_timers(struct meshlink_handle *mesh) { } handle_network_change(mesh, true); + + if(mesh->discovery.enabled) { + discovery_refresh(mesh); + } + pthread_mutex_unlock(&mesh->mutex); }