From fec95d1221c2d7e2059d6ba2fe244211ccee95ad Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 11 Apr 2020 18:15:50 +0200 Subject: [PATCH] Allow meshlink_open() to be called with a NULL name. This will use the name used last time the MeshLink instance was initialized. If there is no initialized instance at the given confbase, it will return an error. Opening an instance with a different name than the one in the configuration files will now also result in an error. --- src/meshlink.c | 76 ++++++++++++++++++++++++++++-------------------- src/meshlink.h | 3 ++ test/basic.c | 17 +++++++++-- test/basicpp.cpp | 7 +++-- 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/src/meshlink.c b/src/meshlink.c index cdf9b17d..4e258c56 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1083,9 +1083,6 @@ static bool meshlink_read_config(meshlink_handle_t *mesh) { return false; } -#if 0 - - // TODO: check this? if(mesh->name && strcmp(mesh->name, name)) { logger(NULL, MESHLINK_ERROR, "Configuration is for a different name (%s)!", name); meshlink_errno = MESHLINK_ESTORAGE; @@ -1094,8 +1091,6 @@ static bool meshlink_read_config(meshlink_handle_t *mesh) { return false; } -#endif - free(mesh->name); mesh->name = name; xasprintf(&mesh->myport, "%u", myport); @@ -1153,13 +1148,7 @@ meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const ch return NULL; } - if(!name || !*name) { - logger(NULL, MESHLINK_ERROR, "No name given!\n"); - meshlink_errno = MESHLINK_EINVAL; - return NULL; - }; - - if(!check_id(name)) { + if(name && !check_id(name)) { logger(NULL, MESHLINK_ERROR, "Invalid name given!\n"); meshlink_errno = MESHLINK_EINVAL; return NULL; @@ -1174,7 +1163,7 @@ meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const ch meshlink_open_params_t *params = xzalloc(sizeof * params); params->confbase = xstrdup(confbase); - params->name = xstrdup(name); + params->name = name ? xstrdup(name) : NULL; params->appname = xstrdup(appname); params->devclass = devclass; params->netns = -1; @@ -1347,6 +1336,36 @@ meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *nam } meshlink_handle_t *meshlink_open_ephemeral(const char *name, const char *appname, dev_class_t devclass) { + if(!name) { + logger(NULL, MESHLINK_ERROR, "No name given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(!check_id(name)) { + logger(NULL, MESHLINK_ERROR, "Invalid name given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(!appname || !*appname) { + logger(NULL, MESHLINK_ERROR, "No appname given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(strchr(appname, ' ')) { + logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(devclass < 0 || devclass >= DEV_CLASS_COUNT) { + logger(NULL, MESHLINK_ERROR, "Invalid devclass given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + /* Create a temporary struct on the stack, to avoid allocating and freeing one. */ meshlink_open_params_t params; memset(¶ms, 0, sizeof(params)); @@ -1360,11 +1379,9 @@ meshlink_handle_t *meshlink_open_ephemeral(const char *name, const char *appname } meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { - // Validate arguments provided by the application - bool usingname = false; - logger(NULL, MESHLINK_DEBUG, "meshlink_open called\n"); + // Validate arguments provided by the application if(!params->appname || !*params->appname) { logger(NULL, MESHLINK_ERROR, "No appname given!\n"); meshlink_errno = MESHLINK_EINVAL; @@ -1377,18 +1394,10 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { return NULL; } - if(!params->name || !*params->name) { - logger(NULL, MESHLINK_ERROR, "No name given!\n"); - //return NULL; - } else { //check name only if there is a name != NULL - - if(!check_id(params->name)) { - logger(NULL, MESHLINK_ERROR, "Invalid name given!\n"); - meshlink_errno = MESHLINK_EINVAL; - return NULL; - } else { - usingname = true; - } + if(params->name && !check_id(params->name)) { + logger(NULL, MESHLINK_ERROR, "Invalid name given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; } if(params->devclass < 0 || params->devclass >= DEV_CLASS_COUNT) { @@ -1427,9 +1436,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { memcpy(mesh->dev_class_traits, default_class_traits, sizeof(default_class_traits)); - if(usingname) { - mesh->name = xstrdup(params->name); - } + mesh->name = params->name ? xstrdup(params->name) : NULL; // Hash the key if(params->key) { @@ -1464,6 +1471,13 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { // If no configuration exists yet, create it. if(!meshlink_confbase_exists(mesh)) { + if(!mesh->name) { + logger(NULL, MESHLINK_ERROR, "No configuration files found!\n"); + meshlink_close(mesh); + meshlink_errno = MESHLINK_ESTORAGE; + return NULL; + } + if(!meshlink_setup(mesh)) { logger(NULL, MESHLINK_ERROR, "Cannot create initial configuration\n"); meshlink_close(mesh); diff --git a/src/meshlink.h b/src/meshlink.h index 6a50eb66..ffcf9547 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -151,6 +151,7 @@ extern const char *meshlink_strerror(meshlink_errno_t err) __attribute__((__warn * After the function returns, the application is free to overwrite or free @a confbase. * @param name The name which this instance of the application will use in the mesh. * After the function returns, the application is free to overwrite or free @a name. + * If NULL is passed as the name, the name used last time the MeshLink instance was initialized is used. * @param appname The application name which will be used in the mesh. * After the function returns, the application is free to overwrite or free @a name. * @param devclass The device class which will be used in the mesh. @@ -228,6 +229,7 @@ extern struct meshlink_handle *meshlink_open_ex(const meshlink_open_params_t *pa * After the function returns, the application is free to overwrite or free @a confbase. * @param name The name which this instance of the application will use in the mesh. * After the function returns, the application is free to overwrite or free @a name. + * If NULL is passed as the name, the name used last time the MeshLink instance was initialized is used. * @param appname The application name which will be used in the mesh. * After the function returns, the application is free to overwrite or free @a name. * @param devclass The device class which will be used in the mesh. @@ -257,6 +259,7 @@ extern struct meshlink_handle *meshlink_open(const char *confbase, const char *n * After the function returns, the application is free to overwrite or free @a confbase. * @param name The name which this instance of the application will use in the mesh. * After the function returns, the application is free to overwrite or free @a name. + * If NULL is passed as the name, the name used last time the MeshLink instance was initialized is used. * @param appname The application name which will be used in the mesh. * After the function returns, the application is free to overwrite or free @a name. * @param devclass The device class which will be used in the mesh. diff --git a/test/basic.c b/test/basic.c index bf8ff772..bc93de09 100644 --- a/test/basic.c +++ b/test/basic.c @@ -16,10 +16,16 @@ int main() { meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb); - // Open a new meshlink instance. + // Check that the first time we need to supply a name assert(meshlink_destroy("basic_conf")); - meshlink_handle_t *mesh = meshlink_open("basic_conf", "foo", "basic", DEV_CLASS_BACKBONE); + + meshlink_handle_t *mesh = meshlink_open("basic_conf", NULL, "basic", DEV_CLASS_BACKBONE); + assert(!mesh); + + // Open a new meshlink instance. + + mesh = meshlink_open("basic_conf", "foo", "basic", DEV_CLASS_BACKBONE); assert(mesh); // Check that we can't open a second instance of the same node. @@ -74,10 +80,17 @@ int main() { meshlink_close(mesh); mesh = meshlink_open("basic_conf", "bar", "basic", DEV_CLASS_BACKBONE); + assert(!mesh); + + // Open it without providing a name + + mesh = meshlink_open("basic_conf", NULL, "basic", DEV_CLASS_BACKBONE); assert(mesh); self = meshlink_get_self(mesh); assert(self); + assert(!strcmp(mesh->name, "foo")); + assert(!strcmp(self->name, "foo")); // Check that we remembered we were reachable diff --git a/test/basicpp.cpp b/test/basicpp.cpp index ff49e3d4..2f4e5c84 100644 --- a/test/basicpp.cpp +++ b/test/basicpp.cpp @@ -41,11 +41,14 @@ int main() { // Close the mesh and open it again, now with a different name parameter. mesh.close(); - assert(mesh.open("basicpp_conf", "bar", "basicpp", DEV_CLASS_BACKBONE)); + assert(!mesh.open("basicpp_conf", "bar", "basicpp", DEV_CLASS_BACKBONE)); + + // Open it without giving a name. + + assert(mesh.open("basicpp_conf", nullptr, "basicpp", DEV_CLASS_BACKBONE)); // Check that the name is ignored now, and that we still are "foo". - assert(!mesh.get_node("bar")); self = mesh.get_self(); assert(self); assert(!strcmp(self->name, "foo")); -- 2.39.5