X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=da7305515bec02fb4687b91afa0d08b02819dd96;hb=3ed9219f9f7a7b0f71843aa1ca05b5d3cf5cf016;hp=a8ed1fad3d20a0d39db9ad5f9c7a67763d904e6f;hpb=d1b43b5060795728b95b4ed3311b3398771cf34e;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index a8ed1fad..da730551 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -391,7 +391,10 @@ static int getifaddrs_in_netns(struct ifaddrs **ifa, int netns) { #endif char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) { - (void)mesh; + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } // Determine address of the local interface used for outgoing connections. char localaddr[NI_MAXHOST]; @@ -686,7 +689,7 @@ static bool write_main_config_files(meshlink_handle_t *mesh) { } /* Write our own host config file */ - if(!node_write_config(mesh, mesh->self)) { + if(!node_write_config(mesh, mesh->self, true)) { return false; } @@ -820,7 +823,7 @@ static bool finalize_join(join_state_t *state, const void *buf, uint16_t len) { n->last_reachable = 0; n->last_unreachable = 0; - if(!node_write_config(mesh, n)) { + if(!node_write_config(mesh, n, true)) { free_node(n); return false; } @@ -1259,6 +1262,17 @@ bool meshlink_open_params_set_storage_key(meshlink_open_params_t *params, const return true; } +bool meshlink_open_params_set_storage_policy(meshlink_open_params_t *params, meshlink_storage_policy_t policy) { + if(!params) { + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + params->storage_policy = policy; + + return true; +} + bool meshlink_encrypted_key_rotate(meshlink_handle_t *mesh, const void *new_key, size_t new_keylen) { if(!mesh || !new_key || !new_keylen) { logger(mesh, MESHLINK_ERROR, "Invalid arguments given!\n"); @@ -1541,6 +1555,8 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { // If no configuration exists yet, create it. + bool new_configuration = false; + if(!meshlink_confbase_exists(mesh)) { if(!mesh->name) { logger(NULL, MESHLINK_ERROR, "No configuration files found!\n"); @@ -1554,6 +1570,8 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { meshlink_close(mesh); return NULL; } + + new_configuration = true; } else { if(!meshlink_read_config(mesh)) { logger(NULL, MESHLINK_ERROR, "Cannot read main configuration\n"); @@ -1562,6 +1580,8 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { } } + mesh->storage_policy = params->storage_policy; + #ifdef HAVE_MINGW struct WSAData wsa_state; WSAStartup(MAKEWORD(2, 2), &wsa_state); @@ -1598,7 +1618,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { add_local_addresses(mesh); - if(!node_write_config(mesh, mesh->self)) { + if(!node_write_config(mesh, mesh->self, new_configuration)) { logger(NULL, MESHLINK_ERROR, "Cannot update configuration\n"); return NULL; } @@ -1826,7 +1846,9 @@ void meshlink_stop(meshlink_handle_t *mesh) { if(mesh->nodes) { for splay_each(node_t, n, mesh->nodes) { if(n->status.dirty) { - n->status.dirty = !node_write_config(mesh, n); + if(!node_write_config(mesh, n, false)) { + // ignore + } } } } @@ -2060,6 +2082,20 @@ void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) pthread_mutex_unlock(&mesh->mutex); } +void meshlink_set_blacklisted_cb(struct meshlink_handle *mesh, meshlink_blacklisted_cb_t cb) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + mesh->blacklisted_cb = cb; + pthread_mutex_unlock(&mesh->mutex); +} + static bool prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len, vpn_packet_t *packet) { meshlink_packethdr_t *hdr; @@ -2360,6 +2396,10 @@ static bool search_node_by_dev_class(const node_t *node, const void *condition) return false; } +static bool search_node_by_blacklisted(const node_t *node, const void *condition) { + return *(bool *)condition == node->status.blacklisted; +} + static bool search_node_by_submesh(const node_t *node, const void *condition) { if(condition == node->submesh) { return true; @@ -2422,6 +2462,15 @@ meshlink_node_t **meshlink_get_all_nodes_by_last_reachable(meshlink_handle_t *me return meshlink_get_all_nodes_by_condition(mesh, &range, nodes, nmemb, search_node_by_last_reachable); } +meshlink_node_t **meshlink_get_all_nodes_by_blacklisted(meshlink_handle_t *mesh, bool blacklisted, meshlink_node_t **nodes, size_t *nmemb) { + if(!mesh || !nmemb) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + return meshlink_get_all_nodes_by_condition(mesh, &blacklisted, nodes, nmemb, search_node_by_blacklisted); +} + dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) { if(!mesh || !node) { meshlink_errno = MESHLINK_EINVAL; @@ -2441,6 +2490,28 @@ dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t return devclass; } +bool meshlink_get_node_blacklisted(meshlink_handle_t *mesh, meshlink_node_t *node) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + } + + if(!node) { + return mesh->default_blacklist; + } + + bool blacklisted; + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + blacklisted = ((node_t *)node)->status.blacklisted; + + pthread_mutex_unlock(&mesh->mutex); + + return blacklisted; +} + meshlink_submesh_t *meshlink_get_node_submesh(meshlink_handle_t *mesh, meshlink_node_t *node) { if(!mesh || !node) { meshlink_errno = MESHLINK_EINVAL; @@ -2593,7 +2664,7 @@ bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *no free(n->canonical_address); n->canonical_address = canonical_address; - if(!node_write_config(mesh, n)) { + if(!node_write_config(mesh, n, false)) { pthread_mutex_unlock(&mesh->mutex); return false; } @@ -2617,7 +2688,7 @@ bool meshlink_clear_canonical_address(meshlink_handle_t *mesh, meshlink_node_t * free(n->canonical_address); n->canonical_address = NULL; - if(!node_write_config(mesh, n)) { + if(!node_write_config(mesh, n, false)) { pthread_mutex_unlock(&mesh->mutex); return false; } @@ -2867,7 +2938,7 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, c // If we changed our own host config file, write it out now if(mesh->self->status.dirty) { - if(!node_write_config(mesh, mesh->self)) { + if(!node_write_config(mesh, mesh->self, false)) { logger(mesh, MESHLINK_ERROR, "Could not write our own host config file!\n"); pthread_mutex_unlock(&mesh->mutex); return NULL; @@ -3363,7 +3434,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { n->last_reachable = 0; n->last_unreachable = 0; - if(!node_write_config(mesh, n)) { + if(!node_write_config(mesh, n, true)) { free_node(n); return false; } @@ -3407,6 +3478,10 @@ static bool blacklist(meshlink_handle_t *mesh, node_t *n) { */ for list_each(connection_t, c, mesh->connections) { if(c->node == n) { + if(c->status.active) { + send_error(mesh, c, BLACKLISTED, "blacklisted"); + } + shutdown(c->socket, SHUT_RDWR); } } @@ -3430,7 +3505,10 @@ static bool blacklist(meshlink_handle_t *mesh, node_t *n) { mesh->node_status_cb(mesh, (meshlink_node_t *)n, false); } - return node_write_config(mesh, n) && config_sync(mesh, "current"); + /* Remove any outstanding invitations */ + invitation_purge_node(mesh, n->name); + + return node_write_config(mesh, n, true) && config_sync(mesh, "current"); } bool meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { @@ -3502,7 +3580,7 @@ static bool whitelist(meshlink_handle_t *mesh, node_t *n) { update_node_status(mesh, n); } - return node_write_config(mesh, n) && config_sync(mesh, "current"); + return node_write_config(mesh, n, true) && config_sync(mesh, "current"); } bool meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { @@ -3609,6 +3687,9 @@ bool meshlink_forget_node(meshlink_handle_t *mesh, meshlink_node_t *node) { return false; } + /* Delete any pending invitations */ + invitation_purge_node(mesh, n->name); + /* Delete the node struct and any remaining edges referencing this node */ node_del(mesh, n); @@ -3633,7 +3714,7 @@ void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const node_t *n = (node_t *)node; if(node_add_recent_address(mesh, n, (sockaddr_t *)addr)) { - if(!node_write_config(mesh, n)) { + if(!node_write_config(mesh, n, false)) { logger(mesh, MESHLINK_DEBUG, "Could not update %s\n", n->name); } } @@ -3804,7 +3885,7 @@ static void channel_retransmit(struct utcp_connection *utcp_connection) { node_t *n = utcp_connection->utcp->priv; meshlink_handle_t *mesh = n->mesh; - if(n->mtuprobes == 31) { + if(n->mtuprobes == 31 && n->mtutimeout.cb) { timeout_set(&mesh->loop, &n->mtutimeout, &(struct timespec) { 0, 0 }); @@ -3993,9 +4074,15 @@ void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_ac } void meshlink_set_channel_sndbuf(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t size) { - (void)mesh; + meshlink_set_channel_sndbuf_storage(mesh, channel, NULL, size); +} - if(!channel) { +void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t size) { + meshlink_set_channel_rcvbuf_storage(mesh, channel, NULL, size); +} + +void meshlink_set_channel_sndbuf_storage(meshlink_handle_t *mesh, meshlink_channel_t *channel, void *buf, size_t size) { + if(!mesh || !channel) { meshlink_errno = MESHLINK_EINVAL; return; } @@ -4004,14 +4091,26 @@ void meshlink_set_channel_sndbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch abort(); } - utcp_set_sndbuf(channel->c, size); + utcp_set_sndbuf(channel->c, buf, size); pthread_mutex_unlock(&mesh->mutex); } -void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t size) { - (void)mesh; +void meshlink_set_channel_rcvbuf_storage(meshlink_handle_t *mesh, meshlink_channel_t *channel, void *buf, size_t size) { + if(!mesh || !channel) { + meshlink_errno = MESHLINK_EINVAL; + return; + } - if(!channel) { + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + utcp_set_rcvbuf(channel->c, buf, size); + pthread_mutex_unlock(&mesh->mutex); +} + +void meshlink_set_channel_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint32_t flags) { + if(!mesh || !channel) { meshlink_errno = MESHLINK_EINVAL; return; } @@ -4020,7 +4119,7 @@ void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch abort(); } - utcp_set_rcvbuf(channel->c, size); + utcp_set_flags(channel->c, flags); pthread_mutex_unlock(&mesh->mutex); } @@ -4564,6 +4663,20 @@ void meshlink_set_scheduling_granularity(struct meshlink_handle *mesh, long gran utcp_set_clock_granularity(granularity); } +void meshlink_set_storage_policy(struct meshlink_handle *mesh, meshlink_storage_policy_t policy) { + if(!mesh) { + meshlink_errno = EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + mesh->storage_policy = policy; + pthread_mutex_unlock(&mesh->mutex); +} + void handle_network_change(meshlink_handle_t *mesh, bool online) { (void)online;