X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fgraph.c;h=5bf6361e737417865a07252c672fdfc9b4bff817;hb=fb0cfccf7dc2240b576011edcf74fd5b058916cb;hp=b5af2241f51b189b8fafd8268aa6c63112cee8f5;hpb=0200d3cd5d773d9b101c33264532d2a301c2af32;p=tinc diff --git a/src/graph.c b/src/graph.c index b5af2241..5bf6361e 100644 --- a/src/graph.c +++ b/src/graph.c @@ -46,7 +46,7 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "config.h" #include "connection.h" #include "device.h" @@ -58,16 +58,13 @@ #include "subnet.h" #include "utils.h" -static bool graph_changed = true; - /* Implementation of Kruskal's algorithm. Running time: O(EN) Please note that sorting on weight is already done by add_edge(). */ -void mst_kruskal(void) -{ - avl_node_t *node, *next; +void mst_kruskal(void) { + splay_node_t *node, *next; edge_t *e; node_t *n; connection_t *c; @@ -101,7 +98,13 @@ void mst_kruskal(void) /* Starting point */ - ((edge_t *) edge_weight_tree->head->data)->from->status.visited = true; + for(node = edge_weight_tree->head; node; node = node->next) { + e = node->data; + if(e->from->status.reachable) { + e->from->status.visited = true; + break; + } + } /* Add safe edges */ @@ -143,9 +146,8 @@ void mst_kruskal(void) Running time: O(E) */ -void sssp_bfs(void) -{ - avl_node_t *node, *next, *to; +void sssp_bfs(void) { + splay_node_t *node, *next, *to; edge_t *e; node_t *n; list_t *todo_list; @@ -221,7 +223,7 @@ void sssp_bfs(void) e->to->options = e->options; if(sockaddrcmp(&e->to->address, &e->address)) { - node = avl_unlink(node_udp_tree, e->to); + node = splay_unlink(node_udp_tree, e->to); sockaddrfree(&e->to->address); sockaddrcpy(&e->to->address, &e->address); @@ -231,7 +233,7 @@ void sssp_bfs(void) e->to->hostname = sockaddr2hostname(&e->to->address); if(node) - avl_insert_node(node_udp_tree, node); + splay_insert_node(node_udp_tree, node); if(e->to->options & OPTION_PMTU_DISCOVERY) { e->to->mtuprobes = 0; @@ -263,11 +265,11 @@ void sssp_bfs(void) if(n->status.reachable) { ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Node %s (%s) became reachable"), n->name, n->hostname); - avl_insert(node_udp_tree, n); + splay_insert(node_udp_tree, n); } else { ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Node %s (%s) became unreachable"), n->name, n->hostname); - avl_delete(node_udp_tree, n); + splay_delete(node_udp_tree, n); } n->status.validkey = false; @@ -305,34 +307,22 @@ void sssp_bfs(void) } } -void graph(void) -{ - mst_kruskal(); - sssp_bfs(); - graph_changed = true; -} - - - /* Dump nodes and edges to a graphviz file. The file can be converted to an image with dot -Tpng graph_filename -o image_filename.png -Gconcentrate=true */ -void dump_graph(void) -{ - avl_node_t *node; +static void dump_graph(int fd, short events, void *data) { + splay_node_t *node; node_t *n; edge_t *e; char *filename = NULL, *tmpname = NULL; FILE *file; - if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename)) + if(!get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename)) return; - graph_changed = false; - ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph"); if(filename[0] == '|') { @@ -364,10 +354,25 @@ void dump_graph(void) fprintf(file, "}\n"); - fclose(file); - - if(filename[0] != '|') { + if(filename[0] == '|') { + pclose(file); + } else { + fclose(file); +#ifdef HAVE_MINGW + unlink(filename); +#endif rename(tmpname, filename); free(tmpname); } } + +void graph(void) { + static struct event ev; + + sssp_bfs(); + mst_kruskal(); + + if(!timeout_initialized(&ev)) + timeout_set(&ev, dump_graph, NULL); + event_add(&ev, &(struct timeval){5, 0}); +}