X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=8f0f82d1a8ae1c3afe5f94f0db22c134c2783ecd;hb=de126fa104aaeabbc66b5dd59da9d07da2f0fd97;hp=815acdeadd60f40e6e8691a2f5e779a849e5f9e2;hpb=55010e8cd9fad4996db774aab3d578b431f9ee73;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 815acdea..8f0f82d1 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -37,6 +37,7 @@ typedef struct { #include "meshlink_internal.h" #include "netutl.h" #include "node.h" +#include "submesh.h" #include "protocol.h" #include "route.h" #include "sockaddr.h" @@ -59,6 +60,7 @@ const var_t variables[] = { {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, {"Name", VAR_SERVER}, /* Host configuration */ + {"SubMesh", VAR_HOST | VAR_SAFE}, {"CanonicalAddress", VAR_HOST}, {"Address", VAR_HOST | VAR_MULTIPLE}, {"ECDSAPublicKey", VAR_HOST}, @@ -1304,6 +1306,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { mesh->discovery = true; mesh->invitation_timeout = 604800; // 1 week mesh->netns = params->netns; + mesh->submeshes = NULL; if(usingname) { mesh->name = xstrdup(params->name); @@ -1415,6 +1418,38 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { return mesh; } +meshlink_submesh_t *meshlink_submesh_open(meshlink_handle_t *mesh, const char *submesh) { + meshlink_submesh_t *s = NULL; + + if(!mesh) { + logger(NULL, MESHLINK_ERROR, "No mesh handle given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(!submesh || !*submesh) { + logger(NULL, MESHLINK_ERROR, "No submesh name given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + s = (meshlink_submesh_t *)lookup_submesh(mesh, submesh); + + if(s) { + logger(NULL, MESHLINK_ERROR, "SubMesh Already exists!\n"); + meshlink_errno = MESHLINK_EEXIST; + return NULL; + } + + s = (meshlink_submesh_t *)new_submesh(); + s->name = xstrdup(submesh); + + submesh_add(mesh, (submesh_t *)s); + + meshlink_errno = MESHLINK_OK; + return s; +} + static void *meshlink_main_loop(void *arg) { meshlink_handle_t *mesh = arg; @@ -1697,6 +1732,13 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const return false; } + node_t *n = (node_t *)destination; + + if(n->status.blacklisted) { + logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name); + return false; + } + // Prepare the packet vpn_packet_t *packet = malloc(sizeof(*packet)); @@ -2216,12 +2258,24 @@ void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) { mesh->invitation_timeout = timeout; } -char *meshlink_invite_ex(meshlink_handle_t *mesh, const char *name, uint32_t flags) { +char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name, uint32_t flags) { + meshlink_submesh_t *s = NULL; + if(!mesh) { meshlink_errno = MESHLINK_EINVAL; return NULL; } + if(submesh) { + s = (meshlink_submesh_t *)lookup_submesh(mesh, submesh->name); + + if(s != submesh) { + logger(mesh, MESHLINK_DEBUG, "Invalid SubMesh Handle.\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + } + pthread_mutex_lock(&(mesh->mesh_mutex)); // Check validity of the new node's name @@ -2309,6 +2363,11 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, const char *name, uint32_t fla // Fill in the details. fprintf(f, "Name = %s\n", name); + + if(s) { + fprintf(f, "SubMesh = %s\n", s->name); + } + fprintf(f, "ConnectTo = %s\n", mesh->self->name); // Copy Broadcast and Mode @@ -2354,8 +2413,8 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, const char *name, uint32_t fla return url; } -char *meshlink_invite(meshlink_handle_t *mesh, const char *name) { - return meshlink_invite_ex(mesh, name, 0); +char *meshlink_invite(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name) { + return meshlink_invite_ex(mesh, submesh, name, 0); } bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { @@ -2721,6 +2780,20 @@ void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { node_t *n; n = (node_t *)node; + + if(n == mesh->self) { + logger(mesh, MESHLINK_ERROR, "%s blacklisting itself?\n", node->name); + meshlink_errno = MESHLINK_EINVAL; + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return; + } + + if(n->status.blacklisted) { + logger(mesh, MESHLINK_DEBUG, "Node %s already blacklisted\n", node->name); + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return; + } + n->status.blacklisted = true; logger(mesh, MESHLINK_DEBUG, "Blacklisted %s.\n", node->name); @@ -2734,6 +2807,18 @@ void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { } } + utcp_abort_all_connections(n->utcp); + + n->mtu = 0; + n->minmtu = 0; + n->maxmtu = MTU; + n->mtuprobes = 0; + n->status.udp_confirmed = false; + + if(n->status.reachable) { + update_node_status(mesh, n); + } + pthread_mutex_unlock(&(mesh->mesh_mutex)); } @@ -2746,9 +2831,22 @@ void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { pthread_mutex_lock(&(mesh->mesh_mutex)); node_t *n = (node_t *)node; + + if(!n->status.blacklisted) { + logger(mesh, MESHLINK_DEBUG, "Node %s was already whitelisted\n", node->name); + meshlink_errno = MESHLINK_EINVAL; + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return; + } + n->status.blacklisted = false; - //TODO: remove blacklisted = yes from the config file + if(n->status.reachable) { + update_node_status(mesh, n); + } + + //Remove blacklisting from the config file + append_config_file(mesh, n->name, "blacklisted", NULL); pthread_mutex_unlock(&(mesh->mesh_mutex)); return; @@ -2937,6 +3035,11 @@ meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_n } } + if(n->status.blacklisted) { + logger(mesh, MESHLINK_ERROR, "Cannot open a channel with blacklisted node\n"); + return NULL; + } + meshlink_channel_t *channel = xzalloc(sizeof(*channel)); channel->node = n; channel->receive_cb = cb; @@ -3020,7 +3123,7 @@ void update_node_status(meshlink_handle_t *mesh, node_t *n) { } if(mesh->node_status_cb) { - mesh->node_status_cb(mesh, (meshlink_node_t *)n, n->status.reachable); + mesh->node_status_cb(mesh, (meshlink_node_t *)n, n->status.reachable && !n->status.blacklisted); } }