]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Add duplicate node detection callback.
[meshlink] / src / meshlink.c
index 52a4389a9311e1e872091e9cccc335db94ca3b37..69dd71415519252a6198b02a59da07f7dc1834f1 100644 (file)
@@ -1,6 +1,6 @@
 /*
     meshlink.c -- Implementation of the MeshLink API.
-    Copyright (C) 2014, 2017 Guus Sliepen <guus@meshlink.io>
+    Copyright (C) 2014-2018 Guus Sliepen <guus@meshlink.io>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -534,6 +534,31 @@ int check_port(meshlink_handle_t *mesh) {
        return 0;
 }
 
+static void deltree(const char *dirname) {
+       DIR *d = opendir(dirname);
+
+       if(d) {
+               struct dirent *ent;
+
+               while((ent = readdir(d))) {
+                       if(ent->d_name[0] == '.') {
+                               continue;
+                       }
+
+                       char filename[PATH_MAX];
+                       snprintf(filename, sizeof(filename), "%s" SLASH "%s", dirname, ent->d_name);
+
+                       if(unlink(filename)) {
+                               deltree(filename);
+                       }
+               }
+
+               closedir(d);
+       }
+
+       rmdir(dirname);
+}
+
 static bool finalize_join(meshlink_handle_t *mesh) {
        char *name = xstrdup(get_value(mesh->data, "Name"));
 
@@ -559,6 +584,19 @@ static bool finalize_join(meshlink_handle_t *mesh) {
 
        fprintf(f, "Name = %s\n", name);
 
+       // Wipe all old host config files and invitations
+       snprintf(filename, sizeof(filename), "%s" SLASH "hosts", mesh->confbase);
+       deltree(filename);
+
+       if(mkdir(filename, 0777) && errno != EEXIST) {
+               logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
+               return false;
+       }
+
+       snprintf(filename, sizeof(filename), "%s" SLASH "invitations", mesh->confbase);
+       deltree(filename);
+
+       // Create a new host config file for ourself
        snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
        FILE *fh = fopen(filename, "w");
 
@@ -690,8 +728,10 @@ static bool finalize_join(meshlink_handle_t *mesh) {
        sptps_send_record(&(mesh->sptps), 1, b64key, strlen(b64key));
        free(b64key);
 
+       free(mesh->name);
        free(mesh->self->name);
        free(mesh->self->connection->name);
+       mesh->name = xstrdup(name);
        mesh->self->name = xstrdup(name);
        mesh->self->connection->name = name;
 
@@ -1008,6 +1048,12 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const c
                return NULL;
        }
 
+       if(strchr(appname, ' ')) {
+               logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
        if(!name || !*name) {
                logger(NULL, MESHLINK_ERROR, "No name given!\n");
                //return NULL;
@@ -1169,10 +1215,14 @@ bool meshlink_start(meshlink_handle_t *mesh) {
 
        mesh->threadstarted = true;
 
+#if HAVE_CATTA
+
        if(mesh->discovery) {
                discovery_start(mesh);
        }
 
+#endif
+
        pthread_mutex_unlock(&(mesh->mesh_mutex));
        return true;
 }
@@ -1186,11 +1236,15 @@ void meshlink_stop(meshlink_handle_t *mesh) {
        pthread_mutex_lock(&(mesh->mesh_mutex));
        logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
 
+#if HAVE_CATTA
+
        // Stop discovery
        if(mesh->discovery) {
                discovery_stop(mesh);
        }
 
+#endif
+
        // Shut down the main thread
        event_loop_stop(&mesh->loop);
 
@@ -1277,32 +1331,6 @@ void meshlink_close(meshlink_handle_t *mesh) {
        free(mesh);
 }
 
-static void deltree(const char *dirname) {
-       DIR *d = opendir(dirname);
-
-       if(d) {
-               struct dirent *ent;
-
-               while((ent = readdir(d))) {
-                       if(ent->d_name[0] == '.') {
-                               continue;
-                       }
-
-                       char filename[PATH_MAX];
-                       snprintf(filename, sizeof(filename), "%s" SLASH "%s", dirname, ent->d_name);
-
-                       if(unlink(filename)) {
-                               deltree(filename);
-                       }
-               }
-
-               closedir(d);
-       }
-
-       rmdir(dirname);
-       return;
-}
-
 bool meshlink_destroy(const char *confbase) {
        if(!confbase) {
                meshlink_errno = MESHLINK_EINVAL;
@@ -1350,6 +1378,17 @@ void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_c
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
+void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_duplicate_cb_t cb) {
+       if(!mesh) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       pthread_mutex_lock(&(mesh->mesh_mutex));
+       mesh->node_duplicate_cb = cb;
+       pthread_mutex_unlock(&(mesh->mesh_mutex));
+}
+
 void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) {
        if(mesh) {
                pthread_mutex_lock(&(mesh->mesh_mutex));
@@ -2106,7 +2145,7 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) {
 
        mesh->blen = 0;
 
-       if(!sendline(mesh->sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) {
+       if(!sendline(mesh->sock, "0 ?%s %d.%d %s", b64key, PROT_MAJOR, 1, mesh->appname)) {
                logger(mesh, MESHLINK_DEBUG, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
                closesocket(mesh->sock);
                meshlink_errno = MESHLINK_ENETWORK;
@@ -2341,8 +2380,14 @@ void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) {
        //Make blacklisting persistent in the config file
        append_config_file(mesh, n->name, "blacklisted", "yes");
 
+       //Immediately terminate any connections we have with the blacklisted node
+       for list_each(connection_t, c, mesh->connections) {
+               if(c->node == n) {
+                       terminate_connection(mesh, c, c->status.active);
+               }
+       }
+
        pthread_mutex_unlock(&(mesh->mesh_mutex));
-       return;
 }
 
 void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) {
@@ -2632,7 +2677,18 @@ void update_node_status(meshlink_handle_t *mesh, node_t *n) {
        }
 }
 
+void handle_duplicate_node(meshlink_handle_t *mesh, node_t *n) {
+       if(!mesh->node_duplicate_cb || n->status.duplicate) {
+               return;
+       }
+
+       n->status.duplicate = true;
+       mesh->node_duplicate_cb(mesh, (meshlink_node_t *)n);
+}
+
 void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) {
+#if HAVE_CATTA
+
        if(!mesh) {
                meshlink_errno = MESHLINK_EINVAL;
                return;
@@ -2656,6 +2712,11 @@ void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) {
 
 end:
        pthread_mutex_unlock(&mesh->mesh_mutex);
+#else
+       (void)mesh;
+       (void)enable;
+       meshlink_errno = MESHLINK_ENOTSUP;
+#endif
 }
 
 static void __attribute__((constructor)) meshlink_init(void) {