+ // Rename confbase/new/ to confbase/current
+
+ if(!config_rename(mesh, "new", "current")) {
+ logger(mesh, MESHLINK_ERROR, "Cannot rename %s/new to %s/current\n", mesh->confbase, mesh->confbase);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ pthread_mutex_unlock(&mesh->mutex);
+ return false;
+ }
+
+ devtool_keyrotate_probe(3);
+
+ // Cleanup the "old" confbase sub-directory
+
+ if(!config_destroy(mesh->confbase, "old")) {
+ pthread_mutex_unlock(&mesh->mutex);
+ return false;
+ }
+
+ // Change the mesh handle key with new key
+
+ free(mesh->config_key);
+ mesh->config_key = new_config_key;
+
+ pthread_mutex_unlock(&mesh->mutex);
+
+ return true;
+}
+
+void meshlink_open_params_free(meshlink_open_params_t *params) {
+ if(!params) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ free(params->confbase);
+ free(params->name);
+ free(params->appname);
+
+ free(params);
+}
+
+/// Device class traits
+static const dev_class_traits_t default_class_traits[DEV_CLASS_COUNT] = {
+ { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE
+ { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY
+ { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE
+ { .pingtimeout = 5, .pinginterval = 60, .min_connects = 1, .max_connects = 1, .edge_weight = 9 }, // DEV_CLASS_UNKNOWN
+};
+
+meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
+ if(!confbase || !*confbase) {
+ logger(NULL, MESHLINK_ERROR, "No confbase 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));
+
+ params.confbase = (char *)confbase;
+ params.name = (char *)name;
+ params.appname = (char *)appname;
+ params.devclass = devclass;
+ params.netns = -1;
+
+ return meshlink_open_ex(¶ms);
+}
+
+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;
+ }
+
+ /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
+ meshlink_open_params_t params;
+ memset(¶ms, 0, sizeof(params));
+
+ params.confbase = (char *)confbase;