From a97a07d79c847d0b30c61a2589e7bde62f25d603 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 27 Jan 2020 15:07:35 +0100 Subject: [PATCH] Only let mesh->self be reachable when the mesh is started. This ensures meshlink_node_get_reachability(mesh->self) returns true only if the mesh has been started. It also handles reachability of self in graph.c just like any other node. This means there will now also be a node status callback generated when the mesh is started and stopped. --- src/graph.c | 2 +- src/meshlink.c | 16 +++++++++------- src/net_setup.c | 3 --- test/basic.c | 30 ++++++++++++++++++++++++++---- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/graph.c b/src/graph.c index d70279c2..e6212116 100644 --- a/src/graph.c +++ b/src/graph.c @@ -72,7 +72,7 @@ static void sssp_bfs(meshlink_handle_t *mesh) { /* Begin with mesh->self */ - mesh->self->status.visited = true; + mesh->self->status.visited = mesh->threadstarted; mesh->self->nexthop = mesh->self; mesh->self->prevedge = NULL; mesh->self->distance = 0; diff --git a/src/meshlink.c b/src/meshlink.c index 2d4c2e1f..2309d775 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -37,6 +37,7 @@ #include "ed25519/sha512.h" #include "discovery.h" #include "devtools.h" +#include "graph.h" #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 @@ -1527,8 +1528,9 @@ bool meshlink_start(meshlink_handle_t *mesh) { pthread_cond_wait(&mesh->cond, &mesh->mutex); mesh->threadstarted = true; - mesh->self->last_reachable = time(NULL); - mesh->self->status.dirty = true; + + // Ensure we are considered reachable + graph(mesh); pthread_mutex_unlock(&mesh->mutex); return true; @@ -1543,11 +1545,6 @@ void meshlink_stop(meshlink_handle_t *mesh) { pthread_mutex_lock(&mesh->mutex); logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n"); - if(mesh->self) { - mesh->self->last_unreachable = time(NULL); - mesh->self->status.dirty = true; - } - // Shut down the main thread event_loop_stop(&mesh->loop); @@ -1587,6 +1584,11 @@ void meshlink_stop(meshlink_handle_t *mesh) { exit_outgoings(mesh); + // Ensure we are considered unreachable + if(mesh->nodes) { + graph(mesh); + } + // Try to write out any changed node config files, ignore errors at this point. if(mesh->nodes) { for splay_each(node_t, n, mesh->nodes) { diff --git a/src/net_setup.c b/src/net_setup.c index 8baff8b8..1b091db0 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -412,12 +412,9 @@ bool setup_myself(meshlink_handle_t *mesh) { /* Done */ mesh->self->nexthop = mesh->self; - mesh->self->status.reachable = true; node_add(mesh, mesh->self); - graph(mesh); - if(!config_scan_all(mesh, "current", "hosts", load_node, NULL)) { logger(mesh, MESHLINK_WARNING, "Could not scan all host config files"); } diff --git a/test/basic.c b/test/basic.c index 46f86960..bf8ff772 100644 --- a/test/basic.c +++ b/test/basic.c @@ -37,18 +37,31 @@ int main() { assert(self); assert(!strcmp(self->name, "foo")); - // Check that we are reachable. + // Check that we are not reachable. - assert(meshlink_get_node_reachability(mesh, self, NULL, NULL)); + time_t last_reachable; + time_t last_unreachable; + assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable)); + assert(!last_reachable); + assert(!last_unreachable); // Start and stop the mesh. assert(meshlink_start(mesh)); + + // Check that we are now reachable + + assert(meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable)); + assert(last_reachable); + assert(!last_unreachable); + meshlink_stop(mesh); - // Check that we are still reachable. + // Check that we are no longer reachable. - assert(meshlink_get_node_reachability(mesh, self, NULL, NULL)); + assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable)); + assert(last_reachable); + assert(last_unreachable); // Make sure we can start and stop the mesh again. @@ -63,6 +76,15 @@ int main() { mesh = meshlink_open("basic_conf", "bar", "basic", DEV_CLASS_BACKBONE); assert(mesh); + self = meshlink_get_self(mesh); + assert(self); + + // Check that we remembered we were reachable + + assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable)); + assert(last_reachable); + assert(last_unreachable); + // Check that the name is ignored now, and that we still are "foo". assert(!meshlink_get_node(mesh, "bar")); -- 2.39.5