X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fgraph.c;h=e6d70afa3f9742bf9e264dbc04ed6cf915d080b5;hb=6eaefb4dbce240334e35f67d9f3db5d4f44e49c9;hp=9dd3fa5df7e94537ed80a94fdebf672f9784f53c;hpb=8b55dfacb199d152391aa5f7adbbbe35bceea7d7;p=tinc diff --git a/src/graph.c b/src/graph.c index 9dd3fa5d..e6d70afa 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,7 @@ void mst_kruskal(void) /* Starting point */ - for(node = edge_weight_tree->head; node; node = next) { + for(node = edge_weight_tree->head; node; node = node->next) { e = node->data; if(e->from->status.reachable) { e->from->status.visited = true; @@ -149,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; @@ -227,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); @@ -237,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; @@ -269,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; @@ -311,70 +307,43 @@ void sssp_bfs(void) } } -void graph(void) -{ - sssp_bfs(); - mst_kruskal(); - 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; +int dump_graph(struct evbuffer *out) { + 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)) - return; - - graph_changed = false; - - ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph"); - - if(filename[0] == '|') { - file = popen(filename + 1, "w"); - } else { - asprintf(&tmpname, "%s.new", filename); - file = fopen(tmpname, "w"); - } - - if(!file) { - logger(LOG_ERR, "Unable to open graph dump file %s: %s", filename, strerror(errno)); - free(tmpname); - return; - } - fprintf(file, "digraph {\n"); + if(evbuffer_add_printf(out, "digraph {\n") == -1) + return errno; /* dump all nodes first */ for(node = node_tree->head; node; node = node->next) { n = node->data; - fprintf(file, " %s [label = \"%s\"];\n", n->name, n->name); + if(evbuffer_add_printf(out, " %s [label = \"%s\"];\n", + n->name, n->name) == -1) + return errno; } /* now dump all edges */ for(node = edge_weight_tree->head; node; node = node->next) { e = node->data; - fprintf(file, " %s -> %s;\n", e->from->name, e->to->name); + if(evbuffer_add_printf(out, " %s -> %s;\n", + e->from->name, e->to->name) == -1) + return errno; } - fprintf(file, "}\n"); - - if(filename[0] == '|') { - pclose(file); - } else { - fclose(file); - rename(tmpname, filename); - free(tmpname); - } + if(evbuffer_add_printf(out, "}\n") == -1) + return errno; + + return 0; +} + +void graph(void) { + sssp_bfs(); + mst_kruskal(); }