X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=69dd71415519252a6198b02a59da07f7dc1834f1;hb=f712fdc0b3de22566cdf06954256c62f46f25542;hp=f6121a1ea67f589335f271a7b3edd39568ca8435;hpb=5c7be85686db219955e1af592b32d0d4108625cb;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index f6121a1e..69dd7141 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1,6 +1,6 @@ /* meshlink.c -- Implementation of the MeshLink API. - Copyright (C) 2014, 2017 Guus Sliepen + Copyright (C) 2014-2018 Guus Sliepen 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; @@ -1033,6 +1079,7 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const c mesh->appname = xstrdup(appname); mesh->devclass = devclass; mesh->discovery = true; + mesh->invitation_timeout = 604800; // 1 week if(usingname) { mesh->name = xstrdup(name); @@ -1168,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; } @@ -1185,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); @@ -1276,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; @@ -1349,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)); @@ -1744,7 +1784,7 @@ bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *no } bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { - return meshlink_set_canonical_address(mesh, mesh->self, address, NULL); + return meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL); } bool meshlink_add_external_address(meshlink_handle_t *mesh) { @@ -1832,6 +1872,10 @@ done: return rval; } +void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) { + mesh->invitation_timeout = timeout; +} + char *meshlink_invite(meshlink_handle_t *mesh, const char *name) { if(!mesh) { meshlink_errno = MESHLINK_EINVAL; @@ -2101,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; @@ -2336,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) { @@ -2627,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; @@ -2651,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) {