X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=d094452733712c2e1b02b3bbfaa09efce7e96cca;hb=43d8f901c4bbb693643bb6f188c97dd28c1d0b0a;hp=520176232d6f05beb68fa2eeb11caa60116e9b61;hpb=6054182c9e208fd0b3f5c6c90f54cb5af75d3f5c;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 52017623..d0944527 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; @@ -1847,6 +1882,68 @@ meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_ return result; } +meshlink_node_t **meshlink_get_all_nodes_by_dev_class(meshlink_handle_t *mesh, dev_class_t devclass, meshlink_node_t **nodes, size_t *nmemb) { + if(!mesh || ((int)devclass < 0) || (devclass > _DEV_CLASS_MAX) || !nmemb) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + meshlink_node_t **result; + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + *nmemb = 0; + + for splay_each(node_t, n, mesh->nodes) { + if(n->devclass == devclass) { + *nmemb = *nmemb + 1; + } + } + + if(*nmemb == 0) { + free(nodes); + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return NULL; + } + + result = realloc(nodes, *nmemb * sizeof(*nodes)); + + if(result) { + meshlink_node_t **p = result; + + for splay_each(node_t, n, mesh->nodes) { + if(n->devclass == devclass) { + *p++ = (meshlink_node_t *)n; + } + } + } else { + *nmemb = 0; + free(nodes); + meshlink_errno = MESHLINK_ENOMEM; + } + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return result; +} + +dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) { + if(!mesh || !node) { + meshlink_errno = MESHLINK_EINVAL; + return -1; + } + + dev_class_t devclass; + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + devclass = ((node_t *)node)->devclass; + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return devclass; +} + bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) { if(!mesh || !data || !len || !signature || !siglen) { meshlink_errno = MESHLINK_EINVAL; @@ -2154,12 +2251,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 @@ -2247,6 +2356,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 @@ -2292,8 +2406,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) {