]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Add support for opening a MeshLink instance without permanent storage.
[meshlink] / src / meshlink.c
index a3e3eb7cee99fc8a38ab640389b616564e6468ec..f6ebe1993531322c817f72cb67d299c392fc7132 100644 (file)
@@ -558,36 +558,28 @@ static bool finalize_join(meshlink_handle_t *mesh, const void *buf, uint16_t len
                        return false;
                }
 
-               packmsg_input_t in2 = {data, len};
-               uint32_t version = packmsg_get_uint32(&in2);
+               config_t config = {data, len};
+               node_t *n = new_node();
 
-               if(version != MESHLINK_CONFIG_VERSION) {
+               if(!node_read_from_config(mesh, n, &config)) {
+                       free_node(n);
                        logger(mesh, MESHLINK_ERROR, "Invalid host config file in invitation file!\n");
+                       meshlink_errno = MESHLINK_EPEER;
                        return false;
                }
 
-               char *host = packmsg_get_str_dup(&in2);
-
-               if(!check_id(host)) {
-                       logger(mesh, MESHLINK_ERROR, "Invalid node name in invitation file!\n");
-                       free(host);
-                       return false;
-               }
-
-               if(!strcmp(host, name)) {
+               if(!strcmp(n->name, name)) {
                        logger(mesh, MESHLINK_DEBUG, "Secondary chunk would overwrite our own host config file.\n");
-                       free(host);
+                       free_node(n);
+                       meshlink_errno = MESHLINK_EPEER;
                        return false;
                }
 
-               config_t config = {data, len};
-               config_write(mesh, host, &config);
-
-               node_t *n = new_node();
-               n->name = host;
-               node_read_full(mesh, n);
-               n->devclass = mesh->devclass;
                node_add(mesh, n);
+
+               if(!config_write(mesh, n->name, &config)) {
+                       return false;
+               }
        }
 
        sptps_send_record(&(mesh->sptps), 1, ecdsa_get_public_key(mesh->private_key), 32);
@@ -599,8 +591,6 @@ static bool finalize_join(meshlink_handle_t *mesh, const void *buf, uint16_t len
 
        logger(mesh, MESHLINK_DEBUG, "Configuration stored in: %s\n", mesh->confbase);
 
-       load_all_nodes(mesh);
-
        return true;
 }
 
@@ -942,18 +932,10 @@ static bool meshlink_read_config(meshlink_handle_t *mesh) {
 }
 
 
-meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *name, const char *appname, dev_class_t devclass, const void *key, size_t keylen) {
+static meshlink_handle_t *meshlink_open_internal(const char *confbase, const char *name, const char *appname, dev_class_t devclass, const void *key, size_t keylen) {
        // Validate arguments provided by the application
        bool usingname = false;
 
-       logger(NULL, MESHLINK_DEBUG, "meshlink_open called\n");
-
-       if(!confbase || !*confbase) {
-               logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
-               meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
-       }
-
        if(!appname || !*appname) {
                logger(NULL, MESHLINK_ERROR, "No appname given!\n");
                meshlink_errno = MESHLINK_EINVAL;
@@ -966,17 +948,14 @@ meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *nam
                return NULL;
        }
 
-       if(!name || !*name) {
-               logger(NULL, MESHLINK_ERROR, "No name given!\n");
-               //return NULL;
-       } else { //check name only if there is a name != NULL
+       if(name) {
                if(!check_id(name)) {
                        logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
                        meshlink_errno = MESHLINK_EINVAL;
                        return NULL;
-               } else {
-                       usingname = true;
                }
+
+               usingname = true;
        }
 
        if((int)devclass < 0 || devclass > _DEV_CLASS_MAX) {
@@ -985,14 +964,12 @@ meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *nam
                return NULL;
        }
 
-       if((key && !keylen) || (!key && keylen)) {
-               logger(NULL, MESHLINK_ERROR, "Invalid key length!\n");
-               meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
+       meshlink_handle_t *mesh = xzalloc(sizeof(meshlink_handle_t));
+
+       if(confbase) {
+               mesh->confbase = xstrdup(confbase);
        }
 
-       meshlink_handle_t *mesh = xzalloc(sizeof(meshlink_handle_t));
-       mesh->confbase = xstrdup(confbase);
        mesh->appname = xstrdup(appname);
        mesh->devclass = devclass;
        mesh->discovery = true;
@@ -1065,9 +1042,42 @@ meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *nam
 }
 
 meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
-       return meshlink_open_encrypted(confbase, name, appname, devclass, NULL, 0);
+       if(!confbase || !*confbase) {
+               logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       return meshlink_open_internal(confbase, name, appname, devclass, NULL, 0);
+}
+
+meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *name, const char *appname, dev_class_t devclass, const void *key, size_t keylen) {
+       if(!confbase || !*confbase) {
+               logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       if(!key || !keylen) {
+               logger(NULL, MESHLINK_ERROR, "No key given!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       return meshlink_open_internal(confbase, name, appname, devclass, key, keylen);
 }
 
+meshlink_handle_t *meshlink_open_ephemeral(const char *name, const char *appname, dev_class_t devclass) {
+       if(!name || !*name) {
+               logger(NULL, MESHLINK_ERROR, "No name given!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       return meshlink_open_internal(NULL, name, appname, devclass, NULL, 0);
+}
+
+
 static void *meshlink_main_loop(void *arg) {
        meshlink_handle_t *mesh = arg;
 
@@ -2021,38 +2031,63 @@ char *meshlink_export(meshlink_handle_t *mesh) {
                return NULL;
        }
 
-       config_t config;
+       // Create a config file on the fly.
 
-       // Get our config file
+       uint8_t buf[4096];
+       packmsg_output_t out = {buf, sizeof(buf)};
+       packmsg_add_uint32(&out, MESHLINK_CONFIG_VERSION);
+       packmsg_add_str(&out, mesh->name);
 
        pthread_mutex_lock(&(mesh->mesh_mutex));
 
-       if(!config_read(mesh, mesh->self->name, &config)) {
-               meshlink_errno = MESHLINK_ESTORAGE;
-               pthread_mutex_unlock(&mesh->mesh_mutex);
-               return NULL;
+       packmsg_add_int32(&out, mesh->self->devclass);
+       packmsg_add_bool(&out, mesh->self->status.blacklisted);
+       packmsg_add_bin(&out, ecdsa_get_public_key(mesh->private_key), 32);
+       packmsg_add_str(&out, mesh->self->canonical_address ? mesh->self->canonical_address : "");
+
+       uint32_t count = 0;
+
+       for(uint32_t i = 0; i < 5; i++) {
+               if(mesh->self->recent[i].sa.sa_family) {
+                       count++;
+               } else {
+                       break;
+               }
+       }
+
+       packmsg_add_array(&out, count);
+
+       for(uint32_t i = 0; i < count; i++) {
+               packmsg_add_sockaddr(&out, &mesh->self->recent[i]);
        }
 
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 
+       if(!packmsg_output_ok(&out)) {
+               logger(mesh, MESHLINK_DEBUG, "Error creating export data\n");
+               meshlink_errno = MESHLINK_EINTERNAL;
+               return NULL;
+       }
+
        // Prepare a base64-encoded packmsg array containing our config file
 
-       uint8_t *buf = xmalloc(((config.len + 4) * 4) / 3 + 4);
-       packmsg_output_t out = {buf, config.len + 4};
-       packmsg_add_array(&out, 1);
-       packmsg_add_bin(&out, config.buf, config.len);
-       config_free(&config);
+       uint32_t len = packmsg_output_size(&out, buf);
+       uint32_t len2 = ((len + 4) * 4) / 3 + 4;
+       uint8_t *buf2 = xmalloc(len2);
+       packmsg_output_t out2 = {buf2, len2};
+       packmsg_add_array(&out2, 1);
+       packmsg_add_bin(&out2, buf, packmsg_output_size(&out, buf));
 
-       if(!packmsg_output_ok(&out)) {
+       if(!packmsg_output_ok(&out2)) {
                logger(mesh, MESHLINK_DEBUG, "Error creating export data\n");
                meshlink_errno = MESHLINK_EINTERNAL;
-               free(buf);
+               free(buf2);
                return NULL;
        }
 
-       b64encode_urlsafe(buf, (char *)buf, packmsg_output_size(&out, buf));
+       b64encode_urlsafe(buf2, (char *)buf2, packmsg_output_size(&out2, buf2));
 
-       return (char *)buf;
+       return (char *)buf2;
 }
 
 bool meshlink_import(meshlink_handle_t *mesh, const char *data) {