]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Modified meshlink_invite to generate invites for submesh
[meshlink] / src / meshlink.c
index 520176232d6f05beb68fa2eeb11caa60116e9b61..d094452733712c2e1b02b3bbfaa09efce7e96cca 100644 (file)
@@ -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) {