]> git.meshlink.io Git - meshlink/commitdiff
Allow meshlink_open() to be called with a NULL name.
authorGuus Sliepen <guus@meshlink.io>
Sat, 11 Apr 2020 16:15:50 +0000 (18:15 +0200)
committerGuus Sliepen <guus@meshlink.io>
Sat, 11 Apr 2020 16:15:50 +0000 (18:15 +0200)
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
src/meshlink.h
test/basic.c
test/basicpp.cpp

index cdf9b17dcd94fe1d77d31a4102b539cf4049f02e..4e258c5633f1a1e7e2bf1f4982bea39cd81231f6 100644 (file)
@@ -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(&params, 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);
index 6a50eb66f1b3a54776e6c5c5ce191570631a6aee..ffcf954753bbb871d878bfcf8efd99708e6ab55c 100644 (file)
@@ -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.
index bf8ff772af73db120cadbc2d54403fb36b512d26..bc93de09c68e32508dab5ce5bb27391dec875bca 100644 (file)
 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
 
index ff49e3d428f749e9d7d9845c6176d494ed47782f..2f4e5c84a12d727349f751540ac33a60d26c160d 100644 (file)
@@ -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"));