X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fgraph.c;h=d3ac4e6b0a33a7ef1449d26d03f91d3d8a5f1ec3;hb=158cbe99f972a1613b7d4d95abfe5fe48e019e67;hp=6428f4db77c2e2a8fb49969ca6432142578f7d10;hpb=d917c8cb6b69475d568ccbe82389b9f2b3eb5e80;p=meshlink diff --git a/src/graph.c b/src/graph.c index 6428f4db..d3ac4e6b 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,7 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2012 Guus Sliepen , - 2001-2005 Ivo Timmermans + Copyright (C) 2014 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 @@ -44,24 +43,20 @@ #include "system.h" -#include "config.h" #include "connection.h" -#include "device.h" #include "edge.h" #include "graph.h" #include "list.h" #include "logger.h" #include "netutl.h" #include "node.h" -#include "process.h" #include "protocol.h" -#include "subnet.h" #include "utils.h" #include "xalloc.h" #include "graph.h" /* Implementation of Kruskal's algorithm. - Running time: O(E) + Running time: O(EN) Please note that sorting on weight is already done by add_edge(). */ @@ -78,11 +73,24 @@ static void mst_kruskal(void) { for splay_each(node_t, n, node_tree) n->status.visited = false; + /* Starting point */ + + for splay_each(edge_t, e, edge_weight_tree) { + if(e->from->status.reachable) { + e->from->status.visited = true; + break; + } + } + /* Add safe edges */ + bool skipped = false; + for splay_each(edge_t, e, edge_weight_tree) { - if(!e->reverse || (e->from->status.visited && e->to->status.visited)) + if(!e->reverse || (e->from->status.visited == e->to->status.visited)) { + skipped = true; continue; + } e->from->status.visited = true; e->to->status.visited = true; @@ -93,8 +101,12 @@ static void mst_kruskal(void) { if(e->reverse->connection) e->reverse->connection->status.mst = true; - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, - e->to->name, e->weight); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); + + if(skipped) { + skipped = false; + next = edge_weight_tree->head; + } } } @@ -186,7 +198,7 @@ static void check_reachability(void) { for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; - n->last_state_change = time(NULL); + n->last_state_change = now.tv_sec; if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", @@ -213,39 +225,14 @@ static void check_reachability(void) { n->minmtu = 0; n->mtuprobes = 0; - if(timeout_initialized(&n->mtuevent)) - event_del(&n->mtuevent); - - char *name; - char *address; - char *port; - char *envp[7]; - - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", n->name); - sockaddr2str(&n->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "REMOTEPORT=%s", port); - envp[6] = NULL; - - execute_script(n->status.reachable ? "host-up" : "host-down", envp); - - xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); - execute_script(name, envp); - - free(name); - free(address); - free(port); - - for(int i = 0; i < 6; i++) - free(envp[i]); + timeout_del(&n->mtutimeout); - subnet_update(n, NULL, n->status.reachable); + //TODO: callback to application to inform of this node going up/down if(!n->status.reachable) { update_node_udp(n, NULL); + memset(&n->status, 0, sizeof n->status); + n->options = 0; } else if(n->connection) { if(n->status.sptps) { if(n->connection->outgoing) @@ -259,7 +246,6 @@ static void check_reachability(void) { } void graph(void) { - subnet_cache_flush(); sssp_bfs(); check_reachability(); mst_kruskal();